diff --git a/AdventOfCode.lpi b/AdventOfCode.lpi index 8751a01..8c3808e 100644 --- a/AdventOfCode.lpi +++ b/AdventOfCode.lpi @@ -30,9 +30,12 @@ - + + + + + - diff --git a/AdventOfCode.lpr b/AdventOfCode.lpr index 08750d6..d3d63eb 100644 --- a/AdventOfCode.lpr +++ b/AdventOfCode.lpr @@ -23,7 +23,8 @@ uses {$IFDEF UNIX} cthreads, {$ENDIF} - Classes, SysUtils, CustApp, UTrebuchet; + Classes, SysUtils, CustApp, + UTrebuchet, UCubeConundrum; type @@ -44,8 +45,9 @@ type procedure TAdventOfCode.RunPuzzleSolutions; begin - WriteLn('Advent of Code 2023'); - TTrebuchet.Solve; + WriteLn('### Advent of Code 2023 ###'); + TTrebuchet.Run; + TCubeConundrum.Run; end; procedure TAdventOfCode.DoRun; diff --git a/puzzles/UCubeConundrum.pas b/puzzles/UCubeConundrum.pas new file mode 100644 index 0000000..36e05f9 --- /dev/null +++ b/puzzles/UCubeConundrum.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 UCubeConundrum; + +{$mode ObjFPC}{$H+} + +interface + +uses + Classes, SysUtils; + +const + CMaxRed = 12; + CMaxGreen = 13; + CMaxBlue = 14; + +type + + { TCubeConundrum } + + TCubeConundrum = class(TObject) + private + FValue: Integer; + procedure ProcessDataLine(const ALine: string); + procedure ProcessGame(const id: Integer; const draws: TStringArray); + function ProcessDraw(const cubes: TStringArray): Boolean; + public + function Solve: Integer; + class procedure Run; static; + end; + +implementation + +{ TCubeConundrum } + +procedure TCubeConundrum.ProcessDataLine(const ALine: string); +var + gameSplit, subSplit: TStringArray; + id: Integer; +begin + gameSplit := ALine.Split(':'); + subSplit := gameSplit[0].Split(' '); + id := StrToInt(subSplit[1]); + subSplit := gameSplit[1].Split(';'); + ProcessGame(id, subSplit); +end; + +procedure TCubeConundrum.ProcessGame(const id: Integer; const draws: TStringArray); +var + draw: string; + drawSplit: TStringArray; +begin + for draw in draws do + begin + drawSplit := draw.Split(','); + if not ProcessDraw(drawSplit) then + Exit; + end; + + // All draws fulfill maxima. + Inc(FValue, id); +end; + +function TCubeConundrum.ProcessDraw(const cubes: TStringArray): Boolean; +var + cubeColor: string; + colorSplit: TStringArray; + max: Integer; +begin + for cubeColor in cubes do + begin + colorSplit := cubeColor.Trim.Split(' '); + if colorSplit[1] = 'red' then + max := CMaxRed + else if colorSplit[1] = 'green' then + max := CMaxGreen + else if colorSplit[1] = 'blue' then + max := CMaxBlue; + + if StrToInt(colorSplit[0]) > max then + begin + Result := False; + Exit; + end; + end; + + Result := True; +end; + +function TCubeConundrum.Solve: Integer; +var + data: TextFile; + s: string; +begin + FValue := 0; + + AssignFile(data, ConcatPaths(['data', 'cube_conundrum.txt'])); + try + reset(data); + while (not EOF(data)) do + begin + readln(data, s); + ProcessDataLine(s); + end; + finally + CloseFile(data) + end; + + Result := FValue; +end; + +class procedure TCubeConundrum.Run; +var + cubeConundrum: TCubeConundrum; +begin + WriteLn; + WriteLn('--- Day 2: Cube Conundrum ---'); + cubeConundrum := TCubeConundrum.Create; + WriteLn('Part 1: ', cubeConundrum.Solve); + cubeConundrum.Free; +end; + +end.