09 February 2024 | Challenge 255 |
Frequent Oddities
Task 1: Odd Character
Submitted by: Mohammad Sajid Anwar
You are given two strings, $s
and $t
.
The string $t
is generated using the shuffled characters of the string $s
with an additional character.
Write a script to find the additional character in the string $t
.
Example 1
Input: $s = "Perl" $t = "Preel"
Output: "e"
Example 2
Input: $s = "Weekly" $t = "Weeakly"
Output: "a"
Example 3
Input: $s = "Box" $t = "Boxy"
Output: "y"
Solution
We may relax the preconditions in this task and solve something more general:
Find the characters in string $t
that are not contained in string $s
respecting their multiplicity.
Therefore we count up for every character in $t
and count down for every character in $s
.
Characters with a positive final count (in the multiplicity of their count) represent the solution of the generalized task.
We may utilize a property of the x
operator: it produces an empty list if the right operand is negative.
However, we need to suppress a warning in this case.
The solution:
sub char_diff ($s, $t) {
my %count;
$count{$_}++ for split //, $t;
$count{$_}-- for split //, $s;
no warnings 'numeric';
map +($_) x $count{$_}, keys %count;
}
See the full solution.
Task 2: Most Frequent Word
Submitted by: Mohammad Sajid Anwar
You are given a paragraph $p
and a banned word $w
.
Write a script to return the most frequent word that is not banned.
Example 1
Input: $p = "Joe hit a ball, the hit ball flew far after it was hit."
$w = "hit"
Output: "ball"
The banned word "hit" occurs 3 times.
The other word "ball" occurs 2 times.
Example 2
Input: $p = "Perl and Raku belong to the same family. Perl is the most popular language in the weekly challenge."
$w = "the"
Output: "Perl"
The banned word "the" occurs 3 times.
The other word "Perl" occurs 2 times.
Solution
This task may be generalized by allowing a list of banned words.
We count the individual words in the given paragraph, remove the banned words and pick the word having a maximum count from the remainder.
The solution:
use List::UtilsBy 'max_by';
sub mfw {
my $p = shift;
my %count;
$count{$_}++ for split /\W+/, $p;
delete @count{@_};
max_by {$count{$_}} keys %count;
}
See the full solution.
If you have a question about this post or if you like to comment on it, feel free to open an issue in my github repository.