The weekly challenge 242 - Task 1: Missing Members

 1 #!/usr/bin/perl
 2 # https://theweeklychallenge.org/blog/perl-weekly-challenge-242/#TASK1
 3 #
 4 # Task 1: Missing Members
 5 # =======================
 6 #
 7 # You are given two arrays of integers.
 8 #
 9 # Write a script to find out the missing members in each other arrays.
10 #
11 ## Example 1
12 ##
13 ## Input: @arr1 = (1, 2, 3)
14 ##        @arr2 = (2, 4, 6)
15 ## Output: ([1, 3], [4, 6])
16 ##
17 ## (1, 2, 3) has 2 members (1, 3) missing in the array (2, 4, 6).
18 ## (2, 4, 6) has 2 members (4, 6) missing in the array (1, 2, 3).
19 #
20 ## Example 2
21 ##
22 ## Input: @arr1 = (1, 2, 3, 3)
23 ##        @arr2 = (1, 1, 2, 2)
24 ## Output: ([3])
25 ##
26 ## (1, 2, 3, 3) has 2 members (3, 3) missing in the array (1, 1, 2, 2). Since they are same, keep just one.
27 ## (1, 1, 2, 2) has 0 member missing in the array (1, 2, 3, 3).
28 #
29 ############################################################
30 ##
31 ## discussion
32 ##
33 ############################################################
34 #
35 # For each element of each array, if it is not in the other array,
36 # save it for the output.
37 # Example 2 has a caveat though, by not returning an empty array in
38 # case of no missing elements it is unclear in which of the arrays
39 # the element was originally. It's better to return an empty array
40 # here, so let's just do that instead.
41 
42 missing_members( [ 1, 2, 3 ], [ 2, 4, 6 ] );
43 missing_members( [ 1, 2, 3, 3 ], [ 1, 1, 2, 2 ] );
44 
45 sub missing_members {
46    my ($arr1, $arr2) = @_;
47    print "Input: (" . join(", ", @$arr1) . "), (" . join(", ", @$arr2) . ")\n";
48    my (@res1, @res2, %keys1, %keys2);
49    map { $keys1{$_} = 1; } @$arr1;
50    map { $keys2{$_} = 1; } @$arr2;
51    my %seen = ();
52    foreach my $elem (@$arr1) {
53       push @res1, $elem unless $keys2{$elem} or $seen{$elem};
54       $seen{$elem} = 1;
55    }
56    %seen = ();
57    foreach my $elem (@$arr2) {
58       push @res2, $elem unless $keys1{$elem} or $seen{$elem};
59       $seen{$elem} = 1;
60    }
61    print "Output: ([" . join(", ", @res1) . "], [" . join(", ", @res2) . "])\n";
62 }