diff --git a/AdventOfCode.lpi b/AdventOfCode.lpi index dbeeb5b..8cebdb5 100644 --- a/AdventOfCode.lpi +++ b/AdventOfCode.lpi @@ -77,6 +77,10 @@ + + + + diff --git a/AdventOfCode.lpr b/AdventOfCode.lpr index e80b665..9bda50e 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, UMirageMaintenance, UPipeMaze; + UHauntedWasteland, UNumberTheory, UMirageMaintenance, UPipeMaze, UCosmicExpansion; type @@ -61,6 +61,7 @@ begin engine.RunAndFree(THauntedWasteland.Create); engine.RunAndFree(TMirageMaintenance.Create); engine.RunAndFree(TPipeMaze.Create); + engine.RunAndFree(TCosmicExpansion.Create); engine.Free; end; diff --git a/solvers/UCosmicExpansion.pas b/solvers/UCosmicExpansion.pas new file mode 100644 index 0000000..6f9ba96 --- /dev/null +++ b/solvers/UCosmicExpansion.pas @@ -0,0 +1,127 @@ +{ + 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 UCosmicExpansion; + +{$mode ObjFPC}{$H+} + +interface + +uses + Classes, SysUtils, Generics.Collections, Math, USolver; + +const + CGalaxyChar = '#'; + CEmptySpaceFactor = 2; + CNonEmptySpaceFactor = 1; + +type + + { TCosmicExpansion } + + TCosmicExpansion = class(TSolver) + private + FColumnExpansion, FRowExpansion: specialize TList; + FGalaxies: specialize TList; + procedure InitColumnExpansion(const ASize: Integer); + 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 + +{ TCosmicExpansion } + +procedure TCosmicExpansion.InitColumnExpansion(const ASize: Integer); +var + i: Integer; +begin + if FColumnExpansion.Count = 0 then + begin + FColumnExpansion.Capacity := ASize; + for i := 1 to ASize do + FColumnExpansion.Add(CEmptySpaceFactor); + end; +end; + +constructor TCosmicExpansion.Create; +begin + FColumnExpansion := specialize TList.Create; + FRowExpansion := specialize TList.Create; + FGalaxies := specialize TList.Create; +end; + +destructor TCosmicExpansion.Destroy; +begin + FColumnExpansion.Free; + FRowExpansion.Free; + FGalaxies.Free; + inherited Destroy; +end; + +procedure TCosmicExpansion.ProcessDataLine(const ALine: string); +var + empty: Boolean; + i : Integer; +begin + InitColumnExpansion(Length(ALine)); + + empty := True; + for i := 1 to Length(ALine) do + if ALine[i] = CGalaxyChar then + begin + FGalaxies.Add(Point(i, FRowExpansion.Count)); + empty := False; + FColumnExpansion[i - 1] := CNonEmptySpaceFactor; + end; + + if empty then + FRowExpansion.Add(CEmptySpaceFactor) + else + FRowExpansion.Add(CNonEmptySpaceFactor); +end; + +procedure TCosmicExpansion.Finish; +var + i, j, k: Integer; +begin + for i := 0 to FGalaxies.Count - 1 do + for j := i + 1 to FGalaxies.Count - 1 do begin + for k := Min(FGalaxies[i].X, FGalaxies[j].X) to Max(FGalaxies[i].X, FGalaxies[j].X) - 1 do + Inc(FPart1, FColumnExpansion[k]); + for k := Min(FGalaxies[i].Y, FGalaxies[j].Y) + 1 to Max(FGalaxies[i].Y, FGalaxies[j].Y) do + Inc(FPart1, FRowExpansion[k]); + end; +end; + +function TCosmicExpansion.GetDataFileName: string; +begin + Result := 'cosmic_expansion.txt'; +end; + +function TCosmicExpansion.GetPuzzleName: string; +begin + Result := 'Day 11: Cosmic Expansion'; +end; + +end. + diff --git a/tests/AdventOfCodeFPCUnit.lpi b/tests/AdventOfCodeFPCUnit.lpi index 46f8cdf..3875c21 100644 --- a/tests/AdventOfCodeFPCUnit.lpi +++ b/tests/AdventOfCodeFPCUnit.lpi @@ -84,6 +84,10 @@ + + + + diff --git a/tests/AdventOfCodeFPCUnit.lpr b/tests/AdventOfCodeFPCUnit.lpr index 2697a07..3a607b4 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, UMirageMaintenanceTestCases, UPipeMazeTestCases; + UHauntedWastelandTestCases, UMirageMaintenanceTestCases, UPipeMazeTestCases, UCosmicExpansionTestCases; {$R *.res} diff --git a/tests/UCosmicExpansionTestCases.pas b/tests/UCosmicExpansionTestCases.pas new file mode 100644 index 0000000..4093e91 --- /dev/null +++ b/tests/UCosmicExpansionTestCases.pas @@ -0,0 +1,78 @@ +{ + 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 UCosmicExpansionTestCases; + +{$mode ObjFPC}{$H+} + +interface + +uses + Classes, SysUtils, fpcunit, testregistry, USolver, UBaseTestCases, UCosmicExpansion; + +type + + { TCosmicExpansionFullDataTestCase } + + TCosmicExpansionFullDataTestCase = class(TEngineBaseTest) + protected + function CreateSolver: ISolver; override; + published + procedure TestPart1; + end; + + { TCosmicExpansionExampleTestCase } + + TCosmicExpansionExampleTestCase = class(TExampleEngineBaseTest) + protected + function CreateSolver: ISolver; override; + published + procedure TestPart1; + end; + +implementation + +{ TCosmicExpansionFullDataTestCase } + +function TCosmicExpansionFullDataTestCase.CreateSolver: ISolver; +begin + Result := TCosmicExpansion.Create; +end; + +procedure TCosmicExpansionFullDataTestCase.TestPart1; +begin + AssertEquals(9686930, FSolver.GetResultPart1); +end; + +{ TCosmicExpansionExampleTestCase } + +function TCosmicExpansionExampleTestCase.CreateSolver: ISolver; +begin + Result := TCosmicExpansion.Create; +end; + +procedure TCosmicExpansionExampleTestCase.TestPart1; +begin + AssertEquals(374, FSolver.GetResultPart1); +end; + +initialization + + RegisterTest(TCosmicExpansionFullDataTestCase); + RegisterTest(TCosmicExpansionExampleTestCase); +end. +