Peter
Peter Campbell Smith

Scrambled and split

Weekly challenge 279 — 22 July 2024

Week 279: 22 Jul 2024

Task 2

Task — Split string

You are given a string, $str. Write a script to split the given string into two containing exactly same number of vowels and return true if you can otherwise false.

Examples


Example 1
Input: $str = "perl"
Output: false

Example 2
Input: $str = "book"
Output: true
Two possible strings "bo" and "ok" 
containing exactly one vowel each.

Example 3
Input: $str = "good morning"
Output: true
Two possible strings "good " and "morning"
containing two vowels each or "good m" and 
"orning" containing two vowels each.

Analysis

A little thought reveals:

  • If the number of vowels in the string ($n) is even, then it is possible to split the string after the $n/2th vowel to create two equally vowelled substrings.
  • If the number of vowels is odd, then it can't be split into two equivowelled substrings.

We can count the vowels using this rather opaque construct:

$vowels = () = $string =~ m|[aeiou]|gi;

This works because $string =~ m|[aeiou]|gi in array context returns an array of matches. We aren't interested in what matched, but only in the number of matches, so if we capture the array of matches in the anonymous array () and then assign that to a scalar, lo and behold, that's the number of vowels in $string.

That relies on some rather obscure Perl and I would hesitate to use it in a production environment!

Of course, this challenge does require an interpretation of 'vowels'. I have assumed that the string is English, or at least composed of
[A-Za-z]. But in other languages, Ä and é are vowels and in Dutch I believe ij is regarded as a single letter and - maybe - a vowel. And then there's η in Greek and и in Ukrainian and no dount a zillion more in other languages.

There is also an unanswered doubt about a string containing no vowels. My solution will return 'true' for 'bcdfgh' as it can be split into two strings each containing 0 vowels. And of course even an empty string '' can be split into two empty strings - '' and '', each of which contains 0 vowels.

Try it 

Try running the script with any input:



example: sausage and beans

Script


#!/usr/bin/perl

# Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge

use v5.26;    # The Weekly Challenge - 2024-07-22
use utf8;     # Week 279 - task 2 - Split string
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';

split_string('good morning');
split_string('perl');
split_string('Write a script to split the given string into two');
split_string('Write a script to split the given string into three');
split_string('bcdfgh');
split_string('');

sub split_string {
    
    my ($string, $vowels);
    
    $string = shift;
    
    # count the vowels
    $vowels = () = $string =~ m|[aeiou]|gi;
    
    printf(qq[\nInput:  \$str = '%s'\n], $string);
    printf(qq[Output: %s\n], ($vowels & 1) ? 'false' : 'true');
}

Output


Input:  $str = 'good morning'
Output: true

Input:  $str = 'perl'
Output: false

Input:  $str = 'Write a script to split the given 
                string into two'
Output: false

Input:  $str = 'Write a script to split the given 
                string into three'
Output: true

Input:  $str = 'bcdfgh'
Output: true

Input:  $str = ''
Output: true

 

Any content of this website which has been created by Peter Campbell Smith is in the public domain