From cc868a6c0aad0866f85152fa7d7a4d1db7d76363 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20M=C3=BCller?= Date: Mon, 4 Dec 2023 21:59:39 +0100 Subject: [PATCH] Added solution for "Day 4: Scratchcards", part 2 --- solvers/UScratchcards.pas | 41 ++++++++++++++++++++++++++++++-- tests/UScratchcardsTestCases.pas | 4 ++-- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/solvers/UScratchcards.pas b/solvers/UScratchcards.pas index ede0449..c22ddfa 100644 --- a/solvers/UScratchcards.pas +++ b/solvers/UScratchcards.pas @@ -22,7 +22,7 @@ unit UScratchcards; interface uses - Classes, SysUtils, USolver; + Classes, SysUtils, fgl, USolver; type @@ -30,8 +30,11 @@ type TScratchcards = class(TSolver) private + FCardCopies: specialize TFPGList; function GetNumber(const AString: string; const AIndex: Integer): Integer; public + constructor Create; + destructor Destroy; override; procedure ProcessDataLine(const ALine: string); override; procedure Finish; override; function GetDataFileName: string; override; @@ -48,12 +51,33 @@ begin Result := StrToInt(Trim(Copy(AString, AIndex * 3 + 1, 3))) end; +constructor TScratchcards.Create; +begin + FCardCopies := specialize TFPGList.Create; +end; + +destructor TScratchcards.Destroy; +begin + FCardCopies.Free; + inherited Destroy; +end; + procedure TScratchcards.ProcessDataLine(const ALine: string); var cardSplit: TStringArray; wins: array of Integer; - count, i, have, win, cardPoints: Integer; + count, i, have, win, cardPoints, cardMatches, cardCopies: Integer; begin + // Counts copies of this card. + if FCardCopies.Count > 0 then + begin + cardCopies := FCardCopies[0]; + FCardCopies.Delete(0); + end + else + cardCopies := 1; + Inc(FPart2, cardCopies); + cardSplit := ALine.Split([':', '|']); // Determines winning numbers. @@ -66,6 +90,7 @@ begin // Checks have numbers against winning numbers. cardPoints := 0; + cardMatches := 0; count := cardSplit[2].Length div 3; for i := 0 to count - 1 do begin @@ -78,12 +103,24 @@ begin cardPoints := 1 else Inc(cardPoints, cardPoints); + Inc(cardMatches); Break; end; end; end; Inc(FPart1, cardPoints); + + // Adds copies of following cards and deletes the current card count. + if FCardCopies.Capacity < cardMatches then + FCardCopies.Capacity := cardMatches; + for i := 0 to cardMatches - 1 do + begin + if FCardCopies.Count <= i then + FCardCopies.Add(cardCopies + 1) + else + FCardCopies[i] := FCardCopies[i] + cardCopies; + end; end; procedure TScratchcards.Finish; diff --git a/tests/UScratchcardsTestCases.pas b/tests/UScratchcardsTestCases.pas index 5f41315..1377c5e 100644 --- a/tests/UScratchcardsTestCases.pas +++ b/tests/UScratchcardsTestCases.pas @@ -78,7 +78,7 @@ end; procedure TScratchcardsFullDataTestCase.TestPart2; begin - AssertEquals(-1, FSolver.GetResultPart2); + AssertEquals(5539496, FSolver.GetResultPart2); end; { TScratchcardsExampleTestCase } @@ -103,7 +103,7 @@ end; procedure TScratchcardsExampleTestCase.TestPart2; begin - AssertEquals(-1, FSolver.GetResultPart2); + AssertEquals(30, FSolver.GetResultPart2); end; initialization