Skip to content

Instantly share code, notes, and snippets.

@Ancurio
Created December 1, 2023 15:11
Show Gist options
  • Save Ancurio/aa034b64501afe98e10e0fd9503b2de6 to your computer and use it in GitHub Desktop.
Save Ancurio/aa034b64501afe98e10e0fd9503b2de6 to your computer and use it in GitHub Desktop.
Advent of Code 2023 Day 01
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