Peter’s blog ✴ Week 375 ✴ 25 May 2026

THE WEEKLY CHALLENGE
Single and beautiful

The Perl Camel

Task 1

Single common word

You are given two arrays of strings.

Write a script to return the number of strings that appear exactly once in each of the two given arrays. String comparison is case sensitive.

Examples


Example 1
Input: @array1 = ('apple', 'banana', 'cherry')
       @array2 = ('banana', 'cherry', 'date')
Output: 2

Example 2
Input: @array1 = ('a', 'ab', 'abc')
       @array2 = ('a', 'a', 'ab', 'abc')
Output: 2
'a' appears once in @array1 but appears twice in @array2,
   therefore, not counted.

Example 3
Input: @array1 = ('orange', 'lemon')
       @array2 = ('grape', 'melon')
Output: 0

Example 4
Input: @array1 = ('test', 'test', 'demo')
       @array2 = ('test', 'demo', 'demo')
Output: 0

Example 5
Input: @array1 = ('Hello', 'world')
       @array2 = ('hello', 'world')
Output: 1
String comparison is case sensitive.

Analysis

The logic of this challenge is that for every word in both arrays we need to know:

  • How often it appears in array 1
  • How often it appears in array 2

When dealing with the properties of strings it's often easiest to make each string the key of an array, so that's what I did.

So for any $word in array 1 I add 1 to $occurs{$word}, and for any $word in array 2 I add a million to $occurs{$word}.

I then grep the keys of %occurs to extract any where the value is 1000001, because those are the words occurring once in each array, as requested.

Of course this will fail if any word occurs more than a million times, but there are ways to get around that - for example, storing the counts in $occurs{$word}->[0] and $occurs{$word}->[1].

Try it 

Your input:



eg: all cows eat grass



eg: some pigs eat grass

Script


#!/usr/bin/perl

# Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge

use v5.26;    # The Weekly Challenge - 2026-05-25
use utf8;     # Week 375 - task 1 - Single common word
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';
use Encode;

single_common_word
    (['apple', 'banana', 'cherry'], ['banana', 'cherry', 'date']);
single_common_word
    (['apple', 'banana', 'cherry'], ['date', 'orange', 'plum']);
single_common_word
    (['apple', 'apple', 'cherry', 'cherry'], ['apple', 'cherry']);
single_common_word
    (['APPLE', 'BANANA', 'cherry'], ['banana', 'cherry', 'apple']);
single_common_word
    (['a' .. 'z'], ['b' .. 'y']);
    
sub single_common_word {
    
    my ($array, $word, $results, @results, %occurs);
    
    # count frequency of words in each array
    for $array (0 .. 1) {
        for $word (@{$_[$array]}) {
            
            # add 1 if in array1 or 1_000_000 if in array2
            $occurs{$word} += $array ? 1e6 : 1; 
        }
    }
    
    # words occuring once in each array have occurs == 1000001
    @results = grep {$occurs{$_} == 1e6 + 1} keys %occurs;
    
    # report
    say qq[\nInput:  \@array1 = ('] . join(q[', '], @{$_[0]}) . q[')];
    say qq[        \@array2 = ('] . join(q[', '], @{$_[1]}) . q[')];
    print qq[Output: ] . scalar @results;
    print q[ - ('] . join(q[', '], @results) . q[')] 
        if scalar @results;
    say '';
}

12 lines of code

Output from script


Input:  @array1 = ('apple', 'banana', 'cherry')
        @array2 = ('banana', 'cherry', 'date')
Output: 2 - ('banana', 'cherry')

Input:  @array1 = ('apple', 'banana', 'cherry')
        @array2 = ('date', 'orange', 'plum')
Output: 0

Input:  @array1 = ('apple', 'apple', 'cherry', 'cherry')
        @array2 = ('apple', 'cherry')
Output: 0

Input:  @array1 = ('APPLE', 'BANANA', 'cherry')
        @array2 = ('banana', 'cherry', 'apple')
Output: 1 - ('cherry')

Input:  @array1 = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
   'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
   'x', 'y', 'z')
        @array2 = ('b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
   'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
   'y')
Output: 24 - ('d', 'x', 'w', 'k', 'g', 'h', 'c', 'f', 's', 'n', 'e',
   'i', 'u', 'p', 'l', 'b', 'r', 'q', 'm', 'v', 'j', 'y', 'o', 't')

 

Any content of this website which has been created by Peter Campbell Smith is in the public domain