From 60c80cf9466b3f1d8e9a7dbb984c177c03452c91 Mon Sep 17 00:00:00 2001 From: Folkert Kevelam Date: Wed, 19 Mar 2025 20:08:32 +0100 Subject: [PATCH] Add solutions for day 3 part 1 and part 2 --- AoC/2015/day_3/day_3.adb | 120 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 AoC/2015/day_3/day_3.adb diff --git a/AoC/2015/day_3/day_3.adb b/AoC/2015/day_3/day_3.adb new file mode 100644 index 0000000..5928828 --- /dev/null +++ b/AoC/2015/day_3/day_3.adb @@ -0,0 +1,120 @@ +with Ada.Text_IO; use Ada.Text_IO; +with Ada.Containers; use Ada.Containers; +with Ada.Containers.Hashed_Sets; + +procedure Day_3 is + + type Uint32 is mod 2**32; + + type Coordinate is + record + X : Uint32; + Y : Uint32; + end record; + + function "=" (A,B : Coordinate) return Boolean is + begin + return A.X = B.X and A.Y = B.Y; + end "="; + + type Coordinates is array (Natural range <>) of Coordinate; + + function Hash(A : Uint32) return Uint32 is + Key : Uint32 := A; + begin + Key := (not @) + (@ * 2**15); + Key := @ or (@ / 2**12); + Key := @ + (@ * 2**2); + Key := @ or (@ / 2**4); + Key := @ * 2057; + Key := @ or (Key / 2**16); + return Key; + end Hash; + + function Hash(A : Coordinate) return Hash_Type is + Result : UInt32 := Hash((53 + Hash(A.X)) * 53 + Hash(A.Y)); + begin + return Hash_Type(Integer(Result/2)); + end Hash; + + package Set is new Ada.Containers.Hashed_Sets( + Element_Type => Coordinate, + Hash => Hash, + Equivalent_Elements => "="); + + function Read_File(File_Name : String) return Set.Set is + S : Set.Set; + Base : Coordinate := ( X => 0, Y => 0); + File : File_Type; + begin + S.Insert(Base); + Open(File, In_File, File_Name); + + main_loop: + while not End_Of_File(File) loop + declare + Line : String := Get_Line(File); + begin + for I in Line'Range loop + case Line(I) is + when '^' => Base.Y := @ + 1; + when 'v' => Base.Y := @ - 1; + when '>' => Base.X := @ + 1; + when '<' => Base.X := @ - 1; + when others => exit main_loop; + end case; + if not S.Contains(Base) then + S.Insert(Base); + end if; + end loop; + end; + end loop main_loop; + + Close(File); + + return S; + end Read_File; + + function Read_File_Part_Two(File_Name : String) return Set.Set is + S : Set.Set; + Base : Coordinates(0 .. 1) := + (others => (X => 0, Y => 0)); + File : File_Type; + Santa : Natural := 0; + begin + S.Insert(Base(0)); + Open(File, In_File, File_Name); + + main_loop: + while not End_Of_File(File) loop + declare + Line : String := Get_Line(File); + begin + for I in Line'Range loop + case Line(I) is + when '^' => Base(Santa).Y := @ + 1; + when 'v' => Base(Santa).Y := @ - 1; + when '>' => Base(Santa).X := @ + 1; + when '<' => Base(Santa).X := @ - 1; + when others => exit main_loop; + end case; + if not S.Contains(Base(Santa)) then + S.Insert(Base(Santa)); + end if; + Santa := (@ + 1) mod 2; + end loop; + end; + end loop main_loop; + + Close(File); + return S; + end Read_File_Part_Two; + + File_Name : String := "input_day_3.txt"; + S : Set.Set; + +begin + + Put_Line(Read_File_Part_Two(File_Name).Length'Image); + +end Day_3;