Peter’s blog ✴ Week 383 ✴ 20 July 2026

THE WEEKLY CHALLENGE
Similar list, friendly colour

The Perl Camel

Task 1

Similar list

You are given three list of strings. Write a script to find out if the first two lists are similar with the help the third list. The third list contains the similar words map.

Examples


Example 1
Input: $list1 = ('great', 'acting')
       $list2 = ('fine', 'drama')
       $list3 = (['great', 'fine'], ['acting', 'drama'])
Output: true

Example 2
Input: $list1 = ('apple', 'pie')
       $list2 = ('banana', 'pie')
       $list3 = (['apple', 'peach'], ['peach', 'banana'])
Output: false

Example 3
Input: $list1 = ('perl4', 'python')
       $list2 = ('raku', 'python')
       $list3 = (['perl4', 'perl5', 'raku'])
Output: true

Example 4
Input: $list1 = ('enjoy', 'challenge')
       $list2 = ('love', 'weekly', 'challenge')
       $list3 = (['enjoy', 'love'])
Output: false

Example 5
Input: $list1 = ('fast', 'car')
       $list2 = ('quick', 'vehicle')
       $list3 = (['quick', 'fast'], ['vehicle', 'car'])
Output: true

Analysis

Just back from a holiday in the cool north to find this slightly tricky challenge.

And here's my logic.

I loop through all the items in list1 and list2. If an item exists in any of the sublists in list3, I replace it with the first item in the sublist. So for example 1 above, in list1 'great' is replaced by 'great' (ie left unchanged) and 'acting' by 'acting', but in list2 'fine' is changed to 'great' because 'fine' appears in the first sublist of list2 and similarly 'drama' is changed to 'acting'. That results in list1 and list2 being identical and the result is true.

There are a couple of matters left unclear by the task description and the examples. Firstly, if A is similar to B and B is similar to C, does that imply that A is similar to C? I have assumed that it doesn't: consider 'carrot, tomato, banana', where carrots and tomatoes are both similarly red, and tomatoes and bananas are both similarly fruit, but that doesn't imply that 'carrot' and 'banana' are similar.

The other mystery is whether the order of list1 and list2 matters, so if list1 is 'cat, dog' and list2 is 'dog, cat' are these lists similar? I have assumed that they are similar, but if you disagree just remove the two sorts in the last line of my solution.

So how do I go about it? First I convert the elements of list 3 into '~' separated strings in @sims, so for example 1 $sims[0] contains '~great~acting~' and $sims[1] contains '~fine~drama~'.

Secondly I go through lists 1 and 2 word by word, and if I find that word in any of my @sims strings, I change it to the first word in that string. So any occurrence of 'fine' or 'drama' is changed to 'fine'.

Lastly, I sort the revised lists 1 and 2 and join them with '~' as the separator, and if those joined strings are the same then the output is 'true', or if not, it's false.

I haven't had time to test this as thoroughly as I would like, but - subject to ny two assumptions above - I have not been able to find a counter-example. Please let me know if you disagree!

Try it 

Try it coming shortly!

Script


#!/usr/bin/perl

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

use v5.26;    # The Weekly Challenge - 2026-07-20
use utf8;     # Week 383 - task 1 - Similar list
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';
use Encode;

similar_list(['great', 'acting'], ['fine', 'drama'], 
    [['great', 'fine'], ['acting', 'drama']]);
similar_list(['apple', 'pie'], ['banana', 'pie'], [['apple', 'peach'], 
    ['peach', 'banana']]);
similar_list(['perl4', 'python'], ['raku', 'python'], 
    [['perl4', 'perl5', 'raku']]);
similar_list(['enjoy', 'challenge'], ['love', 'weekly', 'challenge'], 
    [['enjoy', 'love']]);
similar_list(['fast', 'car'], ['quick', 'vehicle'], 
    [['quick', 'fast'], ['vehicle', 'car']]);
similar_list([qw[the quick brown fox jumps over the lazy dog]],
        [qw[hound a tan vaults the speedy sleepy wolf above]],
        [['the', 'a'], ['speedy', 'quick'], ['brown', 'tan'], 
        ['fox', 'wolf'], ['vaults', 'jumps'], ['above', 'over'], 
        ['the', 'my'], ['sleepy', 'lazy'], ['hound', 'dog']]);

sub similar_list {
    
    my (@list1, @list2, @lists3, $k1, $k2, $i3, $j3, %similar, $word, 
        @sims, $list, $s, $first);
    
    # initialise
    @list1 = @{$_[0]};
    @list2 = @{$_[1]};
    @lists3 = @{$_[2]};
    say qq[\nInput:  \@list1 = ('] . join(q[', '], @list1) . q[')];
    say   qq[        \@list2 = ('] . join(q[', '], @list2) . q[')];
    say   qq[        \@lists3[$_] = ('] . 
        join(q[', '], @{$lists3[$_]}) . q[')] for 0 .. $#lists3;
    
    # make lists of similar words, eg ~great~fine~
    for $j3 (0 .. $#lists3) {
        $sims[$j3] = '~' . join('~', @{$lists3[$j3]}) . '~';
    }
    
    # subsitute first in those lists for any in list1 and list2
    for $list (\@list1, \@list2) {
        for $k1 (0 .. @$list - 1) {
            for $s (@sims) {
                if ($s =~ m|~$list->[$k1]~|) {
                    ($first) = $s =~ m|(~\w+~)|;
                    $list->[$k1] = $first;
                }
            }
        }
    }
    
    # report
    say 'Output: ' . 
        (join(',', sort @list1) eq join(',', sort @list2) ? 
        'true' : 'false');
}

21 lines of code
Completed after the closing date and not submitted to GitHub

Output from script


Input:  @list1 = ('great', 'acting')
        @list2 = ('fine', 'drama')
        @lists3[0] = ('great', 'fine')
        @lists3[1] = ('acting', 'drama')
Output: true

Input:  @list1 = ('apple', 'pie')
        @list2 = ('banana', 'pie')
        @lists3[0] = ('apple', 'peach')
        @lists3[1] = ('peach', 'banana')
Output: false

Input:  @list1 = ('perl4', 'python')
        @list2 = ('raku', 'python')
        @lists3[0] = ('perl4', 'perl5', 'raku')
Output: true

Input:  @list1 = ('enjoy', 'challenge')
        @list2 = ('love', 'weekly', 'challenge')
        @lists3[0] = ('enjoy', 'love')
Output: false

Input:  @list1 = ('fast', 'car')
        @list2 = ('quick', 'vehicle')
        @lists3[0] = ('quick', 'fast')
        @lists3[1] = ('vehicle', 'car')
Output: true

Input:  @list1 = ('the', 'quick', 'brown', 'fox', 'jumps', 'over',
   'the', 'lazy', 'dog')
        @list2 = ('hound', 'a', 'tan', 'vaults', 'the', 'speedy',
   'sleepy', 'wolf', 'above')
        @lists3[0] = ('the', 'a')
        @lists3[1] = ('speedy', 'quick')
        @lists3[2] = ('brown', 'tan')
        @lists3[3] = ('fox', 'wolf')
        @lists3[4] = ('vaults', 'jumps')
        @lists3[5] = ('above', 'over')
        @lists3[6] = ('the', 'my')
        @lists3[7] = ('sleepy', 'lazy')
        @lists3[8] = ('hound', 'dog')
Output: true

 

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