Flipping members
Weekly challenge 242 — 6 November 2023
Week 242: 6 Nov 2023
You are given two arrays of integers. Write a script to list the members of each array which are missing from the other array.
Example 1 Input: @arr1 = (1, 2, 3) @arr2 = (2, 4, 6) Output: ([1, 3], [4, 6]) (1, 2, 3) has 2 members (1, 3) missing in the array (2, 4, 6). (2, 4, 6) has 2 members (4, 6) missing in the array (1, 2, 3). Example 2 Input: @arr1 = (1, 2, 3, 3) @arr2 = (1, 1, 2, 2) Output: ([3]) (1, 2, 3, 3) has 2 members (3, 3) missing in the array (1, 1, 2, 2). Since they are same, keep just one. (1, 1, 2, 2) has 0 member missing in the array (1, 2, 3, 3).
This is easily stated and fairly easily solved, but it is harder to come up with a good solution that would work efficiently if the arrays had, thousands of members. In such a case I can think of two approaches:
1 Sort each array and work steadily along both of them in parallel, noting where a value was missinng from either.
2 Use a hash and build $exists{$j}
for every $j
in @arr2
, and then match
@arr1
sequentially aginst the hash.
But our arrays are small and I didn't use either of those approaches. Mine simply does this:
for $j (@two) { @one = grep { $_ != $j } @one; }
This iterates $j
over the members of @two
and creates a new @one
which omits any
$two[$j]
. For this to give the required answer, the arrays have to be made unique, and I
used the handy module List::Uniq
for that.
And, of course, all of these solutions need to be done again with @arr1
and @arr2
swapped.
#!/usr/bin/perl use v5.16; # The Weekly Challenge - 2023-11-06 use utf8; # Week 242 task 1 - Missing members use strict; # Peter Campbell Smith use warnings; # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge use List::Uniq 'uniq'; missing_members([1, 2, 3], [2, 4, 6]); missing_members([1, 2, 3, 3], [1, 1, 2, 2]); missing_members([1, 2, 3, 4, 5, 6, 7, 8, 9], [2, 4, 6, 8, 10]); # make bigger example my ($j, @arr1, @arr2); for $j (0 .. 29) { push @arr1, int(rand(15) + 1); push @arr2, int(rand(15) + 1); } missing_members(\@arr1, \@arr2); sub missing_members { printf('%sInput: ([%s], [%s])%s', "\n", join(', ', @{$_[0]}), join(', ', @{$_[1]}), "\n"); printf('Output: ([%s], [%s])%s', mm($_[0], $_[1]), mm($_[1], $_[0]), "\n"); } sub mm { my (@one, @two, $j); # make each array unique @one = uniq(@{$_[0]}); @two = uniq(@{$_[1]}); # delete from @one anything that occurs in @two for $j (@two) { @one = grep { $_ != $j } @one; } # and return what's left return join(', ', @one); }
Input: ([1, 2, 3], [2, 4, 6]) Output: ([1, 3], [4, 6]) Input: ([1, 2, 3, 3], [1, 1, 2, 2]) Output: ([3], []) Input: ([1, 2, 3, 4, 5, 6, 7, 8, 9], [2, 4, 6, 8, 10]) Output: ([1, 3, 5, 7, 9], [10]) Input: ([13, 7, 6, 9, 7, 8, 11, 1, 14, 7, 15, 12, 11, 7, 5, 4, 1, 7, 11, 5, 14, 3, 8, 8, 6, 3, 15, 9, 12, 11], [7, 5, 12, 10, 1, 5, 9, 12, 7, 9, 8, 3, 14, 14, 10, 15, 10, 10, 6, 7, 10, 15, 1, 8, 8, 14, 15, 1, 2, 11]) Output: ([13, 4], [10, 2])
Any content of this website which has been created by Peter Campbell Smith is in the public domain