02 May 2025 | Challenge 319 |
Common Vowels
Task 1: Word Count
Submitted by: Mohammad Sajid Anwar
You are given a list of words containing alphabetic characters only.
Write a script to return the count of words either starting with a vowel or ending with a vowel.
Example 1
Input: @list = ("unicode", "xml", "raku", "perl")
Output: 2
The words are "unicode" and "raku".
Example 2
Input: @list = ("the", "weekly", "challenge")
Output: 2
Example 3
Input: @list = ("perl", "python", "postgres")
Output: 0
Solution
In the task’s description does neither specify the terms alphabetic character nor the meaning of vowel in this context. Making some assumptions to solve this task:
- Restricting alphabetic characters to Latin letters.
- A vowel being a “speech sound” is not strictly related to letters.
For this task, considering the letters
aeiou
and their derived forms as vowels.
Under these assumptions there are four categories of letters that can be regarded as a vowel:
- the base vowels
aeiou
- derived vowels, i.e base vowels with a modifier like diaeresis, accent etc.
- pure typographic ligatures like
fi
composed off
andi
- ligatures that have evolved into a letter of its own, e.g.
æ
orœ
Here is a small list of Danish, French and German words that should count as starting with or ending in a vowel:Öl
, Bö
, øre
, knæ
, œuf
, Profi
, Ålborg
.
In contrary, words starting with or ending in a spoken vowel that are not counted are e.g. hour
, Yttrium
or many
.
In the solution the base vowels are simply specified as a “Bracketed Character class”.
Derived vowels can be identified by their base vowel by canonical decomposition into Normalization Form D. Trailing non-letter characters can be ignored.
Typographic ligatures are broken into their component letters by transforming into “case folded” form.
Finally, the individual special forms of vowels need to be added to the mentioned “Bracketed Character class”.
Putting these together results in this implementation:
use v5.16;
use warnings;
use Unicode::Normalize;
sub word_count {
scalar grep /^(?&VOWEL)|(?&VOWEL)\P{L}*$(?(DEFINE)(?<VOWEL>[aeiouøæœ]))/,
map NFD(fc), @_;
}
See the full solution to task 1.
Task 2: Minimum Common
Submitted by: Mohammad Sajid Anwar
You are given two arrays of integers.
Write a script to return the minimum integer common to both arrays. If none found return -1
.
Example 1
Input: @array_1 = (1, 2, 3, 4)
@array_2 = (3, 4, 5, 6)
Output: 3
The common integer in both arrays: 3, 4
The minimum is 3.
Example 2
Input: @array_1 = (1, 2, 3)
@array_2 = (2, 4)
Output: 2
Example 3
Input: @array_1 = (1, 2, 3, 4)
@array_2 = (5, 6, 7, 8)
Output: -1
Solution
The task may easily generalized to an arbitrary number of lists.
use strict;
use warnings;
use PDL;
sub minimum_common {
my ($sect, @an) = map long($_), @_;
$sect = setops $sect, 'AND', $_ for @an;
$sect->isempty ? -1 : min $sect;
}
See the full solution to task 2.
If you have a question about this post or if you like to comment on it, feel free to open an issue in my github repository.