diff --git a/AdventOfCode.lpi b/AdventOfCode.lpi index 64a32e1..646efc6 100644 --- a/AdventOfCode.lpi +++ b/AdventOfCode.lpi @@ -37,6 +37,10 @@ + + + + diff --git a/AdventOfCode.lpr b/AdventOfCode.lpr index d3d63eb..c5c3607 100644 --- a/AdventOfCode.lpr +++ b/AdventOfCode.lpr @@ -24,6 +24,7 @@ uses cthreads, {$ENDIF} Classes, SysUtils, CustApp, + USolver, UTrebuchet, UCubeConundrum; type @@ -44,10 +45,14 @@ type { TAdventOfCode } procedure TAdventOfCode.RunPuzzleSolutions; +var + engine: TSolverEngine; begin WriteLn('### Advent of Code 2023 ###'); TTrebuchet.Run; TCubeConundrum.Run; + engine := TSolverEngine.Create; + engine.Free; end; procedure TAdventOfCode.DoRun; diff --git a/USolver.pas b/USolver.pas new file mode 100644 index 0000000..a5e0de9 --- /dev/null +++ b/USolver.pas @@ -0,0 +1,138 @@ +{ + 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 USolver; + +{$mode ObjFPC}{$H+} +{$interfaces corba} + +interface + +uses + Classes, SysUtils; + +type + + { ISolver } + + ISolver = interface + procedure Init; + procedure ProcessDataLine(const ALine: string); + procedure Finish; + procedure Free; + function GetDataFileName: string; + function GetPuzzleName: string; + function GetResultPart1: Integer; + function GetResultPart2: Integer; + property DataFileName: string read GetDataFileName; + property PuzzleName: string read GetPuzzleName; + property ResultPart1: Integer read GetResultPart1; + property ResultPart2: Integer read GetResultPart2; + end; + + { TSolver } + + TSolver = class abstract(ISolver) + protected + FPart1, FPart2: Integer; + public + procedure Init; virtual; + procedure ProcessDataLine(const ALine: string); virtual; abstract; + procedure Finish; virtual; abstract; + procedure Free; virtual; + function GetDataFileName: string; virtual; abstract; + function GetPuzzleName: string; virtual; abstract; + function GetResultPart1: Integer; virtual; + function GetResultPart2: Integer; virtual; + end; + + { TSolverEngine } + + TSolverEngine = class + private + procedure ProcessData(constref ASolver: ISolver); + public + procedure Run(constref ASolver: ISolver); + procedure RunAndFree(constref ASolver: ISolver); + end; + +implementation + +{ TSolver } + +procedure TSolver.Init; +begin + FPart1 := 0; + FPart2 := 0; +end; + +procedure TSolver.Free; +begin + Free; +end; + +function TSolver.GetResultPart1: Integer; +begin + Result := FPart1; +end; + +function TSolver.GetResultPart2: Integer; +begin + Result := FPart2; +end; + +{ TSolverEngine } + +procedure TSolverEngine.ProcessData(constref ASolver: ISolver); +var + data: TextFile; + s: string; +begin + ASolver.Init; + + AssignFile(data, ConcatPaths(['data', ASolver.DataFileName])); + try + reset(data); + while (not EOF(data)) do + begin + readln(data, s); + ASolver.ProcessDataLine(s); + end; + finally + CloseFile(data) + end; + + ASolver.Finish; +end; + +procedure TSolverEngine.Run(constref ASolver: ISolver); +begin + WriteLn; + WriteLn('--- ', ASolver.PuzzleName, ' ---'); + ProcessData(ASolver); + WriteLn('Part 1: ', ASolver.ResultPart1); + WriteLn('Part 2: ', ASolver.ResultPart2); +end; + +procedure TSolverEngine.RunAndFree(constref ASolver: ISolver); +begin + Run(ASolver); + ASolver.Free; +end; + +end. +