{ Solutions to the Advent Of Code. Copyright (C) 2023 Stefan Müller This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . } unit UWaitForIt; {$mode ObjFPC}{$H+} interface uses Classes, SysUtils, Generics.Collections, Math, USolver; type { TWaitForIt } TWaitForIt = class(TSolver) private FTimes, FDistances: specialize TList; FLongTime, FLongDistance: UInt64; function CalcRange(const ATime, ADistance: UInt64): Cardinal; public constructor Create; destructor Destroy; override; procedure ProcessDataLine(const ALine: string); override; procedure Finish; override; function GetDataFileName: string; override; function GetPuzzleName: string; override; end; implementation { TWaitForIt } function TWaitForIt.CalcRange(const ATime, ADistance: UInt64): Cardinal; var x1, x2: Integer; p, s: Double; begin p := ATime / 2; s := Sqrt(p * p - ADistance); x1 := Math.Floor(p - s + 1); x2 := Math.Ceil(p + s - 1); Result := x2 - x1 + 1; end; constructor TWaitForIt.Create; begin FTimes := specialize TList.Create; FDistances := specialize TList.Create; end; destructor TWaitForIt.Destroy; begin FTimes.Free; FDistances.Free; inherited Destroy; end; procedure TWaitForIt.ProcessDataLine(const ALine: string); var split: TStringArray; list: specialize TList; value: PUInt64; i: Integer; cleaned: string; begin split := ALine.Split([' ', ':']); if split[0] = 'Time' then begin list := FTimes; value := @FLongTime; end else if split[0] = 'Distance' then begin list := FDistances; value := @FLongDistance; end else Exit; cleaned := ''; for i := 1 to Length(split) - 1 do if split[i] <> '' then begin list.Add(StrToDWord(split[i])); cleaned := Concat(cleaned, split[i]); end; value^ := StrToUInt64(cleaned); end; procedure TWaitForIt.Finish; var i: Integer; begin FPart1 := 1; for i := 0 to FTimes.Count - 1 do FPart1 := FPart1 * CalcRange(FTimes[i], FDistances[i]); FPart2 := CalcRange(FLongTime, FLongDistance); end; function TWaitForIt.GetDataFileName: string; begin Result := 'wait_for_it.txt'; end; function TWaitForIt.GetPuzzleName: string; begin Result := 'Day 6: Wait For It'; end; end.