From d7552fdf029e8fc4c9f14b6e4e4d05e634ce1927 Mon Sep 17 00:00:00 2001 From: Folkert Kevelam Date: Sun, 16 Mar 2025 18:14:03 +0100 Subject: [PATCH] Add solutions to day 3 and day 3 2 --- AoC/2024/day_3/day_3.adb | 237 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 AoC/2024/day_3/day_3.adb diff --git a/AoC/2024/day_3/day_3.adb b/AoC/2024/day_3/day_3.adb new file mode 100644 index 0000000..28eb221 --- /dev/null +++ b/AoC/2024/day_3/day_3.adb @@ -0,0 +1,237 @@ +with Ada.Text_IO; use Ada.Text_IO; +with Ada.Containers.Vectors; + +procedure Day_3 is + + type Mul is + record + X : Integer; + Y : Integer; + end record; + + type Muls is array (Natural range <>) of Mul; + + package mul_vec is new Ada.Containers.Vectors( + Index_Type => Natural, Element_Type => Mul); + + procedure Find_Muls( S : String; Vec : in out mul_vec.Vector ) is + + type State_Machine is ( + Start, + Bracket_Open, + First_Num, + Second_Num + ); + + State : State_Machine := Start; + Index : Natural := S'First; + Num_Start : Natural; + FNum_Length, SNum_Length : Natural := 0; + First, Second : Integer; + + begin + + State_Loop: + while Index <= S'Last loop + case State is + when Start => + if Index + 2 > S'Last then + exit State_Loop; + end if; + if S(Index .. Index + 2) = "mul" then + State := Bracket_Open; + FNum_Length := 0; + SNum_Length := 0; + Index := @ + 2; + end if; + Index := @ + 1; + when Bracket_Open => + if S(Index) = '(' then + State := First_Num; + Num_Start := Index + 1; + else + State := Start; + end if; + Index := @ + 1; + when First_Num => + case S(Index) is + when ',' => + First := Integer'Value(S(Num_Start .. Index - 1)); + State := Second_Num; + Num_Start := Index + 1; + Index := @ + 1; + when '0' .. '9' => + FNum_Length := @ + 1; + Index := @ + 1; + when others => + State := Start; + end case; + + if FNum_Length > 3 then + State := Start; + end if; + when Second_Num => + case S(Index) is + when ')' => + Second := Integer'Value(S(Num_Start .. Index - 1)); + State := Start; + Num_Start := Index + 1; + Vec.Append( + Mul'(X => First, Y => Second) + ); + Index := @ + 1; + when '0' .. '9' => + SNum_Length := @ + 1; + Index := @ + 1; + when others => + State := Start; + end case; + + if SNum_Length > 3 then + State := Start; + end if; + end case; + end loop State_Loop; + + end Find_Muls; + + procedure Find_Muls_Cond( S : String; Vec : in out mul_vec.Vector; Enabled : in out Boolean ) is + + type State_Machine is ( + Start, + Bracket_Open, + First_Num, + Second_Num + ); + + State : State_Machine := Start; + Index : Natural := S'First; + Num_Start : Natural; + FNum_Length, SNum_Length : Natural := 0; + First, Second : Integer; + + begin + State_Loop: + while Index <= S'Last loop + if Index + 7 < S'Last then + if S(Index .. Index + 3) = "do()" then + Put_Line(S(Index .. Index + 3)); + Index := @ + 4; + Enabled := True; + elsif S(Index .. Index + 6) = "don't()" then + Put_Line(S(Index .. Index + 6)); + Enabled := False; + State := Start; + Index := @ + 7; + end if; + end if; + + case State is + when Start => + if Index + 2 > S'Last then + exit State_Loop; + end if; + if S(Index .. Index + 2) = "mul" then + State := Bracket_Open; + FNum_Length := 0; + SNum_Length := 0; + Index := @ + 2; + end if; + Index := @ + 1; + when Bracket_Open => + if S(Index) = '(' then + State := First_Num; + Num_Start := Index + 1; + else + State := Start; + end if; + Index := @ + 1; + when First_Num => + case S(Index) is + when ',' => + First := Integer'Value(S(Num_Start .. Index - 1)); + State := Second_Num; + Num_Start := Index + 1; + Index := @ + 1; + when '0' .. '9' => + FNum_Length := @ + 1; + Index := @ + 1; + when others => + State := Start; + end case; + + if FNum_Length > 3 then + State := Start; + end if; + when Second_Num => + case S(Index) is + when ')' => + Second := Integer'Value(S(Num_Start .. Index - 1)); + State := Start; + Num_Start := Index + 1; + if Enabled then + Put_Line("mul(" & First'Image & "," & Second'Image & ")"); + Vec.Append( + Mul'(X => First, Y => Second) + ); + else + Put_Line("Disabled"); + end if; + Index := @ + 1; + when '0' .. '9' => + SNum_Length := @ + 1; + Index := @ + 1; + when others => + State := Start; + end case; + + if SNum_Length > 3 then + State := Start; + end if; + end case; + end loop State_Loop; + end Find_Muls_Cond; + + function Read_File( File_Name : String; cond : Boolean ) return Muls is + File : File_Type; + Vec : mul_vec.Vector; + Enabled : Boolean := True; + begin + Open(File, In_File, File_Name); + + while not End_Of_File(File) loop + if cond then + Find_Muls_cond(Get_Line(File), Vec, Enabled); + else + Find_Muls(Get_Line(File), Vec); + end if; + end loop; + + Close(File); + + return M : Muls( 0 .. Integer(Vec.Length) - 1) do + for I in 0 .. Integer(Vec.Length) - 1 loop + M(I) := Vec(I); + end loop; + end return; + + end Read_File; + + function Day_1_1( M : Muls ) return Integer is + Sum : Integer := 0; + begin + For Mult of M loop + Sum := @ + Mult.X * Mult.Y; + end loop; + + return Sum; + end Day_1_1; + + File_Name : String := "input_day_3.txt"; + +begin + + Put_Line(Day_1_1(Read_File(File_Name, False))'Image); + Put_Line(Day_1_1(Read_File(File_Name, True))'Image); + +end Day_3;