From 85314237dd92db15a8dbd4f9aa9ed391333461c5 Mon Sep 17 00:00:00 2001 From: Folkert Kevelam Date: Tue, 25 Feb 2025 21:46:47 +0100 Subject: [PATCH] Solve day 2 part 1 --- AoC/2024/day_2/day_2.adb | 134 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 AoC/2024/day_2/day_2.adb diff --git a/AoC/2024/day_2/day_2.adb b/AoC/2024/day_2/day_2.adb new file mode 100644 index 0000000..61e22d8 --- /dev/null +++ b/AoC/2024/day_2/day_2.adb @@ -0,0 +1,134 @@ +with Ada.Text_IO; use Ada.Text_IO; +with Ada.Containers.Vectors; + +procedure Day_2 is + + type Levels is array (Natural range <> ) of Integer; + + type Ordering is (Increasing, Decreasing); + + type Safety is (Safe, Unsafe); + + type Report is + record + Values : Levels(0 .. 9); + Count : Natural := 0; + end record; + + type Reports is array (Natural range <>) of Report; + + function Calculate_Report( R : Report ) return Safety is + Order : Ordering; + begin + if R.Count > 1 then + if R.Values(1) > R.Values(0) then + Order := Increasing; + elsif R.Values(1) < R.Values(0) then + Order := Decreasing; + else + return Unsafe; + end if; + else + return Unsafe; + end if; + + for I in 1 .. R.Count - 1 loop + declare + Diff : Integer := R.Values(I) - R.Values(I-1); + Adiff : Integer := abs(Diff); + begin + if ADiff < 1 or ADiff > 3 then + return Unsafe; + elsif Diff > 0 and Order = Decreasing then + return Unsafe; + elsif Diff < 0 and Order = Increasing then + return Unsafe; + end if; + end; + end loop; + + return Safe; + end Calculate_Report; + + function Get_Safe_Reports( R : Reports ) return Natural is + Sum : Natural := 0; + begin + for Rep of R loop + declare + Result : Safety := Calculate_Report(Rep); + begin + if Result = Safe then + Sum := @ + 1; + end if; + end; + end loop; + + return Sum; + end Get_Safe_Reports; + + function ToNum( Num : String ) return Integer is + begin + return Integer'Value(Num); + end ToNum; + + function Read_Report( Line : String ) return Report is + In_Num : Boolean := False; + Start_Num : Natural; + Result : Report; + begin + for I in Line'Range loop + case Line(I) is + when '-' | '0' .. '9' => + if not In_Num then + In_Num := True; + Start_Num := I; + end if; + when others => + if In_Num then + Result.Values(Result.Count) := + ToNum(Line(Start_Num .. I-1)); + Result.Count := @ + 1; + In_Num := False; + end if; + end case; + end loop; + + if In_Num then + Result.Values(Result.Count) := + ToNum(Line(Start_Num .. Line'Last)); + Result.Count := @ + 1; + end if; + + return Result; + end Read_Report; + + function Read_File( File_Name : String ) return Reports is + File : File_Type; + + package vec is new + Ada.Containers.Vectors( Natural, Report ); + + use vec; + + Result : vec.Vector; + + begin + Open( File, In_File, File_Name ); + while not End_Of_File(File) loop + Result.Append(Read_Report(Get_Line(File))); + end loop; + + Close( File); + + return R : Reports( 0 .. Natural(Result.Length) - 1) do + for I in Result.First_Index .. Result.Last_Index loop + R(Natural(I)) := Result(Natural(I)); + end loop; + end return; + end Read_File; + + File_Name : String := "input_day_2.txt"; + +begin + Put_Line("Day 2 1:" & Get_Safe_Reports(Read_File(File_Name))'Image); +end Day_2;