One and two dimensions
Weekly challenge 337 — 1 September 2025
Week 337: 1 Sep 2025
You are given an array of numbers, @num1
.
Write a script to return an array, @num2
, where $num2[$i]
is the count of all numbers less than
or equal to* $num1[$i]
.
Example 1 Input: @num1 = (6, 5, 4, 8) Output: (2, 1, 0, 3) index 0: numbers <= 6 are 5, 4 => 2 index 1: numbers <= 5 are 4 => 1 index 2: numbers <= 4, none => 0 index 3: numbers <= 8 are 6, 5, 4 => 3 Example 2 Input: @num1 = (7, 7, 7, 7) Output: (0, 0, 0, 0) Example 3 Input: @num1 = (5, 4, 3, 2, 1) Output: (4, 3, 2, 1, 0) Example 4 Input: @num1 = (-1, 0, 3, -2, 1) Output: (1, 2, 4, 0, 3) Example 5 Input: @num1 = (0, 1, 1, 2, 0) Output: (0, 2, 2, 4, 0)
* The examples suggest that the intended condition is 'less than' rather than 'less than or equal to' and I have gone with a solution that matches the examples.
The obvious way to do this is to loop over the input array, and for each element, count the number of other elements less than it. That is easily coded in Perl, with the key line being:
$output[$j] ++ for grep { $_ < $input[$j] } @input
If the array were large - say a million elements - it might be
more efficient to cache the results in a hash. So, for example
if we had elements with values 500 and 600 we could count
the elements less than 500 and set $less_than{500} = $count
.
Then for 600 we'd only need to look for elements with values in the range
500 to 599 and then add $less_than{500}
to that total.
#!/usr/bin/perl # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge use v5.26; # The Weekly Challenge - 2025-09-01 use utf8; # Week 337 - task 1 - Smaller than current use warnings; # Peter Campbell Smith binmode STDOUT, ':utf8'; use Encode; smaller_than_current(6, 5, 4, 8); smaller_than_current(7, 7, 7, 7); smaller_than_current(5, 4, 3, 2, 1); smaller_than_current(-1, 0, 3, -2, 1); smaller_than_current(0, 1, 1, 2, 0); sub smaller_than_current { my (@input, @output, $j); # initialise @input = @_; # count elements smaller than this one for $j (0 .. $#input) { $output[$j] = 0; $output[$j] ++ for grep { $_ < $input[$j] } @input; } say qq[\nInput: (] . join(', ', @input) . ')'; say qq[Output: (] . join(', ', @output) . ')' }
Input: (6, 5, 4, 8) Output: (2, 1, 0, 3) Input: (7, 7, 7, 7) Output: (0, 0, 0, 0) Input: (5, 4, 3, 2, 1) Output: (4, 3, 2, 1, 0) Input: (-1, 0, 3, -2, 1) Output: (1, 2, 4, 0, 3) Input: (0, 1, 1, 2, 0) Output: (0, 2, 2, 4, 0)
Any content of this website which has been created by Peter Campbell Smith is in the public domain