| 22 May 2026 | Challenge 374 |
All Vowels Are Equal
Task 1: Count Vowel
Submitted by: Mohammad Sajid Anwar
You are given a string.
Write a script to return all possible vowel substrings in the given string. A vowel substring is a substring that only consists of vowels and has all five vowels present in it.
Example 1
Input: $str = "aeiou"
Output: ("aeiou")
Example 2
Input: $str = "aaeeeiioouu"
Output: ("aaeeeiioou", "aaeeeiioouu", "aeeeiioou", "aeeeiioouu")
NOTE: Updated output [2025-05-18]
Example 3
Input: $str = "aeiouuaxaeiou"
Output: ("aeiou", "aeiou", "eiouua", "aeiouu", "aeiouua")
NOTE: Updated output [2025-05-18]
Example 4
Input: $str = "uaeiou"
Output: ("aeiou", "uaeio", "uaeiou")
Example 5
Input: $str = "aeioaeioa"
Output: ()
Solution
Perl
This is another occasion to let the regex engine do the work.
We construct a regex that matches vowel-only, all-vowels strings and that forces the regex engine to match all possible substrings thereof.
- For each vowel, create a look-ahead assertion that nongreedily matches any number of vowels followed by that vowel and capture the substring matched by the assertion.
- Capture:
- the longest of the previously captured strings
- all succeeding vowels
- Gather the previously captured string.
- Force the match to fail. This will cause the last succeeding vowel to be dropped, if it exists. Otherwise the start of the match will be advanced.
After the regex match has finally failed, all valid substrings in ascending order of the starting index and with descending length will have been detected.
use v5.26;
use warnings;
use List::UtilsBy 'max_by';
sub vowel_substr {
state $vows = [qw(a e i o u)];
state $vowcl = qr{[@$vows]}ixx;
state $vowsahead = [map qr{(?=($vowcl*?$_))}i, @$vows];
gather {
shift =~ m{
@$vowsahead
(
(??{max_by {length} @{^CAPTURE}})
$vowcl*
)
(?{take $+})
(*FAIL)
}x;
};
}
See the full solution to task 1.
J
J does not provide hooks in its regex engine to insert code in such a general way as Perl does. Therefore all maximum valid substrings are detected with a regex and all sub-sub-strings thereof are checked if they contain all the required characters.
Using named parts to build the final verb for a noun operand m:
- Compile a regular expression that:
- for each character in
mhas a positive look-ahead assertion for any number of characters frommfollowed by just that character - grabs as many characters contained in
mas possiblere =. rxcomp (, (('(?=[', m, ']*?') ,"1 0 m) , "1 ')'), '[', m, ']+'Use this regex to match all maximum substrings containing all and only the required characters.
With the required characters
mas'aei', the regex would be:(?=[aei]*?a)(?=[aei]*?e)(?=[aei]*?i)[aei]+ - for each character in
- Find all substrings of
yfrom the full length ofydown to the length ofm, transpose the resulting triangular matrix such that each row holds substrings starting at the same index and finally flatten the matrix. Transposing is not required but leads to an order that agrees with the Perl versionsubstrings =. , @ |: @ (m&(] <\~ (] - i. @ >: @ -~)&#)) - Apply the left operand to each leaf
for_every =. L:0 - Select an element of
yif all of the characters inmare contained in it.take_all_in =. *./@:(m&e.)@> # ] - Remove the outermost boxing
raze =. ;
The final verb will be assembled from the previously named parts and the operand m holding the required characters:
raze @: (take_all_in @ substrings for_every) @ (re&rxall)
Read it as:
- find all maximum valid substrings of
yby globally matching the regexre - for every matched substring:
- find all sub-sub-strings in the lengths from the substring’s length down to the length of
m - select all sub-sub-strings that contain all characters from
m
- find all sub-sub-strings in the lengths from the substring’s length down to the length of
- remove one level of boxing
all_and_only =: adverb define
re =. rxcomp (, (('(?=[', m, ']*?') ,"1 0 m) , "1 ')'), '[', m, ']+'
substrings =. , @ |: @ (m&(] <\~ (] - i. @ >: @ -~)&#))
take_all_in =. *./@:(m&e.)@> # ]
for_every =. L:0
raze =. ;
raze @: (take_all_in @ substrings for_every) f. @ (re&rxall) : [:
)
all_and_only_vowels =: 'aeiou' all_and_only
all_and_only_vowels 'aeiouuaxaeiou'
┌───────┬──────┬─────┬──────┬─────┐
│aeiouua│aeiouu│aeiou│eiouua│aeiou│
└───────┴──────┴─────┴──────┴─────┘
For this task the characters 'aeiou' have to be chosen as m.
Any other string of unique characters may be used.
See the full solution.
Task 2: Largest Same-digits Number
Submitted by: Mohammad Sajid Anwar
You are given a string containing 0-9 digits only.
Write a script to return the largest number with all digits the same in the given string.
Example 1
Input: $str = "6777133339"
Output: 3333
Example 2
Input: $str = "1200034"
Output: 4
Example 3
Input: $str = "44221155"
Output: 55
Example 4
Input: $str = "88888"
Output: 88888
Example 5
Input: $str = "11122233"
Output: 222
Solution
Ignoring the proposition that the input is a string of decimal digits. Expecting a non-negative integer instead. Furthermore, considering digits in any base B.
Update 2026-05-22:
Looking at other solutions I realized that I solved a different task.
I build the largest number from any same digits in the given number whereas the common interpretation is to find a substring of same digits.
Perl
Convert the number into digits in base B, collect digits by themselves, convert back from base B and find the maximum over these.
use strict;
use warnings;
use List::MoreUtils 'part';
use Math::Prime::Util qw(fromdigits todigits vecmax);
use experimental 'signatures';
sub same_digits ($base, $num) {
vecmax map fromdigits($_//[0], $base), part {$_} todigits $num, $base;
}
Use base 10 (the default) for this task:
$ ./ch-2.pl 1210121
1111
Here is an example in base 3:
\[1312_{10} = 1210121_3\]Same digits:
\[\begin{split} 0&\\ 1111&_3\\ 22&_3\\ \end{split}\]The maximum of these:
\[1111_3 = 40_{10}\]$ ./ch-2.pl -b 3 1312
40
See the full solution to task 2.
J
The J solution is analogous to the Perl version.
Again, building the final verb from named parts.
- Convert integer
yto digits in basem.to_digits =. m&#.^:_1 - convert digits in base
mfromyto an integer.from_digits =. m&#. - apply left operand to each group of equal elements from
y.with_same =. /.~ - find maximum from
ymax =. >./
Assemble a tacit verb for base m from the parts:
max @: (from_digits with_same) @ to_digits
same_digits =: adverb define
to_digits =. m&#.^:_1
from_digits =. m&#.
with_same =. /.~
max =. >./
max @: (from_digits with_same) @ to_digits f. : [:
)
Again, for this task the base is 10:
same_decimal_digits =: 10 same_digits
same_decimal_digits 1210121
1111
The ternary example works as well:
3 same_digits 1312
40
See the full solution.