Perl Weekly Challenge 234: Common Characters
These are some answers to the Week 233, Task 1, of the Perl Weekly Challenge organized by Mohammad S. Anwar.
Spoiler Alert: This weekly challenge deadline is due in a couple of days from now (on September 17, 2023 at 23:59). This blog post offers some solutions to this challenge. Please don’t read on if you intend to complete the challenge on your own.
Task 1: Common Characters
You are given an array of words made up of alphabetic characters only.
Write a script to return all alphabetic characters that show up in all words including duplicates.
Example 1
Input: @words = ("java", "javascript", "julia")
Output: ("j", "a")
Example 2
Input: @words = ("bella", "label", "roller")
Output: ("e", "l", "l")
Example 3
Input: @words = ("cool", "lock", "cook")
Output: ("c", "o")
Common Characters in Raku
The common-chars
subroutine first transforms the input words into an array of arrays of letters, and then uses the ∩,infix%E2%88%A9) set intersection operator to find letters common to all sub-arrays.
sub common-chars (@in) {
my @letters = map { .comb }, @in;
return ~ ∩ @letters;
}
for <java javascript julia>, <bella label roller>,
<cool lock cook> -> @test {
printf "%-25s => ", "@test[]";
say common-chars @test;
}
This program displays the following output:
$ raku ./common-chars.raku
java javascript julia => [a j]
bella label roller => [l e]
cool lock cook => [c o]
Common Characters in Perl
This is essentially a port to Perl of the above Raku program, except that, since Perl doesn't have a set intersection operator, we use the %histo
hash to store the letter frequencies, and extract from the histogram letters whose frequency is equal to the input word count.
use strict;
use warnings;
use feature 'say';
sub common_chars {
my $count = scalar @_;
my @letters = map { [ split // ] } @_;
my %histo; # letter histogram
for my $w_ref (@letters) {
my %unique = map { $_ => 1 } @$w_ref;
$histo{$_}++ for keys %unique;
}
my @result = grep { $histo{$_} == $count } keys %histo;
return "@result";
}
for my $test ([<java javascript julia>],
[<bella label roller>], [<cool lock cook>]) {
printf "%-25s => ", "@$test";
say common_chars @$test;
}
This program displays the following output:
$ perl ./common-chars.pl
java javascript julia => a j
bella label roller => e l
cool lock cook => o c
Wrapping up
The next week Perl Weekly Challenge will start soon. If you want to participate in this challenge, please check https://perlweeklychallenge.org/ and make sure you answer the challenge before 23:59 BST (British summer time) on September 24, 2023. And, please, also spread the word about the Perl Weekly Challenge if you can.
Leave a comment