Matching and returning
Weekly challenge 293 — 28 October 2024
Week 293: 28 Oct 2024
You are given a list of dominoes, @dominoes
.
Write a script to return the number of dominoes that are similar to any other domino.
$dominoes[i] = [a, b] and $dominoes[j] = [c, d] are similar if either:
(a = c and b = d) or (a = d and b = c).
Example 1 Input: @dominos = ([1, 3], [3, 1], [2, 4], [6, 8]) Output: 2 Similar Dominos: $dominoes[0], $dominoes[1] Example 2 Input: @dominos = ([1, 2], [2, 1], [1, 1], [1, 2], [2, 2]) Output: 3 Similar Dominos: $dominoes[0], $dominoes[1], $dominoes[3]
Ever the pedant, my first observation is that dominoes, at least as played in the UK, have 0-6 spots on each side, so the 8 in example 1 is a little surprising. However, in the spirit of agreeing with the boss, I have provided a solution that works for any integral non-negative number of spots.
It's a slightly awkward challenge in that we are required to return the indices of the similar dominoes in the original array. My first thought was to sort the array, but that would lose the original order.
So my solution does this:
@dominoes
, appending each to an element of %matches
, for example, $matches{'1|2'}
#!/usr/bin/perl # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge use v5.26; # The Weekly Challenge - 2024-10-28 use utf8; # Week 293 - task 1 - Similar dominoes use warnings; # Peter Campbell Smith binmode STDOUT, ':utf8'; similar_dominoes([6, 8], [1, 3], [3, 1], [2, 4]); similar_dominoes([10, 12], [12, 10], [33, 34], [34, 33]); similar_dominoes([6, 8], [1, 3], [4, 1], [2, 4]); # bigger example my @d; for (0 .. 19) { push @d, [int(rand(7)), int(rand(7))]; } similar_dominoes(@d); sub similar_dominoes { my ($input, @dominoes, $d, %matches, $some); @dominoes = @_; $input .= qq{[$_->[0], $_->[1]], } for @dominoes; say qq[\nInput: (] . substr($input, 0, -2) . ')'; # sort each domino to have smallest value first (eg 2, 1 -> 1, 2) @dominoes = map ($_->[0] <= $_->[1] ? [$_->[0], $_->[1]] : [$_->[1], $_->[0]], @dominoes); # gather together ones that match for $d (0 .. $#dominoes) { $matches{qq[$dominoes[$d]->[0]|$dominoes[$d]->[1]]} .= qq[\$dominoes[$d], ]; } # list the ones where >1 match $some = 0; say qq[Output: Similar Dominoes:]; for $d (keys %matches) { print qq[ ] . substr($matches{$d}, 0, -2) if $matches{$d} =~ m|,.*,|; if ($matches{$d} =~ m|(\d+).+?(\d+)|) { say qq[ ($dominoes[$1]->[0] and $dominoes[$1]->[1])]; $some = 1; } } say qq[ None] unless $some; }
Input: ([6, 8], [1, 3], [3, 1], [2, 4]) Output: Similar Dominoes: $dominoes[1], $dominoes[2] (1 and 3) Input: ([10, 12], [12, 10], [33, 34], [34, 33]) Output: Similar Dominoes: $dominoes[0], $dominoes[1] (10 and 12) $dominoes[2], $dominoes[3] (33 and 34) Input: ([6, 8], [1, 3], [4, 1], [2, 4]) Output: Similar Dominoes: None Input: ([5, 0], [0, 1], [0, 1], [6, 0], [5, 1], [6, 3], [6, 0], [2, 6], [2, 5], [4, 4], [6, 5], [1, 6], [1, 0], [5, 0], [6, 2], [1, 6], [4, 4], [6, 1], [3, 5], [0, 5]) Output: Similar Dominoes: $dominoes[3], $dominoes[6] (6 and 0) $dominoes[11], $dominoes[15], $dominoes[17] (1 and 6) $dominoes[1], $dominoes[2], $dominoes[12] (0 and 1) $dominoes[7], $dominoes[14] (2 and 6) $dominoes[0], $dominoes[13], $dominoes[19] (5 and 0) $dominoes[9], $dominoes[16] (4 and 4)
Any content of this website which has been created by Peter Campbell Smith is in the public domain