-- 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;