Camel
Peter
Peter Campbell Smith

Missing and mad

Weekly challenge 327 — 23 June 2025

Week 327: 23 Jun 2025

Task 2

Task — Mad

You are given an array of distinct integers. Write a script to find all pairs of elements with minimum absolute difference (MAD) of any two elements.

Examples


Example 1
Input: @ints = (4, 1, 2, 3)
Output: [1,2], [2,3], [3,4]
The minimum absolute difference is 1.
Pairs with MAD: [1,2], [2,3], [3,4]

Example 2
Input: @ints = (1, 3, 7, 11, 15)
Output: [1,3]

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

Analysis

It seems inevitable that we have to check each possible pair of elements to determine the least difference, and even if we find a zero difference we still need to check the remaining ones because we are required to find all MAD pairs.

So I chose to build a hash %difference where the key is the difference between two elements of the input array and the value is a concatenation of qq[$input[$i], $input[$j], ], which is what we'll need if this difference turns out to be the least.

I then sort (numerically) the keys of %difference into @sorted, and the desired result is $difference{$sorted[0]}.

Except it isn't quite, because Mohammad has neatly presented the results with the lower index first and in ascending order by that lower index. We can achieve that simply by sorting @input at the start.

Try it 

Try running the script with any input:



example: 1, 2, 4, 7, 11, 16, 22, 29, 30

Script


#!/usr/bin/perl

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

use v5.26;    # The Weekly Challenge - 2025-06-23
use utf8;     # Week 327 - task 2 - Mad
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';
use Encode;

mad(4, 1, 2, 3);
mad(1, 3, 7, 11, 15);
mad(1, 5, 3, 8);

# bigger example
my (@input);
push @input, int(rand(10000)) for 0 .. 74;
mad(@input);

sub mad {
    
    my(@input, $i, $j, %difference, @sorted);
    
    # initialise (and sort to match Mohammad's output)
    @input = sort @_;
    
    # create all pairs
    for $i (0 .. $#input - 1) {
        for $j ($i + 1 .. $#input) {
            
            # store the differences in $difference{$diff}
            $difference{abs($input[$i] - $input[$j])} .= qq[[$input[$i], $input[$j]], ];
        }
    }
    
    # sort the keys of @difference - so $sorted[0] is the least
    @sorted = sort {$a <=> $b} keys %difference;
        
    # report
    say qq[\nInput:  (] . join(', ', @_) . q[)];
    say qq[Output: ] . substr($difference{$sorted[0]}, 0, -2);
}

Output


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

Input:  (1, 3, 7, 11, 15)
Output: [1, 3]

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

Input:  (4899, 3647, 8429, 1525, 9097, 8957, 6344, 6664,
   4466, 1086, 1042, 7752, 778, 3058, 4421, 1509, 316,
   8288, 4975, 4719, 1738, 544, 8637, 3833, 1663, 9784,
   2932, 6250, 4075, 6150, 9458, 2031, 8985, 2381, 4780,
   7599, 4449, 7726, 2485, 9814, 5509, 402, 3768, 8449,
   1343, 7439, 1807, 2501, 7225, 9487, 7322, 5083, 1418,
   8360, 1982, 8127, 2285, 8628, 251, 1171, 7305, 3817,
   3278, 3839, 841, 7456, 4666, 3733, 140, 9369, 3344,
   6571, 660, 5968, 4052)
Output: [3833, 3839]

 

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