diff --git a/AdventOfCode.lpi b/AdventOfCode.lpi index eb33314..0ceead4 100644 --- a/AdventOfCode.lpi +++ b/AdventOfCode.lpi @@ -69,6 +69,10 @@ + + + + diff --git a/AdventOfCode.lpr b/AdventOfCode.lpr index 5139121..accce58 100644 --- a/AdventOfCode.lpr +++ b/AdventOfCode.lpr @@ -26,7 +26,7 @@ uses Classes, SysUtils, CustApp, USolver, UTrebuchet, UCubeConundrum, UGearRatios, UScratchcards, UGiveSeedFertilizer, UWaitForIt, UCamelCards, - UHauntedWasteland, UNumberTheory; + UHauntedWasteland, UNumberTheory, UMirageMaintenance; type @@ -59,6 +59,7 @@ begin engine.RunAndFree(TWaitForIt.Create); engine.RunAndFree(TCamelCards.Create); engine.RunAndFree(THauntedWasteland.Create); + engine.RunAndFree(TMirageMaintenance.Create); engine.Free; end; diff --git a/solvers/UMirageMaintenance.pas b/solvers/UMirageMaintenance.pas new file mode 100644 index 0000000..535bbb2 --- /dev/null +++ b/solvers/UMirageMaintenance.pas @@ -0,0 +1,136 @@ +{ + 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. + diff --git a/tests/AdventOfCodeFPCUnit.lpi b/tests/AdventOfCodeFPCUnit.lpi index 597e381..17393bc 100644 --- a/tests/AdventOfCodeFPCUnit.lpi +++ b/tests/AdventOfCodeFPCUnit.lpi @@ -76,6 +76,10 @@ + + + + diff --git a/tests/AdventOfCodeFPCUnit.lpr b/tests/AdventOfCodeFPCUnit.lpr index 7554d8e..11cc80b 100644 --- a/tests/AdventOfCodeFPCUnit.lpr +++ b/tests/AdventOfCodeFPCUnit.lpr @@ -5,7 +5,7 @@ program AdventOfCodeFPCUnit; uses Interfaces, Forms, GuiTestRunner, USolver, UBaseTestCases, UTrebuchetTestCases, UCubeConundrumTestCases, UGearRatiosTestCases, UScratchcardsTestCases, UGiveSeedFertilizerTestCases, UWaitForItTestCases, UCamelCardsTestCases, - UHauntedWastelandTestCases; + UHauntedWastelandTestCases, UMirageMaintenanceTestCases; {$R *.res} diff --git a/tests/UMirageMaintenanceTestCases.pas b/tests/UMirageMaintenanceTestCases.pas new file mode 100644 index 0000000..b3310cf --- /dev/null +++ b/tests/UMirageMaintenanceTestCases.pas @@ -0,0 +1,89 @@ +{ + 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 UMirageMaintenanceTestCases; + +{$mode ObjFPC}{$H+} + +interface + +uses + Classes, SysUtils, fpcunit, testregistry, USolver, UBaseTestCases, UMirageMaintenance; + +type + + { TMirageMaintenanceFullDataTestCase } + + TMirageMaintenanceFullDataTestCase = class(TEngineBaseTest) + protected + function CreateSolver: ISolver; override; + published + procedure TestPart1; + procedure TestPart2; + end; + + { TMirageMaintenanceExampleTestCase } + + TMirageMaintenanceExampleTestCase = class(TExampleEngineBaseTest) + protected + function CreateSolver: ISolver; override; + published + procedure TestPart1; + procedure TestPart2; + end; + +implementation + +{ TMirageMaintenanceFullDataTestCase } + +function TMirageMaintenanceFullDataTestCase.CreateSolver: ISolver; +begin + Result := TMirageMaintenance.Create; +end; + +procedure TMirageMaintenanceFullDataTestCase.TestPart1; +begin + AssertEquals(1877825184, FSolver.GetResultPart1); +end; + +procedure TMirageMaintenanceFullDataTestCase.TestPart2; +begin + AssertEquals(-1, FSolver.GetResultPart2); +end; + +{ TMirageMaintenanceExampleTestCase } + +function TMirageMaintenanceExampleTestCase.CreateSolver: ISolver; +begin + Result := TMirageMaintenance.Create; +end; + +procedure TMirageMaintenanceExampleTestCase.TestPart1; +begin + AssertEquals(114, FSolver.GetResultPart1); +end; + +procedure TMirageMaintenanceExampleTestCase.TestPart2; +begin + AssertEquals(-1, FSolver.GetResultPart2); +end; + +initialization + + RegisterTest(TMirageMaintenanceFullDataTestCase); + RegisterTest(TMirageMaintenanceExampleTestCase); +end.