Peter’s blog ✴ Week 394 ✴ 5 October 2026
THE WEEKLY CHALLENGE
Alternation week
You are given three strings containing English alphabetic characters. Find all the longest contiguous substrings common to all three strings that strictly alternate between vowels and consonants.
Example 1 Input: @str = ('relocate', 'delocate', 'allocate') Output: ('locate') Example 2 Input: @str = ('apple', 'banana', 'cherry') Output: () Example 3 Input: @str = ('navigate', 'cavity', 'gravity') Output: ('avi') Example 4 Input: @str = ('pedalgia', 'pedalboard', 'pedantic') Output: ('peda') Example 5 Input: @strings = ('schoolmaster', 'schoolhouse', 'schooling') Output: ('ho', 'ol')
This is much easier than task 1!
First I sort the words by length, which limits the subsets to
being those of $words[0]. Then I generate those subsets in
decreasing order of size, so that I can stop once I find a sequence
that meets the vowel/consonant criterion and occurs in each of the
other words.
My solution handles any number of words, and also handles letters outside the ASCII set, though I haven't tried other alphabets.
The Perl approach employs a straightforward greedy scan-and-shift method along with a two-pass check (the original string and with the first two characters interchanged) to arrive at the minimum number of adjacent swaps. The approach is compact and well-documented and provides a thorough overview of the heuristics employed in the process.
This review may cover either or both challenges for this week.
#!/usr/bin/perl # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge use v5.26; # The Weekly Challenge - 2026-10-05 use utf8; # Week 394 - task 2 - Alternating vowels consonants use warnings; # Peter Campbell Smith binmode STDOUT, ':utf8'; use Encode; alternating_vowels_consonants('relocate', 'delocate', 'allocate'); alternating_vowels_consonants('apple', 'banana', 'cherry'); alternating_vowels_consonants('navigate', 'cavity', 'gravity'); alternating_vowels_consonants('pedalgia', 'pedalboard', 'pedantic'); alternating_vowels_consonants('schoolmaster', 'schoolhouse', 'schooling'); alternating_vowels_consonants('premium', 'uranium', 'tedium', 'triumph'); alternating_vowels_consonants('wäre', 'ärmel', 'klären', 'spärlich', 'verstärkt'); alternating_vowels_consonants('abekuvijo', 'ijoxxkuvxxabe', 'kuvabexijoxabe'); sub alternating_vowels_consonants { my (@words, $length, $size, $start, $substr, $z, $w, $longest, $best); @words = @_; say qq[\nInput: '] . join(q[', '], @words) . q[']; @words = sort {length($a) <=> length($b)} @words; $longest = 0; $best = ''; # get all the substrings of the shortest word $length = length($words[0]); SIZE: for ($size = $length; $size > 0; $size --) { last SIZE if $size < $longest; START: for $start (0 .. $length - $size) { $substr = substr($words[0], $start, $size); # must have alternating vowel/consonant $z = $substr; $z =~ s|[AEIOU]|0|gi; $z =~ s|[B-Y]|1|gi; next if ($z =~ m|00| or $z =~ m|11|); # does it occur in all the other words? for $w (1 .. $#words) { next START unless $words[$w] =~ m|$substr|; } # is it the longest (ie first) if ($size >= $longest) { $longest = $size; $best .= qq['$substr', ]; } } } say qq[Output: ] . ($best ? substr($best, 0, -2) : '-none-'); }
22 lines of code
Input: 'relocate', 'delocate', 'allocate' Output: 'locate' Input: 'apple', 'banana', 'cherry' Output: -none- Input: 'navigate', 'cavity', 'gravity' Output: 'avi' Input: 'pedalgia', 'pedalboard', 'pedantic' Output: 'peda' Input: 'schoolmaster', 'schoolhouse', 'schooling' Output: 'ho', 'ol' Input: 'premium', 'uranium', 'tedium', 'triumph' Output: 'um' Input: 'wäre', 'ärmel', 'klären', 'spärlich', 'verstärkt' Output: 'är' Input: 'abekuvijo', 'ijoxxkuvxxabe', 'kuvabexijoxabe' Output: 'abe', 'kuv', 'ijo'
Any content of this website which has been created by Peter Campbell Smith is in the public domain