Camel
Peter
Peter Campbell Smith

One and two dimensions

Weekly challenge 337 — 1 September 2025

Week 337: 1 Sep 2025

Task 1

Task — Smaller than current

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].

Examples


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)

Analysis

* 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.

Try it 

Try running the script with any input:



example: 3, 1, 4, 1, 5, 9, 2, 6, 5, 4

Script


#!/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) . ')'
}

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