String time
Weekly challenge 348 — 17 November 2025
Week 348: 17 Nov 2025
You are given a string of even length. Write a script to find out whether the given string can be split into two halves of equal lengths, each with the same non-zero number of vowels.
Example 1 Input: $str = 'textbook' Output: false 1st half: 'text' (1 vowel) 2nd half: 'book' (2 vowels) Example 2 Input: $str = 'book' Output: true 1st half: 'bo' (1 vowel) 2nd half: 'ok' (1 vowel) Example 3 Input: $str = 'AbCdEfGh' Output: true 1st half: 'AbCd' (1 vowel) 2nd half: 'EfGh' (1 vowel) Example 4 Input: $str = 'rhythmmyth' Output: false 1st half: 'rhyth' (0 vowel) 2nd half: 'mmyth' (0 vowel) Example 5 Input: $str = 'UmpireeAudio' Output: false 1st half: 'Umpire' (3 vowels) 2nd half: 'eAudio' (5 vowels)
This challenge can be solved many different ways, and I tried several before choosing the one to submit.
I began writing software when computers were many orders of magnitude slower than they are today, and I retain a desire to write software which is efficient, as well as being correct, maintainable and robust.
So my solution is efficient in that it makes a single
pass along the string. Although substr($string, $c, 1)
looks messy, experience shows that Perl handles that
very efficiently.
On the other hand, $x =~ m|[aeiou]|i is not the fastest
way of identifying a vowel, though it is
easy to understand. I think, though haven't tested it, that
$x eq 'a' or $x eq 'e' or $x eq 'i' or $x eq 'o' or $x eq 'u'
would be faster - having first lower-cased the string.
Another option is to start by chopping the string
in two and counting the vowels in each half separately.
That makes for more code, but avoids the messing around
with $h in my code.
So lots of options and I will read the other submissions with interest.
#!/usr/bin/perl # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge use v5.26; # The Weekly Challenge - 2025-11-17 use utf8; # Week 348 - task 1 - String alike use warnings; # Peter Campbell Smith binmode STDOUT, ':utf8'; use Encode; string_alike('rhythm'); string_alike('artifice'); string_alike('MOONSOUP'); string_alike('fairzzzz'); string_alike('uu'); string_alike('aeioupaeioupaeiuopaeioupaeioupaeiuop'); string_alike('123+!£ a $#FF & U (]'); sub string_alike { my ($string, $output, $size, $half, @count, $c, $h); # initialise $string = $_[0]; $output = 'false'; @count = (0, 0); # check for even length $size = length($string); if (($size & 1) == 0) { $half = $size / 2; $h = 0; # count vowels for $c (0 .. $size - 1) { $h = 1 if $c == $half; $count[$h] ++ if substr($string, $c, 1) =~ m|[aeiou]|i; } # check for equality if ($count[0] != 0 and $count[0] eq $count[1]) { $output = qq[true - $count[0] vowel] . ($count[0] == 1 ? '' : 's'); } } say qq[\nInput: '$string']; say qq[Output: $output]; }
Input: 'rhythm' Output: false Input: 'artifice' Output: true - 2 vowels Input: 'MOONSOUP' Output: true - 2 vowels Input: 'fairzzzz' Output: false Input: 'uu' Output: true - 1 vowel Input: 'aeioupaeioupaeiuopaeioupaeioupaeiuop' Output: true - 15 vowels
Any content of this website which has been created by Peter Campbell Smith is in the public domain