Created
December 1, 2023 15:11
-
-
Save Ancurio/aa034b64501afe98e10e0fd9503b2de6 to your computer and use it in GitHub Desktop.
Advent of Code 2023 Day 01
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
with Text_IO; use Text_IO; | |
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; | |
with Ada.Strings.Unbounded; | |
with Ada.Characters.Handling; | |
procedure main is | |
package SU renames Ada.Strings.Unbounded; | |
package CH renames Ada.Characters.Handling; | |
InputFile : File_Type; | |
Fname : constant String := "input.txt"; | |
CurrentLine : SU.Unbounded_String; | |
CurrentChoppedLine : SU.Unbounded_String; | |
FirstDigit : Integer; | |
LastDigit : Integer; | |
Accum : Integer := 0; | |
CurrentChar : Character; | |
AsciiDigitBase : Integer := Character'Pos('0'); | |
CurrentCharAsInt : Integer; | |
FirstDigitSeen : Boolean; | |
FoundDigit : Boolean; | |
-- Check whether <Text> begins with <SearchWord> | |
function Find(Text : in String; SearchWord : in String) return Boolean is | |
begin | |
if SearchWord'Length > Text'Length then | |
return False; | |
end if; | |
for I in 1..SearchWord'Length loop | |
if SearchWord(I) /= Text(I) then | |
return False; | |
end if; | |
end loop; | |
return True; | |
end Find; | |
-- Try to find a written out digit at the beginning of <Str>, and if found, | |
-- write its integer value to <Value>. Returns whether a digit was found. | |
function LookForWrittenDigit(Str : in String; Value : out Integer) return Boolean is | |
begin | |
if Find(Str, "one") then | |
Value := 1; | |
return True; | |
elsif Find(Str, "two") then | |
Value := 2; | |
return True; | |
elsif Find(Str, "three") then | |
Value := 3; | |
return True; | |
elsif Find(Str, "four") then | |
Value := 4; | |
return True; | |
elsif Find(Str, "five") then | |
Value := 5; | |
return True; | |
elsif Find(Str, "six") then | |
Value := 6; | |
return True; | |
elsif Find(Str, "seven") then | |
Value := 7; | |
return True; | |
elsif Find(Str, "eight") then | |
Value := 8; | |
return True; | |
elsif Find(Str, "nine") then | |
Value := 9; | |
return True; | |
end if; | |
return False; | |
end LookForWrittenDigit; | |
begin | |
Open(InputFile, In_File, Fname); | |
while not End_Of_File(InputFile) loop | |
CurrentLine := SU.To_Unbounded_String(Get_Line(InputFile)); | |
FirstDigit := 0; | |
LastDigit := 0; | |
FirstDigitSeen := False; | |
CurrentChoppedLine := CurrentLine; | |
FoundDigit := False; | |
for I in 1..SU.Length(CurrentLine) loop | |
CurrentChar := SU.Element(CurrentChoppedLine, 1); | |
-- Check char digit first | |
if CH.Is_Digit(CurrentChar) then | |
CurrentCharAsInt := Character'Pos(CurrentChar) - AsciiDigitBase; | |
FoundDigit := True; | |
-- Then check written out digit | |
elsif LookForWrittenDigit(SU.To_String(CurrentChoppedLine), CurrentCharAsInt) then | |
FoundDigit := True; | |
end if; | |
if FoundDigit then | |
LastDigit := CurrentCharAsInt; | |
if not FirstDigitSeen then | |
FirstDigitSeen := True; | |
FirstDigit := CurrentCharAsInt; | |
end if; | |
FoundDigit := False; | |
end if; | |
-- Continuously chop off the first character of the line | |
CurrentChoppedLine := | |
SU.Unbounded_Slice(CurrentChoppedLine, 2, SU.Length(CurrentChoppedLine)); | |
end loop; | |
-- First and LastDigit now have the correct values for the current line | |
Accum := Accum + (FirstDigit * 10) + LastDigit; | |
end loop; | |
Put("Accum: "); | |
Put_Line(Integer'Image(Accum)); | |
Close(InputFile); | |
end main; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment