diff --git a/AdventOfCode.lpi b/AdventOfCode.lpi index 0870890..e9f222e 100644 --- a/AdventOfCode.lpi +++ b/AdventOfCode.lpi @@ -45,6 +45,10 @@ + + + + diff --git a/AdventOfCode.lpr b/AdventOfCode.lpr index 3a77065..43c82a3 100644 --- a/AdventOfCode.lpr +++ b/AdventOfCode.lpr @@ -25,7 +25,7 @@ uses {$ENDIF} Classes, SysUtils, CustApp, USolver, - UTrebuchet, UCubeConundrum, UGearRatios; + UTrebuchet, UCubeConundrum, UGearRatios, UScratchcards; type @@ -53,6 +53,7 @@ begin TCubeConundrum.Run; engine := TSolverEngine.Create('data'); engine.RunAndFree(TGearRatios.Create); + engine.RunAndFree(TScratchcards.Create); engine.Free; end; diff --git a/solvers/UScratchcards.pas b/solvers/UScratchcards.pas new file mode 100644 index 0000000..ede0449 --- /dev/null +++ b/solvers/UScratchcards.pas @@ -0,0 +1,105 @@ +{ + 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 UScratchcards; + +{$mode ObjFPC}{$H+} + +interface + +uses + Classes, SysUtils, USolver; + +type + + { TScratchcards } + + TScratchcards = class(TSolver) + private + function GetNumber(const AString: string; const AIndex: Integer): Integer; + public + procedure ProcessDataLine(const ALine: string); override; + procedure Finish; override; + function GetDataFileName: string; override; + function GetPuzzleName: string; override; + end; + + +implementation + +{ TScratchcards } + +function TScratchcards.GetNumber(const AString: string; const AIndex: Integer): Integer; +begin + Result := StrToInt(Trim(Copy(AString, AIndex * 3 + 1, 3))) +end; + +procedure TScratchcards.ProcessDataLine(const ALine: string); +var + cardSplit: TStringArray; + wins: array of Integer; + count, i, have, win, cardPoints: Integer; +begin + cardSplit := ALine.Split([':', '|']); + + // Determines winning numbers. + count := cardSplit[1].Length div 3; + SetLength(wins, count); + for i := 0 to count - 1 do + begin + wins[i] := GetNumber(cardSplit[1], i); + end; + + // Checks have numbers against winning numbers. + cardPoints := 0; + count := cardSplit[2].Length div 3; + for i := 0 to count - 1 do + begin + have := GetNumber(cardSplit[2], i); + for win in wins do + begin + if win = have then + begin + if cardPoints = 0 then + cardPoints := 1 + else + Inc(cardPoints, cardPoints); + Break; + end; + end; + end; + + Inc(FPart1, cardPoints); +end; + +procedure TScratchcards.Finish; +begin + +end; + +function TScratchcards.GetDataFileName: string; +begin + Result := 'scratchcards.txt'; +end; + +function TScratchcards.GetPuzzleName: string; +begin + Result := 'Day 4: Scratchcards'; +end; + +end. + diff --git a/tests/AdventOfCodeFPCUnit.lpi b/tests/AdventOfCodeFPCUnit.lpi index fff5ccd..4f20461 100644 --- a/tests/AdventOfCodeFPCUnit.lpi +++ b/tests/AdventOfCodeFPCUnit.lpi @@ -48,6 +48,10 @@ + + + + diff --git a/tests/AdventOfCodeFPCUnit.lpr b/tests/AdventOfCodeFPCUnit.lpr index cb55c7b..3aa8ff7 100644 --- a/tests/AdventOfCodeFPCUnit.lpr +++ b/tests/AdventOfCodeFPCUnit.lpr @@ -3,7 +3,7 @@ program AdventOfCodeFPCUnit; {$mode objfpc}{$H+} uses - Interfaces, Forms, GuiTestRunner, USolver, UBaseTestCases, UGearRatiosTestCases; + Interfaces, Forms, GuiTestRunner, USolver, UBaseTestCases, UGearRatiosTestCases, UScratchcardsTestCases; {$R *.res} diff --git a/tests/UScratchcardsTestCases.pas b/tests/UScratchcardsTestCases.pas new file mode 100644 index 0000000..5f41315 --- /dev/null +++ b/tests/UScratchcardsTestCases.pas @@ -0,0 +1,113 @@ +{ + 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 UScratchcardsTestCases; + +{$mode ObjFPC}{$H+} + +interface + +uses + Classes, SysUtils, fpcunit, testregistry, USolver, UBaseTestCases, UScratchcards; + +type + + { TScratchcardsBaseTestCase } + + TScratchcardsBaseTestCase = class(TBaseTestCase) + protected + procedure Setup; override; + end; + + { TScratchcardsFullDataTestCase } + + TScratchcardsFullDataTestCase = class(TScratchcardsBaseTestCase) + protected + procedure Setup; override; + published + procedure TestPart1; + procedure TestPart2; + end; + + { TScratchcardsExampleTestCase } + + TScratchcardsExampleTestCase = class(TScratchcardsBaseTestCase) + protected + procedure Setup; override; + published + procedure TestPart1; + procedure TestPart2; + end; + +implementation + +{ TScratchcardsBaseTestCase } + +procedure TScratchcardsBaseTestCase.Setup; +begin + inherited Setup; + FSolver := TScratchcards.Create; +end; + +{ TScratchcardsFullDataTestCase } + +procedure TScratchcardsFullDataTestCase.Setup; +begin + inherited Setup; + FEngine.ProcessData(FSolver); +end; + +procedure TScratchcardsFullDataTestCase.TestPart1; +begin + AssertEquals(21821, FSolver.GetResultPart1); +end; + +procedure TScratchcardsFullDataTestCase.TestPart2; +begin + AssertEquals(-1, FSolver.GetResultPart2); +end; + +{ TScratchcardsExampleTestCase } + +procedure TScratchcardsExampleTestCase.Setup; +begin + inherited Setup; + FSolver.Init; + FSolver.ProcessDataLine('Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53'); + FSolver.ProcessDataLine('Card 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19'); + FSolver.ProcessDataLine('Card 3: 1 21 53 59 44 | 69 82 63 72 16 21 14 1'); + FSolver.ProcessDataLine('Card 4: 41 92 73 84 69 | 59 84 76 51 58 5 54 83'); + FSolver.ProcessDataLine('Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36'); + FSolver.ProcessDataLine('Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11'); + FSolver.Finish; +end; + +procedure TScratchcardsExampleTestCase.TestPart1; +begin + AssertEquals(13, FSolver.GetResultPart1); +end; + +procedure TScratchcardsExampleTestCase.TestPart2; +begin + AssertEquals(-1, FSolver.GetResultPart2); +end; + +initialization + + RegisterTest(TScratchcardsFullDataTestCase); + RegisterTest(TScratchcardsExampleTestCase); +end. diff --git a/tests/bin/AdventOfCodeFPCUnit.fpcunit.ini b/tests/bin/AdventOfCodeFPCUnit.fpcunit.ini index 87cc773..d064076 100644 --- a/tests/bin/AdventOfCodeFPCUnit.fpcunit.ini +++ b/tests/bin/AdventOfCodeFPCUnit.fpcunit.ini @@ -23,3 +23,15 @@ TGearRatiosTestCase.Checked=1 TGearRatiosTestCase.Expanded=0 TGearRatiosTestCase.TestEndOfLineNumber.Checked=1 TGearRatiosTestCase.TestEndOfLineNumber.Expanded=0 +TScratchcardsFullDataTestCase.Checked=1 +TScratchcardsFullDataTestCase.Expanded=1 +TScratchcardsFullDataTestCase.TestPart1.Checked=1 +TScratchcardsFullDataTestCase.TestPart1.Expanded=0 +TScratchcardsFullDataTestCase.TestPart2.Checked=1 +TScratchcardsFullDataTestCase.TestPart2.Expanded=1 +TScratchcardsExampleTestCase.Checked=1 +TScratchcardsExampleTestCase.Expanded=1 +TScratchcardsExampleTestCase.TestPart1.Checked=1 +TScratchcardsExampleTestCase.TestPart1.Expanded=0 +TScratchcardsExampleTestCase.TestPart2.Checked=1 +TScratchcardsExampleTestCase.TestPart2.Expanded=1