This is my response to The Weekly Challenge #374.
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")
Example 5:
Input: $str = "aeioaeioa"
Output: ()
#! /usr/bin/env raku
unit sub MAIN ($str where $str.chars > 0,
:v(:$verbose));
my @matches;
for 0 .. $str.chars -2 -> $start
{
for $start +1 .. $str.chars -1 -> $stop
{
my $candidate = $str.substr($start, $stop - $start +1);
my %letters = $candidate.comb.map({ $_ => 1 });
my $match = %letters.keys.sort.join eq "aeiou";
say ":[$start - $stop]: $candidate \
{ $match ?? " is a match" !! "" }" if $verbose;
@matches.push: $candidate if $match;
}
}
say "(" ~ @matches.map({'"' ~ $_ ~ '"' }).join(" ,") ~ ")";
[3] A string with at least 1 character.
[6] The result will end up here.
[8] Iterate over the leftmost index (from).
[10] Ditto for the rightmost index (to), thus giving us all the
substrings of $str with a minimum lenght of 2. Note that I
could have insisted on a minium length of 4 here, as that is the
absolute minimum to contain the 4 vowels, to make the double loop
faster.
[12] Get the substring.
[13] Set up a hash with all the characters in the substring. Duplicates, if any, are overwritten.
[14] Extract the keys from the hash, sort and join them. Do we only have the 4 vowels?
[19] If so, add the substring to the result.
[23] Pretty print the result (with this non-pretty line of code).
Running it:
$ ./count-vowel aeiou
("aeiou")
$ ./count-vowel aaeeeiioouu
("aaeeeiioou" ,"aaeeeiioouu" ,"aeeeiioou" ,"aeeeiioouu")
$ ./count-vowel aeiouuaxaeiou
("aeiou" ,"aeiouu" ,"aeiouua" ,"eiouua" ,"aeiou")
$ ./count-vowel uaeiou
("uaeio" ,"uaeiou" ,"aeiou")
$ ./count-vowel aeioaeioa
()
Looking good.
With verbose mode:
$ ./count-vowel -v aeiou
:[0 - 1]: ae
:[0 - 2]: aei
:[0 - 3]: aeio
:[0 - 4]: aeiou is a match
:[1 - 2]: ei
:[1 - 3]: eio
:[1 - 4]: eiou
:[2 - 3]: io
:[2 - 4]: iou
:[3 - 4]: ou
("aeiou")
$ ./count-vowel -v aaeeeiioouu
:[0 - 1]: aa
:[0 - 2]: aae
:[0 - 3]: aaee
:[0 - 4]: aaeee
:[0 - 5]: aaeeei
:[0 - 6]: aaeeeii
:[0 - 7]: aaeeeiio
:[0 - 8]: aaeeeiioo
:[0 - 9]: aaeeeiioou is a match
:[0 - 10]: aaeeeiioouu is a match
:[1 - 2]: ae
:[1 - 3]: aee
:[1 - 4]: aeee
:[1 - 5]: aeeei
:[1 - 6]: aeeeii
:[1 - 7]: aeeeiio
:[1 - 8]: aeeeiioo
:[1 - 9]: aeeeiioou is a match
:[1 - 10]: aeeeiioouu is a match
:[2 - 3]: ee
:[2 - 4]: eee
:[2 - 5]: eeei
:[2 - 6]: eeeii
:[2 - 7]: eeeiio
:[2 - 8]: eeeiioo
:[2 - 9]: eeeiioou
:[2 - 10]: eeeiioouu
:[3 - 4]: ee
:[3 - 5]: eei
:[3 - 6]: eeii
:[3 - 7]: eeiio
:[3 - 8]: eeiioo
:[3 - 9]: eeiioou
:[3 - 10]: eeiioouu
:[4 - 5]: ei
:[4 - 6]: eii
:[4 - 7]: eiio
:[4 - 8]: eiioo
:[4 - 9]: eiioou
:[4 - 10]: eiioouu
:[5 - 6]: ii
:[5 - 7]: iio
:[5 - 8]: iioo
:[5 - 9]: iioou
:[5 - 10]: iioouu
:[6 - 7]: io
:[6 - 8]: ioo
:[6 - 9]: ioou
:[6 - 10]: ioouu
:[7 - 8]: oo
:[7 - 9]: oou
:[7 - 10]: oouu
:[8 - 9]: ou
:[8 - 10]: ouu
:[9 - 10]: uu
("aaeeeiioou" ,"aaeeeiioouu" ,"aeeeiioou" ,"aeeeiioouu")
$ ./count-vowel -v aeiouuaxaeiou
:[0 - 1]: ae
:[0 - 2]: aei
:[0 - 3]: aeio
:[0 - 4]: aeiou is a match
:[0 - 5]: aeiouu is a match
:[0 - 6]: aeiouua is a match
:[0 - 7]: aeiouuax
:[0 - 8]: aeiouuaxa
:[0 - 9]: aeiouuaxae
:[0 - 10]: aeiouuaxaei
:[0 - 11]: aeiouuaxaeio
:[0 - 12]: aeiouuaxaeiou
:[1 - 2]: ei
:[1 - 3]: eio
:[1 - 4]: eiou
:[1 - 5]: eiouu
:[1 - 6]: eiouua is a match
:[1 - 7]: eiouuax
:[1 - 8]: eiouuaxa
:[1 - 9]: eiouuaxae
:[1 - 10]: eiouuaxaei
:[1 - 11]: eiouuaxaeio
:[1 - 12]: eiouuaxaeiou
:[2 - 3]: io
:[2 - 4]: iou
:[2 - 5]: iouu
:[2 - 6]: iouua
:[2 - 7]: iouuax
:[2 - 8]: iouuaxa
:[2 - 9]: iouuaxae
:[2 - 10]: iouuaxaei
:[2 - 11]: iouuaxaeio
:[2 - 12]: iouuaxaeiou
:[3 - 4]: ou
:[3 - 5]: ouu
:[3 - 6]: ouua
:[3 - 7]: ouuax
:[3 - 8]: ouuaxa
:[3 - 9]: ouuaxae
:[3 - 10]: ouuaxaei
:[3 - 11]: ouuaxaeio
:[3 - 12]: ouuaxaeiou
:[4 - 5]: uu
:[4 - 6]: uua
:[4 - 7]: uuax
:[4 - 8]: uuaxa
:[4 - 9]: uuaxae
:[4 - 10]: uuaxaei
:[4 - 11]: uuaxaeio
:[4 - 12]: uuaxaeiou
:[5 - 6]: ua
:[5 - 7]: uax
:[5 - 8]: uaxa
:[5 - 9]: uaxae
:[5 - 10]: uaxaei
:[5 - 11]: uaxaeio
:[5 - 12]: uaxaeiou
:[6 - 7]: ax
:[6 - 8]: axa
:[6 - 9]: axae
:[6 - 10]: axaei
:[6 - 11]: axaeio
:[6 - 12]: axaeiou
:[7 - 8]: xa
:[7 - 9]: xae
:[7 - 10]: xaei
:[7 - 11]: xaeio
:[7 - 12]: xaeiou
:[8 - 9]: ae
:[8 - 10]: aei
:[8 - 11]: aeio
:[8 - 12]: aeiou is a match
:[9 - 10]: ei
:[9 - 11]: eio
:[9 - 12]: eiou
:[10 - 11]: io
:[10 - 12]: iou
:[11 - 12]: ou
("aeiou" ,"aeiouu" ,"aeiouua" ,"eiouua" ,"aeiou")
$ ./count-vowel -v uaeiou
:[0 - 1]: ua
:[0 - 2]: uae
:[0 - 3]: uaei
:[0 - 4]: uaeio is a match
:[0 - 5]: uaeiou is a match
:[1 - 2]: ae
:[1 - 3]: aei
:[1 - 4]: aeio
:[1 - 5]: aeiou is a match
:[2 - 3]: ei
:[2 - 4]: eio
:[2 - 5]: eiou
:[3 - 4]: io
:[3 - 5]: iou
:[4 - 5]: ou
("uaeio" ,"uaeiou" ,"aeiou")
$ ./count-vowel -v aeioaeioa
:[0 - 1]: ae
:[0 - 2]: aei
:[0 - 3]: aeio
:[0 - 4]: aeioa
:[0 - 5]: aeioae
:[0 - 6]: aeioaei
:[0 - 7]: aeioaeio
:[0 - 8]: aeioaeioa
:[1 - 2]: ei
:[1 - 3]: eio
:[1 - 4]: eioa
:[1 - 5]: eioae
:[1 - 6]: eioaei
:[1 - 7]: eioaeio
:[1 - 8]: eioaeioa
:[2 - 3]: io
:[2 - 4]: ioa
:[2 - 5]: ioae
:[2 - 6]: ioaei
:[2 - 7]: ioaeio
:[2 - 8]: ioaeioa
:[3 - 4]: oa
:[3 - 5]: oae
:[3 - 6]: oaei
:[3 - 7]: oaeio
:[3 - 8]: oaeioa
:[4 - 5]: ae
:[4 - 6]: aei
:[4 - 7]: aeio
:[4 - 8]: aeioa
:[5 - 6]: ei
:[5 - 7]: eio
:[5 - 8]: eioa
:[6 - 7]: io
:[6 - 8]: ioa
:[7 - 8]: oa
()
Input: $str = "6777133339"
Output: 3333
Example 2:
Input: $str = "1200034"
Output: 4
Example 3:
Input: $str = "44221155"
Output: 55
None found.
Example 4:
Input: $str = "88888"
Output: 88888
Example 5:
Input: $str = "11122233"
Output: 222
This task is eminently suitable for
gather/take. The code to spit out chunks of identical
characters (the grouped procedure in rows 6 - 28) is reused
unmodified from my response to challenge #313.1 Broken Keys;
Reverse Broken with Raku.
#! /usr/bin/env raku
unit sub MAIN ($str where $str ~~ /^<[0..9]>+$/,
:v(:$verbose));
sub grouped ($str)
{
my @parts = gather
{
my $curr;
my $count = 0;
for $str.comb -> $char
{
if $count && $curr ne $char
{
take $curr x $count;
$count = 0;
}
$curr = $char;
$count++;
}
take $curr x $count;
}
say ": Grouped '$str' as { @parts.raku }" if $verbose;
return @parts;
}
my @groups = grouped($str);
say ": Groups: { @groups.join(", ") }" if $verbose;
say @groups>>.Int.max;
[3] Ensure a string of digits only, with at least one of them.
[6-28] See Reverse Broken with Raku.
[30] Get the chunks.
[34] Coerce the chunks (from strings) to integers, get the highest
(with max) and print it.
See docs.raku.org/routine/max for more information about max.
Running it:
$ ./lsdn 6777133339
3333
$ ./lsdn 1200034
4
$ ./lsdn 44221155
55
$ ./lsdn 88888
88888
$ ./lsdn 11122233
222
Looking good.
With verbose mode:
$ ./lsdn -v 6777133339
: Grouped '6777133339' as ["6", "777", "1", "3333", "9"]
: Groups: 6, 777, 1, 3333, 9
3333
$ ./lsdn -v 1200034
: Grouped '1200034' as ["1", "2", "000", "3", "4"]
: Groups: 1, 2, 000, 3, 4
4
$ ./lsdn -v 44221155
: Grouped '44221155' as ["44", "22", "11", "55"]
: Groups: 44, 22, 11, 55
55
$ ./lsdn -v 88888
: Grouped '88888' as ["88888"]
: Groups: 88888
88888
$ ./lsdn -v 11122233
: Grouped '11122233' as ["111", "222", "33"]
: Groups: 111, 222, 33
222
And that's it.