This is my response to The Weekly Challenge #369.
Input: $caption = "Cooking with 5 ingredients!"
Output: "#cookingWithIngredients"
Example 2:
Input: $caption = "the-last-of-the-mohicans"
Output: "#thelastofthemohicans"
Example 3:
Input: $caption = " extra spaces here"
Output: "#extraSpacesHere"
Example 4:
Input: $caption = "iPhone 15 Pro Max Review"
Output: "#iphoneProMaxReview"
Example 5:
Input: $caption = "Ultimate 24-Hour Challenge: Living in a Smart Home \
controlled entirely by Artificial Intelligence and Voice Commands \
in the year 2026!"
Output: "#ultimateHourChallengeLivingInASmartHomeControlledEntirely\
ByArtificialIntelligenceAndVoiceCommandsIn"
I have chosen to do step 2 before step 1, as the order does not really matter.
File: valid-tag
#! /usr/bin/env raku
unit sub MAIN ($caption where $caption.chars > 0, # [1]
:v(:$verbose));
my $stripped = $caption.comb.grep({ /<[a..z A..Z \s]>/ }).join; # [2]
my @words = $stripped.words;
my $final = "#" ~ @words.shift.lc ~ @words.map({ .tclc }).join; # [3]
say ": English & Spaces: «$stripped»\n: Final: «$final»" if $verbose;
say $final.chars > 100 ?? $final.substr(0, 100) !! $final; # [4]
[1] Keep the English letters (a-z and A-Z) and spaces only.
[2] Use words to get a list of words.
See docs.raku.org/routine/words for more information about words.
[3]
Set up the string, starting with a '#' and the first word in
lowercase (with lc). Add the rest of the words, with an uppercase
initial letter and the rest in lowercase (with tclc).
See docs.raku.org/routine/lc for more information about lc.
See docs.raku.org/routine/tclc for more information about tclc.
[4] Print the result, capped to 100 characters if longer than that.
Running it:
$ ./valid-tag "Cooking with 5 ingredients!"
#cookingWithIngredients
$ ./valid-tag "the-last-of-the-mohicans"
#thelastofthemohicans
$ ./valid-tag " extra spaces here"
#extraSpacesHere
$ ./valid-tag "iPhone 15 Pro Max Review"
#iphoneProMaxReview
$ ./valid-tag "Ultimate 24-Hour Challenge: Living in a Smart Home \
controlled entirely by Artificial Intelligence and Voice Commands \
in the year 2026!"
#ultimateHourChallengeLivingInASmartHomeControlledEntirelyByArtificial\
IntelligenceAndVoiceCommandsIn
Looking good.
With verbose mode:
$ ./valid-tag -v "Cooking with 5 ingredients!"
: English & Spaces: «Cooking with ingredients»
: Final: «#cookingWithIngredients»
#cookingWithIngredients
$ ./valid-tag -v "the-last-of-the-mohicans"
: English & Spaces: «thelastofthemohicans»
: Final: «#thelastofthemohicans»
#thelastofthemohicans
$ ./valid-tag -v " extra spaces here"
: English & Spaces: « extra spaces here»
: Final: «#extraSpacesHere»
#extraSpacesHere
$ ./valid-tag -v "iPhone 15 Pro Max Review"
: English & Spaces: «iPhone Pro Max Review»
: Final: «#iphoneProMaxReview»
#iphoneProMaxReview
$ ./valid-tag -v "Ultimate 24-Hour Challenge: Living in a Smart Home \
controlled entirely by Artificial Intelligence and Voice Commands \
in the year 2026!"
: English & Spaces: «Ultimate Hour Challenge Living in a Smart Home \
controlled entirely by Artificial Intelligence and Voice Commands \
in the year »
: Final: «#ultimateHourChallengeLivingInASmartHomeControlledEntirely\
ByArtificial\IntelligenceAndVoiceCommandsInTheYear»
#ultimateHourChallengeLivingInASmartHomeControlledEntirelyByArtificial\
IntelligenceAndVoiceCommandsIn
Input: $str = "RakuPerl", $size = 4, $filler = "*"
Output: ("Raku", "Perl")
Example 2:
Input: $str = "Python", $size = 5, $filler = "0"
Output: ("Pytho", "n0000")
Example 3:
Input: $str = "12345", $size = 3, $filler = "x"
Output: ("123", "45x")
Example 4:
Input: $str = "HelloWorld", $size = 3, $filler = "_"
Output: ("Hel", "loW", "orl", "d__")
Example 5:
Input: $str = "AI", $size = 5, $filler = "!"
Output: "AI!!!"
This task is suitable for gather/take,
where we use gather to collect the parts (the groups).
#! /usr/bin/env raku
unit sub MAIN ($str is copy where $str.chars > 0, # [1]
Int $size where $size > 0, # [2]
$filler where $filler.chars == 1); # [3]
my @output = gather # [4]
{
while $str.chars >= $size # [5]
{
take $str.substr(0, $size); # [6]
$str.substr-rw(0, $size) = ""; # [7]
}
take $str ~ $filler x ($size - $str.chars) if $str.chars; # [8]
}
say @output.join(", "); # [9]
[1] A string with at least one character. Note the
is copy trait, allowing us to change the string (in [7]).
See docs.raku.org/type/Parameter#method_copy for more information about is copy.
[2] The size, as a positive integer.
[3] The filler character, a single character.
[4] Collect the groups with gather.
See my Raku Gather, I Take article or docs.raku.org/language/control#gather/take for more information about gather/take.
[5] As long as we have at least one more complete group to go,
[6] return (with take) a complete group,
[7] and remove that group with substr-rw.
See docs.raku.org/routine/substr-rw for more information about substr-rw.
[8] Return a final group, padded out with the filler character, if we have any leftover characters after the loop.
[9] Print the result.
Running it:
$ ./group-division RakuPerl 4 "*"
Raku, Perl
$ ./group-division Python 5 "0"
Pytho, n0000
$ ./group-division 12345 3 x
123, 45x
$ ./group-division HelloWorld 3 "_"
Hel, loW, orl, d__
$ ./group-division AI 5 "!"
AI!!!
Looking good.
Verbose mode did not make much sense here.
And that's it.