Solve day 1 in ada

This commit is contained in:
Folkert Kevelam 2025-02-21 21:29:31 +01:00
parent e320e31369
commit 760478942b

179
AoC/2024/day_1/day_1.adb Normal file
View File

@ -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;