Peter’s blog ✴ Week 335 ✴ 18 August 2025
THE WEEKLY CHALLENGE
Common winner
You are given an array of words. Write a script to return all the characters that are in every word in the given array, including duplicates.
Example 1 Input: @words = ('bella', 'label', 'roller') Output: ('e', 'l', 'l') Example 2 Input: @words = ('cool', 'lock', 'cook') Output: ('c', 'o') Example 3 Input: @words = ('hello', 'world', 'pole') Output: ('l', 'o') Example 4 Input: @words = ('abc', 'def', 'ghi') Output: () Example 5 Input: @words = ('aab', 'aac', 'aaa') Output: ('a', 'a')
As always, there are various ways to do this, and here is mine.
I create a data structure:
$count->{$c}->[$w] = $n
where
$c is a character which occurs in one of the input words,
$w is the (zero-based) index of a word in the input,
and $n is the number of instances of $c in $word[$n].
So using Mohammad's first example $count->{'l'}->{1} == 2 because the letter l
occures twice in word 1, ie in 'label'.
Then for every $c - ie for every letter that occurs in at least one word -
I loop over $w to find the least $n. So for Mohammad's second example -
'cool', 'lock', 'cook' - I will find that o occurs least frequently - ie once -
in 'lock'. I therefore add 'o', once to my output string. Had it
occurred (at least) twice in every word I would have added it twice, and so on.
And that's it, save for a minor wrinkle, which is that if $c doesn't
occur in word $w, for example, there is no r in bella, then
$count->{$c}->[$w] is undefined. That's OK because in a numeric
context Perl regards undefined to mean zero, but it does output a warning.
So to suppress those I have included no warnings 'uninitialized' in
my code, which is potentially unwise, but I judge it to be
acceptable here.
Solutions demonstrate strong problem-solving skills with particular excellence in the binary representation approach for Task 2, which is both computationally optimal and elegantly implemented.
This review may cover either or both challenges for this week.
#!/usr/bin/perl # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge use v5.26; # The Weekly Challenge - 2025-08-18 use utf8; # Week 335 - task 1 - Common characters use warnings; # Peter Campbell Smith binmode STDOUT, ':utf8'; common_characters('bella', 'label', 'roller'); common_characters('cool', 'lock', 'cook'); common_characters('hello', 'world', 'pole'); common_characters('abc', 'def', 'ghi'); common_characters('aab', 'aac', 'aaa'); sub common_characters { my (@words, @chars, $count, $c, $min, $output, $w, $k); no warnings 'uninitialized'; @words = @_; # create count of character $c in word $w for $w (0 .. $#words) { @chars = split('', $words[$w]); $count->{$chars[$_]}->[$w] ++ for 0 .. $#chars; } # loop $c over characters for $c (sort keys %$count) { # find minimum number of occurrences of $c in all words $min = 1e6; for $w (0 .. $#words) { $k = $count->{$c}->[$w]; $min = $k if $k < $min; } # output that number of occurrences of $c $output .= qq['$c', ] for 1 .. $min; } # report say qq[\nInput: ('] . join(q[', '], @words) . q[')]; say qq[Output: (] . substr($output, 0, -2) . ')'; }
15 lines of code
Input: ('bella', 'label', 'roller') Output: ('e', 'l', 'l') Input: ('cool', 'lock', 'cook') Output: ('c', 'o') Input: ('hello', 'world', 'pole') Output: ('l', 'o') Input: ('abc', 'def', 'ghi') Output: () Input: ('aab', 'aac', 'aaa') Output: ('a', 'a')
Any content of this website which has been created by Peter Campbell Smith is in the public domain