Camel
Peter
Peter Campbell Smith

Common winner

Weekly challenge 335 — 18 August 2025

Week 335: 18 Aug 2025

Task 1

Task — Common characters

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.

Examples


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')

Analysis

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.

Try it 

Try running the script with any input:



example: paragon, marathon, banana

Script


#!/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) . ')';
}

Output


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