-- Reads in strings, counts the number of distinct vowels -- For strings with 0..3 vowels, stores the head (2 chars) -- For strings with 4..6 vowels, stores the tail (3 chars) -- Prints all heads, followed by all tails -- Example input: -- abcde -- aeiou -- bbb -- Example output: -- ab -- bb -- iou with ada.text_io; use ada.text_io; procedure vowel_codes is subtype Distinct_Vowel_Count is Natural range 0 .. 6; function number_distinct_vowels(s: String) return Distinct_Vowel_Count is a, e, i, o, u, y : Boolean := false; ans : Distinct_Vowel_Count := 0; begin for c of s loop case c is when 'a' => a := true; when 'e' => e := true; when 'i' => i := true; when 'o' => o := true; when 'u' => u := true; when 'y' => y := true; when others => null; end case; end loop; -- How to potentially make the loop more efficient ans := ans + (if a then 1 else 0) + (if e then 1 else 0) + (if i then 1 else 0) + (if o then 1 else 0) + (if u then 1 else 0) + (if y then 1 else 0); return ans; -- or simply return the expression above end number_distinct_vowels; Max_Num_Strings: Constant Natural := 100; subtype String_Count is Natural range 0 .. Max_Num_Strings; subtype String_Index is String_Count range 1 .. String_Count'Last; head_length: Constant Natural := 2; tail_length: Constant Natural := 3; -- 0 would be unusual, but allowed -- subtype Long_Enough_String is String -- with Dynamic_Predicate => -- Long_Enough_String'Length >= Natural'Max(head_length, tail_length); -- Will raise an exception immediately if a short string is assigned -- to a variable of this type type Head_Array_Type is array(String_Index) of String(1 .. head_length); type Tail_Array_Type is array(String_Index) of String(1 .. tail_length); head_count: String_Count := 0; tail_count: String_Count := 0; heads: Head_Array_Type; tails: Tail_Array_Type; begin while not end_of_file loop read_block: declare s: String := get_line; num_vowels: Distinct_Vowel_Count := number_distinct_vowels(s); tail_start: Integer := s'last - tail_length + s'first; begin if s'length < Natural'Max(head_length, tail_length) then raise Constraint_Error with " String is too short"; end if; case num_vowels is when 0 .. 3 => head_count := head_count + 1; heads(head_count) := s(1 .. head_length); when 4 .. 6 => tail_count := tail_count + 1; tails(tail_count) := s(tail_start .. s'last); end case; end read_block; end loop; for i in 1 .. head_count loop put(heads(i)); end loop; new_line; for i in 1 .. tail_count loop put(tails(i)); end loop; new_line; end vowel_codes;