with Ada.Text_IO; use Ada.Text_IO; with Ada.Strings; use Ada.Strings; with Ada.Strings.Fixed; use Ada.Strings.Fixed; procedure Day_5 is type Contained is new String( 1 .. 2 ); type Container is array (Natural range <>) of Contained; type Nat_Array is array (Natural range <>) of Natural; function Find( DUT : String; Member : Container ) return Boolean is Index : Nat_Array( Member'First .. Member'Last) := (Others => 1); begin for Char_Idx in DUT'Range loop for Mem_Idx in Member'Range loop if DUT(Char_Idx) = Member(Mem_Idx)(Index(Mem_Idx)) then if Index(Mem_Idx) = Member(Mem_Idx)'Last then return True; end if; Index(Mem_Idx) := @ + 1; else Index(Mem_Idx) := Member(Mem_Idx)'First; end if; end loop; end loop; return False; end Find; function Count_Vowels( DUT : String ) return Natural is Sum : Natural := 0; begin for I in DUT'Range loop case DUT(I) is when 'a' | 'e' | 'i' | 'o' | 'u' => Sum := @ + 1; when others => null; end case; end loop; return Sum; end Count_Vowels; function Multi_Letters( DUT : String ) return Boolean is Letter : Character := DUT(DUT'First); begin for I in DUT'First + 1 .. DUT'Last loop if DUT(I) = Letter then return True; else Letter := DUT(I); end if; end loop; return False; end Multi_Letters; function Has_Repeat_Sequence( DUT : String ) return Boolean is begin for I in DUT'First .. DUT'Last - 1 loop for J in I+2 .. DUT'Last -1 loop if DUT(I) = DUT(J) and DUT(I+1) = DUT(J+1) then return True; end if; end loop; end loop; return False; end Has_Repeat_Sequence; function Has_Repeat_Letters( DUT : String ) return Boolean is begin for I in DUT'First .. DUT'Last - 2 loop if DUT(I) = DUT(I+2) then return True; end if; end loop; return False; end Has_Repeat_Letters; function Nice(DUT : String ) return Boolean is A : Container := ("ab", "cd", "pq", "xy"); begin if Find(DUT, A) then return False; else return (Count_Vowels(DUT) >= 3) and Multi_Letters(DUT); end if; end Nice; function Nice_2(DUT : String ) return Boolean is begin return Has_Repeat_Sequence(DUT) and Has_Repeat_Letters(DUT); end Nice_2; function Day_5_1(File_Name : String) return Natural is File : File_Type; Sum : Natural := 0; begin Open(File, In_File, File_Name); while not End_Of_File(File) loop case Nice(Get_Line(File)) is when True => Sum := @ + 1; when False => null; end case; end loop; Close(File); return Sum; end Day_5_1; function Day_5_2(File_Name : String) return Natural is File : File_Type; Sum : Natural := 0; begin Open(File, In_File, File_Name); while not End_Of_File(File) loop case Nice_2(Get_Line(File)) is when True => Sum := @ + 1; when False => null; end case; end loop; Close(File); return Sum; end Day_5_2; begin Put_Line(Day_5_1("input_day_5.txt")'Image); Put_Line(Day_5_2("input_day_5.txt")'Image); end Day_5;