Camel
Peter
Peter Campbell Smith

Mad numbers
and shifty grid

Weekly challenge 354 — 29 December 2025

Week 354: 29 Dec 2025

Task 1

Task — Min abs diff

You are given an array of distinct integers. Write a script to find all pairs of elements with the minimum absolute difference.

Rules (a,b):

  1. a, b are from the given array.
  2. a < b
  3. b - a = min abs diff any two elements in the given array

Examples


Example 1
Input: @ints = (4, 2, 1, 3)
Output: [1, 2], [2, 3], [3, 4]

Example 2
Input: @ints = (10, 100, 20, 30)
Output: [10, 20], [20, 30]

Example 3
Input: @ints = (-5, -2, 0, 3)
Output: [-2, 0]

Example 4
Input: @ints = (8, 1, 15, 3)
Output: [1, 3]

Example 5
Input: @ints = (12, 5, 9, 1, 15)
Output: [9, 12], [12, 15]

Analysis

I can see two ways to do this. The first uses two nested loops:

for $i (0 .. @ints - 2) {
   for $j (1 .. @ints - 1) {

Then it computes abs($ints[$i] - $ints[$j]) and saves the numbers if the result is the least so far.

However, there is an easier, if lazier way. First, sort @ints. It's now only necessary to do a single loop comparing each element with the one following, and again save the outcome if the difference is less than equal to the smallest seen so far.

Which way is better?

Clearly the second has a clear advantage in avoiding the nested loops, but it also has the overhead of sorting the array.

I tried the second solution - which is what I have submitted - with 10,000 random numbers in the range 0 to 9,999,999 and it came up with 6 pairs of identical numbers more or less instantly. So I think that is good enough.

I do note that the challenge says the numbers are distinct, so there will be no zero differences. My solution works whether or not there are pairs (or more) of identical numbers and thus zero differences.

Try it 

Try running the script with any input:



example: 3, 14, 15, 92, 65, 35

Script


#!/usr/bin/perl

# Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge

use v5.26;    # The Weekly Challenge - 2025-12-29
use utf8;     # Week 354 - task 1 - Min abs diff
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';
use Encode;

min_abs_diff(4, 2, 1, 3);
min_abs_diff(10, 100, 20, 30);
min_abs_diff(-5, -2, 0, 3);
min_abs_diff(8, 1, 15, 3);
min_abs_diff(12, 5, 9, 1, 15);

sub min_abs_diff {
    
    my (@sorted, $j, $least, $diff, $result);
    
    # initialise and sort
    @sorted = sort {$a <=> $b} @_;
    $least = ~1e10;
    
    # loop over numbers
    for $j (0 .. $#sorted - 1) {
        $diff = $sorted[$j + 1] - $sorted[$j];
        
        # not the best
        next if $diff > $least;
        
        # new best
        if ($diff < $least) {
            $result = '';
            $least = $diff;
        }
        
        # new best or equal to previous best
        $result .= qq[[$sorted[$j], $sorted[$j + 1]], ];
    }
        
    say qq[\nInput:  (] . join(', ', @_) . ')';
    say qq[Output: ] . substr($result, 0, -2);
}

Output


Input:  (4, 2, 1, 3)
Output: [1, 2], [2, 3], [3, 4]

Input:  (10, 100, 20, 30)
Output: [10, 20], [20, 30]

Input:  (-5, -2, 0, 3)
Output: [-2, 0]

Input:  (8, 1, 15, 3)
Output: [1, 3]

Input:  (12, 5, 9, 1, 15)
Output: [9, 12], [12, 15]

 

Any content of this website which has been created by Peter Campbell Smith is in the public domain