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.