From 37f4198325ddc3eecd63518b9ba9703ce2ee110f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20M=C3=BCller?= Date: Sat, 2 Dec 2023 18:31:47 +0100 Subject: [PATCH] Added solution for "Day 1: Trebuchet?!", part 2 --- puzzles/utrebuchet.pas | 86 ++++++++++++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 28 deletions(-) diff --git a/puzzles/utrebuchet.pas b/puzzles/utrebuchet.pas index 7abb7b5..b6076a7 100644 --- a/puzzles/utrebuchet.pas +++ b/puzzles/utrebuchet.pas @@ -22,48 +22,31 @@ unit UTrebuchet; interface uses - Classes, SysUtils; + Classes, SysUtils, TypInfo; type + TSpelledOutDigit = (zero, one, two, three, four, five, six, seven, eight, nine); { TTrebuchet } TTrebuchet = class(TObject) private FValue: Integer; - procedure RunSolution; + FConsiderSpelledOutDigits: Boolean; procedure ProcessDataLine(const ALine: string); function FindFirstDigit(const ALine: string; out OEndIndex: Integer): Integer; function FindLastDigit(const ALine: string; const AFirstDigit, AFirstDigitEndIndex: Integer): Integer; function CheckDigit(const ALine: string; const AIndex: Integer; out ODigit, OEndIndex: Integer): Boolean; + function CheckSpelledOutDigit(const ALine: string; const AIndex: Integer; out ODigit, OEndIndex: Integer): Boolean; public - constructor Create; - class procedure Solve; static; + function Solve(const AConsiderSpelledOutDigits: Boolean): Integer; + class procedure Run; static; end; implementation { TTrebuchet } -procedure TTrebuchet.RunSolution; -var - data: TextFile; - s: string; -begin - AssignFile(data, ConcatPaths(['data', 'trebuchet_calibration_document.txt'])); - try - reset(data); - while (not EOF(data)) do - begin - readln(data, s); - ProcessDataLine(s); - end; - finally - CloseFile(data) - end; - WriteLn('Part 1: ', FValue); -end; - procedure TTrebuchet.ProcessDataLine(const ALine: string); var first, endIndex, last: Integer; @@ -100,27 +83,74 @@ begin begin ODigit := StrToInt(ALine[AIndex]); OEndIndex := AIndex; + Result := True; + end + else if FConsiderSpelledOutDigits and CheckSpelledOutDigit(ALine, AIndex, ODigit, OEndIndex) then + begin Result := true; end else begin ODigit := -1; OEndIndex := -1; - Result := false; + Result := False; end; end; -constructor TTrebuchet.Create; +function TTrebuchet.CheckSpelledOutDigit(const ALine: string; const AIndex: Integer; out ODigit, OEndIndex: Integer): + Boolean; +var + i: Integer; + digitName: string; begin - FValue := 0; + for i := Ord(Low(TSpelledOutDigit)) to Ord(High(TSpelledOutDigit)) do + begin + digitName := GetEnumName(TypeInfo(TSpelledOutDigit), Ord(i)); + if CompareStr(digitName, Copy(ALine, AIndex, digitName.Length)) = 0 then + begin + ODigit := i; + OEndIndex := AIndex + digitName.Length - 1; + Result := True; + Exit; + end; + end; + + ODigit := -1; + OEndIndex := -1; + Result := False; end; -class procedure TTrebuchet.Solve; +function TTrebuchet.Solve(const AConsiderSpelledOutDigits: Boolean): Integer; +var + data: TextFile; + s: string; +begin + FValue := 0; + FConsiderSpelledOutDigits := AConsiderSpelledOutDigits; + + AssignFile(data, ConcatPaths(['data', 'trebuchet_calibration_document.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 TTrebuchet.Run; var trebuchet: TTrebuchet; begin + WriteLn; WriteLn('--- Day 1: Trebuchet?! ---'); trebuchet := TTrebuchet.Create; - trebuchet.RunSolution; + WriteLn('Part 1: ', trebuchet.Solve(False)); + WriteLn('Part 2: ', trebuchet.Solve(True)); trebuchet.Free; end;