-- 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 vowels is
type Distinct_Vowel_Count is range 0 .. 6;
package DVCIO is new Ada.Text_IO.Integer_IO(Distinct_Vowel_Count);
use DVCIO;
-- Count number of distinct vowels in s
function number_distinct_vowels(s: String) return Distinct_Vowel_Count is
a, e, i, o, u, y : Boolean := false;
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' => u := true;
when others => null;
end case;
end loop;
return (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);
end number_distinct_vowels;
HEAD_LENGTH: Constant := 2;
TAIL_LENGTH: COnstant := 3;
MAX_NUM_STRINGS: Constant := 100;
type String_Count is range 0 .. MAX_NUM_STRINGS;
package String_Count_IO is new Ada.Text_IO.Integer_IO(String_Count);
use String_Count_IO;
subtype String_Index is String_Count range 1 .. String_Count'last;
type Heads_Array is array(String_Index) of String(1 .. HEAD_LENGTH);
type Tails_Array is array(String_Index) of String(1 .. TAIL_LENGTH);
procedure process_one_string(
s: String;
num_heads: in out String_Count;
heads: in out Heads_Array;
num_tails: in out String_Count;
tails: in out Tails_Array)
is
subtype Few_Vowels is Distinct_Vowel_Count range 0 .. 3;
subtype Many_Vowels is Distinct_Vowel_Count range 4 .. 6;
num_vowels: Distinct_Vowel_Count := number_distinct_vowels(s);
HEAD_END: Constant Natural := s'first + HEAD_LENGTH - 1;
TAIL_START: Constant Natural := 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 Few_Vowels =>
num_heads := num_heads + 1;
heads(num_heads) := s(s'first .. HEAD_END);
when Many_Vowels =>
num_tails := num_tails + 1;
tails(num_tails) := s(TAIL_START .. s'last);
end case;
end process_one_string;
procedure get_and_process_all_strings(
num_heads: out String_Count;
heads: out Heads_Array;
num_tails: out String_Count;
tails: out Tails_Array)
is
begin
num_heads := 0;
num_tails := 0;
while not end_of_file loop
declare
s: String := get_line;
begin
process_one_string(s, num_heads, heads, num_tails, tails);
end; -- declare
end loop;
end get_and_process_all_strings;
procedure put(num_heads: String_Count; heads: Heads_Array;
num_tails: String_Count; tails: Tails_Array)
is
begin
for i in 1 .. num_heads loop
put_line(heads(i));
end loop;
for i in 1 .. num_tails loop
put_line(tails(i));
end loop;
end put;
heads: Heads_Array; -- Array for heads
tails: Tails_Array; -- Array for tails
num_heads,
num_tails: String_Count := 0; -- Number of heads and tails
begin
get_and_process_all_strings(num_heads, heads, num_tails, tails);
put(num_heads, heads, num_tails, tails);
put(num_heads);
put(num_tails);
end vowels;