Perl Weekly Challenge: Week 330
This week, the solutions to both challenges are one-liners in Raku and Perl.
Challenge 1:
Clear Digits
You are given a string containing only lower case English letters and digits.
Write a script to remove all digits by removing the first digit and the closest non-digit character to its left.
Example 1
Input: $str = "cab12"
Output: "c"
Round 1: remove "1" then "b" => "ca2"
Round 2: remove "2" then "a" => "c"
Example 2
Input: $str = "xy99"
Output: ""
Round 1: remove "9" then "y" => "x9"
Round 2: remove "9" then "x" => ""
Example 3
Input: $str = "pa1erl"
Output: "perl"
We get the input from the first command-line argument and assign it to $_
to make the code a little shorter.
In a while
loop, we use s///
to successively remove instances of a digit (\d
) preceded by a non-digit (\D
.)
When all such substitutions have been made, we print whatever is left with say()
. A piece of cake!
$_ = @*ARGS[0]; while s/\D\d// {}; .say
The Perl version is actually slightly shorter.
$_ = shift; while(s/\D\d//) {} say
Challenge 2:
Title Capital
You are given a string made up of one or more words separated by a single space.
Write a script to capitalise the given title. If the word length is 1 or 2 then convert the word to lowercase otherwise make the first character uppercase and remaining lowercase.
Example 1
Input: $str = "PERL IS gREAT"
Output: "Perl is Great"
Example 2
Input: $str = "THE weekly challenge"
Output: "The Weekly Challenge"
Example 3
Input: $str = "YoU ARE A stAR"
Output: "You Are a Star"
Once again, input is the first command-line qrgument. It is split into a list of words with .words()
.
Then the list of words is transformed with .map()
. For each word, we measure its' length with .chars()
.
If the length is less than 3, the word is converted into lower-case with .lc()
. If the word is longer, no problem.
The bountiful standard library of Raku has a method that does exactly what the spec wants to do. .tclc()
makes the
first letter of a word upper-case and all the other letters lower-case.
The words are .join()
ed back together into a string separated by spaces and the whole thing is printed out with
.say()
.
@*ARGS[0].words.map({ $_.chars < 3 ?? $_.lc !! $_.tclc }).join(q{ }).say
The Perl version needs to work around a few missing Raku features but is still pretty short. Instead of .words()
we use split()
with non-word characters (\W
) as the delimeters. Instead of .tclc()
, we convert every
word to lower-case and if the length()
is greater than 2, use a regular expression to make the first character
the word upper-case.
Then as in Raku, the words are join()
together with spaces and printed with (say()
.
say join q{ }, map { $_=lc; length > 2 && s/^(.)/\u$1/; $_} (split /\W+/, shift)