Occurrences
Weekly challenge 283 — 19 August 2024
Week 283: 19 Aug 2024
You are given an array of integers, @ints
, where every element appears more than
once except one element.
Write a script to find the one element that appears exactly one time.
Example 1 Input: @ints = (3, 3, 1) Output: 1 Example 2 Input: @ints = (3, 2, 4, 2, 4) Output: 3 Example 3 Input: @ints = (1) Output: 1 Example 4 Input: @ints = (4, 3, 1, 1, 1, 4) Output: 3
My first idea for solving this was to concatenate the members of @ints
into $string
,
enclosing each element with some sort of brackets. I tried it with <>
as those characters
are not special in a regular expression. So:
1, 2, 2, 3, 3 => <1><2><2><3><3>
I can then do this:
for $i (@ints) { if (@string !~ m|<$i>.*<$i>|) { ... $i is the answer
That works for the given examples, and indeed for any example I could think of. But it is slightly inefficient in that it will check the duplicated numbers more than once if they appear more than once before the unique one.
So I went for a 'purer' solution, which is simply to count the frequency $freq{$i}
of all the numbers $i
,
and then to loop through %freq
to find the first $freq{$i}
having a value of 1.
Neither of these solutions tests the validity of the assertion that there is one and only one
element of @ints
that occurs just once, and in a production environment it would of course be
very advisable to do that.
#!/usr/bin/perl # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge use v5.26; # The Weekly Challenge - 2024-08-19 use utf8; # Week 283 - task 1 - Unique number use warnings; # Peter Campbell Smith binmode STDOUT, ':utf8'; unique_number(1, 1, 2, 3, 4, 5, 3, 4, 5); unique_number(3, 2, 4, 2, 4); unique_number(7); unique_number(4, 3, 1, 1, 4); unique_number(123, 456, 77, 9999, 55, 55, 9999, 77, 456); sub unique_number { my (@ints, %freq, $j); @ints = @_; say qq[\nInput: \@ints = (] . join(', ', @ints) . ')'; # count occurrences of each number $freq{$_} ++ for @ints; # find the (first) one that only occurs once for $j (keys %freq) { if ($freq{$j} == 1) { say qq[Output: $j]; return; } } # none occurs once say qq[Output: none]; }
Input: @ints = (1, 1, 2, 3, 4, 5, 3, 4, 5) Output: 2 Input: @ints = (3, 2, 4, 2, 4) Output: 3 Input: @ints = (7) Output: 7 Input: @ints = (4, 3, 1, 1, 4) Output: 3 Input: @ints = (123, 456, 77, 9999, 55, 55, 9999, 77, 456) Output: 123
Any content of this website which has been created by Peter Campbell Smith is in the public domain