Peter’s blog ✴ Week 394 ✴ 5 October 2026

THE WEEKLY CHALLENGE
Alternation week

The Perl Camel

Task 2

Alternating vowels consonants

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.

Examples


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')

Analysis

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.

Try it 

Your input:



eg: 'forest', 'more', 'Oregon'

Script


#!/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-');
}

23 lines of code

Output from script


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