{ 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 UMirageMaintenance; {$mode ObjFPC}{$H+} interface uses Classes, SysUtils, Generics.Collections, USolver; type { TMirageMaintenance } TMirageMaintenance = class(TSolver) private FN: Integer; FLagrangePolynomialsInN: specialize TList; procedure CalcLagrangePolynomials; 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 { TMirageMaintenance } procedure TMirageMaintenance.CalcLagrangePolynomials; var sign, i, j: Integer; begin FLagrangePolynomialsInN.Clear; if FN mod 2 = 0 then sign := -1 else sign := 1; // Calculates the polynomials in N and -1. for i := 0 to FN - 1 do begin FLagrangePolynomialsInN.Add(sign); sign := -sign; if i < FN - FN div 2 then begin // Multiplies by the non-cancelled numerator terms. for j := FN - i + 1 to FN do FLagrangePolynomialsInN[i] := FLagrangePolynomialsInN[i] * j; // Divides by the non-cancelled denominator terms. for j := 2 to i do FLagrangePolynomialsInN[i] := FLagrangePolynomialsInN[i] div j; end else begin // Multiplies by the non-cancelled numerator terms. for j := i + 1 to FN do FLagrangePolynomialsInN[i] := FLagrangePolynomialsInN[i] * j; // Divides by the non-cancelled over-counted numerator term. FLagrangePolynomialsInN[i] := FLagrangePolynomialsInN[i] div (FN - i); // Divides by the non-cancelled denominator terms. for j := 2 to FN - i - 1 do FLagrangePolynomialsInN[i] := FLagrangePolynomialsInN[i] div j; end; end; end; constructor TMirageMaintenance.Create; begin FLagrangePolynomialsInN := specialize TList.Create; FN := 0; end; destructor TMirageMaintenance.Destroy; begin FLagrangePolynomialsInN.Free; inherited Destroy; end; procedure TMirageMaintenance.ProcessDataLine(const ALine: string); var split: TStringArray; i, y: Integer; p: Int64; begin split := ALine.Split(' '); if Length(split) <> FN then begin FN := Length(split); CalcLagrangePolynomials; end; for i := 0 to FN - 1 do begin y := StrToInt(split[i]); p := y * FLagrangePolynomialsInN[i]; Inc(FPart1, p); end; end; procedure TMirageMaintenance.Finish; begin end; function TMirageMaintenance.GetDataFileName: string; begin Result := 'mirage_maintenance.txt'; end; function TMirageMaintenance.GetPuzzleName: string; begin Result := 'Day 9: Mirage Maintenance'; end; end.