Uniquely ranked
Weekly challenge 260 — 11 March 2024
Week 260: 11 Mar 2024
You are given an array of integers, @ints. Write a script to return 1 if the number of occurrences of each value in the given array is unique or 0 otherwise.
Example 1 Input: @ints = (1,2,2,1,1,3) Output: 1 The number 1 occurred 3 times. The number 2 occurred 2 times. The number 3 occurred 1 time. All occurrences are unique, therefore the output is 1. Example 2 Input: @ints = (1,2,3) Output: 0 Example 3 Input: @ints = (-2,0,1,-2,1,1,0,1,-2,9) Output: 1
I approached this in what seemed to me to be the obvious way. First, I count
the number of times each $value
appears in @ints
and store that in
$occurs{$value}
. I use a hash because $value
might be negative.
Then I do another loop over keys %occurs
and check if $seen{$occurs{$value}}
is defined. If it isn't, then I haven't seen this frequency before and I set
$seen{$occurs{$value}} = $value
for future reference.
If it is defined
then this is a duplicate value, so I set $output
to 0 and record the reason
for failure - which is that $value
and $seen{$occurs{$value}}
both occur
$occurs{$value}
times.
I tried this with 10 000 random numbers and it completes in milliseconds, so I don't think it's worth looking to optimise it.
#!/usr/bin/perl # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge use v5.26; # The Weekly Challenge - 2024-03-11 use utf8; # Week 260 - task 1 - Unique occurrences use warnings; # Peter Campbell Smith binmode STDOUT, ':utf8'; unique_occurrences(1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5); unique_occurrences(1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5); unique_occurrences(1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5); my (@ints, $j); for $j (0 .. 99) { $ints[$j] = int(rand(21) - 10); } unique_occurrences(@ints); sub unique_occurrences { my (@ints, %occurs, $output, $reason, $value, %seen); # initialise @ints = @_; $output = 1; $reason = ''; say qq[\nInput: \@ints = (] . join(', ', @ints) . ')'; # count occurrences $occurs{$_} ++ for @ints; # see if they are all 1 for $value (keys %occurs) { if (defined $seen{$occurs{$value}}) { $output = 0; $reason = qq[($value and $seen{$occurs{$value}} both occur $occurs{$value} times)]; last; } $seen{$occurs{$value}} = $value; } # show the answer say qq[Output: $output $reason]; }
Input: @ints = (1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5) Output: 1 Input: @ints = (1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5) Output: 0 (5 and 4 both occur 5 times) Input: @ints = (1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 5) Output: 0 (4 and 3 both occur 3 times) Input: @ints = (1, 2, 9, 1, 0, 4, -1, -6, -4, -7, -8, -6, -5, 10, 10, 10, 5, 4, 4, 1, -8, -6, -3, 2, 8, 4, 2, 6, 7, 3, 4, 7, -8, 8, -9, 1, -7, 4, 1, -2, 7, -1, -7, 6, 0, -4, 4, 0, 10, 4, 6, -5, 9, -1, 3, -2, -4, 8, 6, -9, 0, -8, -1, 5, 3, 1, 1, 0, 3, 6, -5, -7, -4, 1, -1, 5, 3, -6, -4, -6, 0, -3, 7, 4, -7, 8, 9, 10, -4, 9, -4, -6, 2, -9, -9, 10, -2, -1, -8, 8) Output: 0 (-9 and 9 both occur 4 times)
Any content of this website which has been created by Peter Campbell Smith is in the public domain