Mad numbers
and shifty grid
Weekly challenge 354 — 29 December 2025
Week 354: 29 Dec 2025
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):
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]
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.
#!/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); }
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