Perl Weekly Challenge: Week 280
Challenge 1:
Twice Appearance
You are given a string,
$str
, containing lowercase English letters only.Write a script to print the first letter that appears twice.
Example 1
Input: $str = "acbddbca"
Output: "d"
Example 2
Input: $str = "abccd"
Output: "c"
Example 3
Input: $str = "abcdabbb"
Output: "a"
I was hoping to be able to dispose of this challenge in one line with a regular expression but I couldn't figure it out so I fell back to this simple but effective method instead.
First a hash is created to store each character that has been seen.
my %seen;
Then the input string is split into characters and for each character...
for ($str.comb) -> $c {
...if it has already been seen, it means this is the second time we are seeing it. We print it out and exit the loop (and the script.)
if %seen{$c}:exists {
say $c;
last;
If not, we mark it as seen.
} else {
%seen{$c} = True;
}
}
This is the Perl version. It is a straightforward translation from Raku.
my %seen;
for (split //, shift) {
if (exists $seen{$_}) {
say $_;
last;
} else {
$seen{$_} = 1;
}
}
Challenge 2:
Count Asterisks
You are given a string,
$str
, where every two consecutive vertical bars are grouped into apair
.Write a script to return the number of asterisks,
*
, excluding any between each pair of vertical bars.
Example 1
Input: $str = "p|*e*rl|w**e|*ekly|"
Output: 2
The characters we are looking here are "p" and "w**e".
Example 2
Input: $str = "perl"
Output: 0
Example 3
Example 3
Input: $str = "th|ewe|e**|k|l***ych|alleng|e"
Output: 5
The characters we are looking here are "th", "e**", "l***ych" and "e".
This time we can achieve a one-liner. I will describe the Perl version first.
$_= shift; s/\|.+?\||[^*]//g; say y/*//;
We take the first command-line argument as input with shift()
and assign it to $_
. With a regular expression
we remove everything inside two |
characters or outside but not a *
. All that will be left are some asterisks
and the most concise way to count them is with the y///
(another name for tr///
) operator. Or at the cost of
one more character but perhaps the gain of some clarity, we could have used length()
.
In Raku as well we do the removal via regular expression. But this time, the number of asterisks remaining is
ciunted with .chars()
.
@*ARGS[0].subst(/\|.+?\| | <-[*]>/, q{}, :g).chars.say