Added solution for "Day 4: Scratchcards", part 1

This commit is contained in:
Stefan Müller 2023-12-04 17:47:19 +01:00 committed by Stefan Müller
parent 5bfbc83b13
commit 4d81ae40d5
7 changed files with 241 additions and 2 deletions

View File

@ -45,6 +45,10 @@
<Filename Value="solvers\UGearRatios.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="solvers\UScratchcards.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>

View File

@ -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;

105
solvers/UScratchcards.pas Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
}
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.

View File

@ -48,6 +48,10 @@
<Filename Value="UBaseTestCases.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="UScratchcardsTestCases.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>

View File

@ -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}

View File

@ -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 <http://www.gnu.org/licenses/>.
}
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.

View File

@ -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