Camel
Peter
Peter Campbell Smith

Pair products,
peak points

Weekly challenge 339 — 15 September 2025

Week 339: 15 Sep 2025

Task 1

Task — Max diff

You are given an array of integers having four or more elements. Write a script to find two pairs of numbers from this list (four numbers total) so that the absolute difference between their products is as large as possible.

Examples


Example 1
Input: @ints = (5, 9, 3, 4, 6)
Output: 42
Pair 1: (9, 6)
Pair 2: (3, 4)
Product Diff: (9 * 6) - (3 * 4) => 54 - 12 => 42

Example 2
Input: @ints = (1, -2, 3, -4)
Output: 10
Pair 1: (1, -2)
Pair 2: (3, -4)

Example 3
Input: @ints = (-3, -1, -2, -4)
Output: 10
Pair 1: (-1, -2)
Pair 2: (-3, -4)

Example 4
Input: @ints = (10, 2, 0, 5, 1)
Output: 50
Pair 1: (10, 5)
Pair 2: (0, 1)

Example 5
Input: @ints = (7, 8, 9, 10, 10)
Output: 44
Pair 1: (10, 10)
Pair 2: (7, 8)

Analysis

This is a frustrating challenge in that in some cases there is a simple answer. For example, first sort the provided list, and:

  • if all the numbers are >= 0 then the pairs are the first two and last two from the sorted list, and
  • the same is true if they are all <= 0.

But if neither condition is true, it gets more complicated.

So I went with a foolproof but increasingly expensive solution which is to generate all the variations of 4 numbers from the supplied array and testing them each to see which gives the largest difference.

I have included in my worked examples 50 random numbers in the range -250 .. +250 and my solution takes only about 10 seconds on my quite slow processor, so unless this were needed in a time-critical application I think it would be adequate.

Try it 

Try running the script with any input:



example: -6, 3, 4, 5, 7

Script


#!/usr/bin/perl

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

use v5.26;    # The Weekly Challenge - 2025-09-15
use utf8;     # Week 339 - task 1 - Max diff
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';
use Encode;
use Algorithm::Combinatorics 'variations';

max_diff(5, 9, 3, 4, 6);
max_diff(1, -2, 3, -4);
max_diff(-3, -1, -2, -4);
max_diff(10, 2, 0, 5, 1);
max_diff(7, 8, 9, 10, 10);
max_diff(0, 0, 0, 0, 0);
max_diff(5, 5, 5, 5, 5);
max_diff(-5, -5, -5, -5, -5);

# 50 random numbers in [-250 .. +250]
my @ints;
push @ints, int(rand(501)) - 250 for 1 .. 50;
max_diff(@ints);

sub max_diff {
    
    my ($best, $iter, $c, $diff, $pairs);
    
    # initialise
    $best = -1;
    $iter = variations(\@_, 4);
    
    # iterate over all variations
    while ($c = $iter->next) {
        
        # is this one the best so far?
        $diff = abs($c->[0] * $c->[1] - $c->[2] * $c->[3]);
        if ($diff > $best) {
            $best = $diff;
            $pairs = qq[($c->[0], $c->[1]), ($c->[2], $c->[3])];
        }
    }

    say qq[\nInput:  (] . join(', ', @_) . ')';
    say qq[Output: $best\n        $pairs];
}

Output


Input:  (5, 9, 3, 4, 6)
Output: 42
        (9, 6), (3, 4)

Input:  (1, -2, 3, -4)
Output: 10
        (1, -2), (3, -4)

Input:  (-3, -1, -2, -4)
Output: 10
        (-3, -4), (-1, -2)

Input:  (10, 2, 0, 5, 1)
Output: 50
        (10, 5), (2, 0)

Input:  (7, 8, 9, 10, 10)
Output: 44
        (7, 8), (10, 10)

Input:  (0, 0, 0, 0, 0)
Output: 0
        (0, 0), (0, 0)

Input:  (5, 5, 5, 5, 5)
Output: 0
        (5, 5), (5, 5)

Input:  (-5, -5, -5, -5, -5)
Output: 0
        (-5, -5), (-5, -5)

Input:  (63, 244, -97, -189, -240, 246, -146, -221, 220,
   167, 180, 128, 1, -217, -223, -25, -105, 41, -79, -201,
   -184, -247, -158, -229, 205, -58, -194, 147, -21, -184,
   213, -179, 142, -172, 14, -232, -228, -138, -135, -49,
   121, -189, 156, 248, -111, -104, -41, -163, 77, 0)
Output: 121280
        (244, 246), (-247, 248)

 

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