perl logo Perl logo (Thanks to Olaf Alders)

The weekly challenge 394 - Task 2: Alternating Vowels Consonants

 1 #!/usr/bin/env perl
 2 # https://theweeklychallenge.org/blog/perl-weekly-challenge-394/#TASK2
 3 #
 4 # Task 2: Alternating Vowels Consonants
 5 # =====================================
 6 #
 7 # You are given three strings containing English alphabetic characters.
 8 #
 9 # Find all the longest contiguous substrings common to all three strings that
10 # strictly alternate between vowels and consonants.
11 #
12 ## Example 1
13 ##
14 ## Input: @str = ("relocate", "delocate", "allocate")
15 ## Output: ("locate")
16 #
17 ## Example 2
18 ##
19 ## Input: @str = ("apple", "banana", "cherry")
20 ## Output: ()
21 #
22 ## Example 3
23 ##
24 ## Input: @str = ("navigate", "cavity", "gravity")
25 ## Output: ("avi")
26 #
27 ## Example 4
28 ##
29 ## Input: @str = ("pedalgia", "pedalboard", "pedantic")
30 ## Output: ("peda")
31 #
32 ## Example 5
33 ##
34 ## Input: @strings = ("schoolmaster", "schoolhouse", "schooling")
35 ## Output: ("ho", "ol")
36 #
37 ############################################################
38 ##
39 ## discussion
40 ##
41 ############################################################
42 #
43 # We pick the first word, create all possible substrings of it,
44 # and keep the ones that have alternating vowels and non-vowels,
45 # and group them by length. We then pick the list for the longest
46 # length.
47 
48 use v5.36;
49 use List::Util qw(any max);
50 use Data::Dumper;
51 
52 alternating_vowels_consonants("relocate", "delocate", "allocate");
53 alternating_vowels_consonants("apple", "banana", "cherry");
54 alternating_vowels_consonants("navigate", "cavity", "gravity");
55 alternating_vowels_consonants("pedalgia", "pedalboard", "pedantic");
56 alternating_vowels_consonants("schoolmaster", "schoolhouse", "schooling");
57 
58 sub alternating_vowels_consonants($str1, $str2, $str3) {
59     say "Input: \"$str1\", \"$str2\", \"$str3\"";
60     my $l = length($str1);
61     my $results = {};
62     foreach my $i (0..$l-1) {
63         foreach my $j ($i..$l-1) {
64             my $s = substr($str1, $i, 1 + $j - $i);
65             if(is_alternating($s) && $str2 =~ m/$s/ && $str3 =~ m/$s/) {
66                 next if length($s) <= 1;
67                 push @{$results->{length($s)}}, $s;
68             }
69         }
70     }
71     return say "Output: ()" unless keys %$results;
72     my $m = max(keys %$results);
73     say "Output: (" . join(", ", map { "\"$_\"" } @{$results->{$m}}) . ")";
74 }
75 
76 sub is_alternating($str) {
77     my @chars = split //, $str;
78     my $last = is_vowel($chars[0]);
79     foreach my $i (1..$#chars) {
80         my $this = is_vowel($chars[$i]);
81         if($this == $last) {
82             return 0;
83         }
84         $last = $this;
85     }
86     return 1;
87 }
88 
89 sub is_vowel($c) {
90     return any { lc($c) eq $_ } qw(a e i o u);
91 }
92