Unique arrays and
differing dates
Weekly challenge 183 — 19 September 2022
Week 183: 19 Sep 2022
You are given list of arrayrefs. Write a script to remove the duplicate arrayrefs from the given list.
Example 1 Input: @list = ([1,2], [3,4], [5,6], [1,2]) Output: ([1,2], [3,4], [5,6]) Example 2 Input: @list = ([9,1], [3,7], [2,5], [2,5]) Output: ([9, 1], [3,7], [2,5])
We are given list of arrayrefs and asked to write a script to remove duplicates, ie to eliminate references to arrays which are identical to earlier ones. The examples show the arrays containing positive integers; I have generalised the problem to assume that the array elements can be uniquely represented as strings. This allows any type of number or character string or null, but not perhaps references.
So I wrote a sub signature(@a)
which creates a string by concatenating the array elements with a suitable separator. I used 0xFF as the separator, which will not occur in the representation of any array elements described above.
It's then just a matter of going through the supplied list, checking that $seen{$signature}
is null and if so adding the current list item to the output list and setting $seen{$signature} = 1
.
There is some ambiguity in the task description, and, for example, my algorithm will treat all of the following as being identical: [1, 2], [1.0, 2.0], [1e0, 2e0], ['1', '2'].
#!/usr/bin/perl # Peter Campbell Smith - 2022-09-20 # PWC 183 task 1 use v5.28; use utf8; use warnings; my (@lists, @list, $separator, $list_ref, $item, $signature, @new_list, %seen); # inputs @lists = ( [[1,2], [3,4], [5,6], [1,2]], [[9,1], [3,7], [2,5], [2,5]], [[4,6], [6,4], [9,0], [6,4], [5,7], [7,-1], [4,6]], [['cat', 'dog'], ['cat', 'mouse'], ['cat, cat'], ['dog', 'cat'], ['mouse', 'mouse'], ['cat', 'mouse']], [[1, 2], [1.0, 2.0], [1e0, 2e0], ['1', '2'], [4 - 3, 9 - 8], [0, 0]]); # loop over inputs and initialise $separator = 0xFF; while ($list_ref = shift @lists) { @list = @$list_ref; @new_list = (); %seen = (); say ''; # loop over items in @list and add them to @new_list if unseen so far for $item (@list) { $signature = array_signature($item); next if $seen{$signature}; push @new_list, $item; $seen{$signature} = 1; } # show the input and output show_list('Input: ', @list); show_list('Output:', @new_list); } sub array_signature { # returns a stringified copy of inpout @list my ($list, $j, $signature); $list = shift; for $j (0 .. scalar @$list - 1) { $signature .= $list->[$j] . $separator; } return $signature; } sub show_list { # displays @list in Mohammad's format my ($caption, @list, $output, $j); ($caption, @list) = @_; $output = qq[$caption (]; for $item (@list) { $output .= '['; for $j (0 .. scalar @$item - 1) { $output .= $item->[$j] . ', ' } $output =~ s|, $|], |; } $output =~ s|, $|)|; say $output; }
Input: ([1, 2], [3, 4], [5, 6], [1, 2]) Output: ([1, 2], [3, 4], [5, 6]) Input: ([9, 1], [3, 7], [2, 5], [2, 5]) Output: ([9, 1], [3, 7], [2, 5]) Input: ([4, 6], [6, 4], [9, 0], [6, 4], [5, 7], [7, -1], [4, 6]) Output: ([4, 6], [6, 4], [9, 0], [5, 7], [7, -1]) Input: ([cat, dog], [cat, mouse], [cat, cat], [dog, cat], [mouse, mouse], [cat, mouse]) Output: ([cat, dog], [cat, mouse], [cat, cat], [dog, cat], [mouse, mouse]) Input: ([1, 2], [1, 2], [1, 2], [1, 2], [1, 1], [0, 0]) Output: ([1, 2], [1, 1], [0, 0])
Any content of this website which has been created by Peter Campbell Smith is in the public domain