Add solutions to day 3 and day 3 2
This commit is contained in:
parent
48a8c1dcf6
commit
d7552fdf02
237
AoC/2024/day_3/day_3.adb
Normal file
237
AoC/2024/day_3/day_3.adb
Normal file
|
|
@ -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;
|
||||
Loading…
Reference in New Issue
Block a user