Peter’s blog ✴ Week 283 ✴ 19 August 2024
THE WEEKLY CHALLENGE
Occurrences
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.
Try DIY tool to play with your sample data. Interface is very user friendly to keep you engage. Thanks for your contributions.
#!/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]; }
10 lines of code
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