From 760478942b870517a6749b54c45f26b6df4fb7a6 Mon Sep 17 00:00:00 2001 From: Folkert Kevelam Date: Fri, 21 Feb 2025 21:29:31 +0100 Subject: [PATCH] Solve day 1 in ada --- AoC/2024/day_1/day_1.adb | 179 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 AoC/2024/day_1/day_1.adb diff --git a/AoC/2024/day_1/day_1.adb b/AoC/2024/day_1/day_1.adb new file mode 100644 index 0000000..1dfd312 --- /dev/null +++ b/AoC/2024/day_1/day_1.adb @@ -0,0 +1,179 @@ +with Ada.Text_IO; use Ada.Text_IO; +with Ada.Numerics.Elementary_Functions; use Ada.Numerics.Elementary_Functions; +with Ada.Containers.Generic_Array_Sort; +with Ada.Containers.Vectors; + +procedure Day_1 is + + type Index is new Natural; + type Input is array ( Index range <>) of Integer; + type Count is new Natural; + + type Counted_Data is + record + Data : Integer; + Data_Count : Count; + end record; + + type Count_Array is array (Index range <> ) of Counted_Data; + + function Day_1_1( Left, Right : Input ) return Integer is + Sorted_Left : Input := Left; + Sorted_Right : Input := Right; + + Score : Integer := 0; + + procedure Sort is + new Ada.Containers.Generic_Array_Sort(Index, Integer, Input); + begin + + Sort(Sorted_Left); + Sort(Sorted_Right); + + for I in Sorted_Left'Range loop + Score := @ + abs(Sorted_Left(I) - Sorted_Right(I)); + end loop; + + return Score; + + end Day_1_1; + + function Sort_And_Deduplicate( Arr : Input ) return Count_Array is + Sorted : Input := Arr; + Out_Arr : Count_Array( Index'First .. Arr'Length ); + Arr_Index : Index := Index'First; + In_Index : Index := Index'First; + + procedure Sort is + new Ada.Containers.Generic_Array_Sort(Index, Integer, Input); + begin + Sort(Sorted); + + Out_Arr(Arr_Index).Data := Sorted(Index'First); + Out_Arr(Arr_Index).Data_Count := 0; + + for I in Index'First .. (Index'First + Arr'Length - 1) loop + if( Sorted(I) = Out_Arr(Arr_Index).Data) then + Out_Arr(Arr_Index).Data_Count := @ + 1; + else + Arr_Index := @ + 1; + Out_Arr(Arr_Index).Data := Sorted(I); + Out_Arr(Arr_Index).Data_Count := 1; + end if; + end loop; + + return Out_Con : Count_Array(Index'First .. Arr_Index) do + for I in Index'First .. Arr_Index loop + Out_Con(I) := Out_Arr(I); + end loop; + end return; + end Sort_And_Deduplicate; + + function Find( Num : Integer; Arr : Count_Array ) return Count is + Lower_Bound : Index := Index'First; + Upper_Bound : Index := Arr'Length - 1; + Upper : Integer := 1 + Integer(Log(Float(Arr'Length), 2.0)); + Mid : Index; + begin + for I in 0 .. Upper loop + if Upper_Bound - Lower_Bound <= 1 then + if Num = Arr(Upper_Bound).Data then + return Arr(Upper_Bound).Data_Count; + elsif Num = Arr(Upper_Bound).Data then + return Arr(Upper_Bound).Data_Count; + else + return 0; + end if; + end if; + + Mid := (Upper_Bound + Lower_Bound) / 2; + if Num > Arr(Mid).Data then + Lower_Bound := Mid; + elsif Num < Arr(Mid).Data then + Upper_Bound := Mid; + else + return Arr(Mid).Data_Count; + end if; + end loop; + + return 0; + end Find; + + function Day_1_2( Left, Right : Input ) return Integer is + C_Left : Count_Array := Sort_And_Deduplicate(Left); + C_Right : Count_Array := Sort_And_Deduplicate(Right); + Score : Integer := 0; + begin + + for I in C_Left'Range loop + declare + D : Integer := Integer(Find(C_Left(I).Data, C_Right)); + C : Integer := Integer(C_Left(I).Data_Count); + begin + Score := @ + D * C * C_Left(I).Data; + end; + end loop; + + return Score; + + end Day_1_2; + + type Array2( Count : Index ) is + record + Left : Input( 0 .. Count); + Right : Input( 0 .. Count); + end record; + + function Read_Arrays_Into_File( Filename : String ) return Array2 is + File : File_Type; + + package Vec is new Ada.Containers.Vectors( Index, Integer ); + use Vec; + + Left : Vec.Vector; + Right : Vec.Vector; + begin + Open(File, In_File, Filename); + + while not End_Of_File(File) loop + declare + Line : String := Get_Line(File); + Start_First : Integer := Line'First; + End_First : Integer := 0; + Start_Second : Integer := 0; + End_Second : Integer := Line'Last; + Index : Integer := Line'First; + begin + while Line(Index) /= ' ' loop + Index := @ + 1; + end loop; + End_First := Index - 1; + while Line(Index) = ' ' loop + Index := @ + 1; + end loop; + Start_Second := Index; + Left.Append( + Integer'Value(Line(Start_First .. End_First))); + Right.Append( + Integer'Value(Line(Start_Second .. End_Second))); + end; + end loop; + + Close(File); + + return Out_Arr : Array2( Index(Left.Length) ) do + for I in Left.First_Index .. Left.Last_Index loop + Out_Arr.Left(I) := Left(I); + Out_Arr.Right(I) := Right(I); + end loop; + end return; + + end Read_Arrays_Into_File; + + Filename : String := "input_day_1_1.txt"; + + Data : Array2 := Read_Arrays_Into_File(Filename); +begin + Put_Line("Sum score: " & Day_1_1(Data.Left, Data.Right)'Image); + Put_Line("Simi score: " & Day_1_2(Data.Left, Data.Right)'Image); +end Day_1;