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;