From 42f70ecd1b8714f984440be4d17e41643ad4a263 Mon Sep 17 00:00:00 2001 From: Folkert Kevelam Date: Fri, 28 Feb 2025 22:58:42 +0100 Subject: [PATCH] Add dirty solution for day 2 2 --- AoC/2024/day_2/day_2.adb | 123 ++++++++++++++++++++++++++++++--------- 1 file changed, 95 insertions(+), 28 deletions(-) diff --git a/AoC/2024/day_2/day_2.adb b/AoC/2024/day_2/day_2.adb index 61e22d8..dbd8164 100644 --- a/AoC/2024/day_2/day_2.adb +++ b/AoC/2024/day_2/day_2.adb @@ -3,59 +3,125 @@ with Ada.Containers.Vectors; procedure Day_2 is + type Safety is (Unsafe, Safe); + type Ordering is (Increasing, Decreasing, Equal); + 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); + Values : Levels(0 .. 9) := (others => 0); Count : Natural := 0; end record; type Reports is array (Natural range <>) of Report; + type Orderings is array (Natural range <>) of Ordering; + type Safeties is array (Natural range <>) of Safety; - function Calculate_Report( R : Report ) return Safety is - Order : Ordering; + type Level_Report is + record + Order : Orderings( 0 .. 9 ) := (others => Equal); + Diff : Levels( 0 .. 9 ) := (others => 0); + Count : Natural := 0; + end record; + + function Calculate_Levels( R : Report ) return Level_Report is + Out_R : Level_Report; 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 + for I in 0 .. R.Count - 2 loop + declare + Diff : Integer := R.Values(I+1) - R.Values(I); + begin + if Diff > 0 then + Out_R.Order(I) := Increasing; + elsif Diff < 0 then + Out_R.Order(I) := Decreasing; + else + Out_R.Order(I) := Equal; + end if; + + Out_R.Diff(I) := abs(Diff); + end; + end loop; + + Out_R.Count := R.Count - 1; + + return Out_R; + end Calculate_Levels; + + function Calculate_Report( Levels : Level_Report ) return Safety is + begin + if Levels.Diff(0) < 1 or Levels.Diff(0) > 3 then return Unsafe; end if; - for I in 1 .. R.Count - 1 loop + for I in 0 .. Levels.Count - 2 loop + if not (Levels.Order(I+1) = Levels.Order(I)) then + return Unsafe; + end if; + if Levels.Diff(I+1) < 1 or Levels.Diff(I+1) > 3 then + return Unsafe; + end if; + end loop; + + if Levels.Order(0) = Equal then + return Unsafe; + end if; + + return Safe; + end Calculate_Report; + + function Calculate_Report_Lossy( R : Report ) return Safety is + Levels : Level_Report := Calculate_Levels(R); + begin + if Calculate_Report( Levels ) = Safe then + return Safe; + else + for I in 0 .. R.Count - 1 loop + declare + New_Report : Report; + begin + for J in 0 .. I-1 loop + New_Report.Values(J) := R.Values(J); + end loop; + for J in I+1 .. R.Count -1 loop + New_Report.Values(J-1) := R.Values(J); + end loop; + New_Report.Count := R.Count - 1; + Put_Line("Check level reduced report @" & Integer'Image(I)); + Put_Line(R'Image); + Put_Line(New_Report'Image); + if Calculate_Report(Calculate_Levels( New_Report)) = Safe then + return Safe; + end if; + end; + end loop; + return Unsafe; + end if; + end Calculate_Report_Lossy; + + function Get_Safe_Reports_Lossy( R : Reports ) return Natural is + Sum : Natural := 0; + begin + for Rep of R loop declare - Diff : Integer := R.Values(I) - R.Values(I-1); - Adiff : Integer := abs(Diff); + Result : Safety := Calculate_Report_Lossy(Rep); 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; + if Result = Safe then + Sum := @ + 1; end if; end; end loop; - return Safe; - end Calculate_Report; + return Sum; + end Get_Safe_Reports_Lossy; function Get_Safe_Reports( R : Reports ) return Natural is Sum : Natural := 0; begin for Rep of R loop declare - Result : Safety := Calculate_Report(Rep); + Result : Safety := Calculate_Report(Calculate_Levels(Rep)); begin if Result = Safe then Sum := @ + 1; @@ -131,4 +197,5 @@ procedure Day_2 is begin Put_Line("Day 2 1:" & Get_Safe_Reports(Read_File(File_Name))'Image); + Put_Line("Day 2 2:" & Get_Safe_Reports_Lossy(Read_File(File_Name))'Image); end Day_2;