Camel
Peter
Peter Campbell Smith

Mind the gap

Weekly challenge 309 — 17 February 2025

Week 309: 17 Feb 2025

Task 1

Task — Min gap

You are given an array of integers, @ints, increasing order. Write a script to return the element before which you find the smallest gap.

Examples


Example 1
Input: @ints = (2, 8, 10, 11, 15)
Output: 11
 8 - 2  => 6
10 - 8  => 2
11 - 10 => 1
15 - 11 => 4
11 is where we found the min gap.

Example 2
Input: @ints = (1, 5, 6, 7, 14)
Output: 6
 5 - 1 => 4
 6 - 5 => 1
 7 - 6 => 1
14 - 7 => 7
6 and 7 where we found the min gap, so we pick the 
   first instance.

Example 3
Input: @ints = (8, 20, 25, 28)
Output: 28
 8 - 20 => 14
25 - 20 => 5
28 - 25 => 3
28 is where we found the min gap.

Analysis

So, once again, someone will have a nice one-liner and I have chosen to do it the more explicit way, by moving along @ints from the second element to the last, comparing each element with the previous one. While that might be expressed more succinctly in code, I don't think there is much one could do to optimise the search.

It's interesting that when I generate an @ints as 12 random integers in the range 0 - 999, the minimum gap is often 0 or 1 and rarely more than 9. If they were distributed evenly, the 11 gaps would all be 90.

Try it 

Try running the script with any input:



example: 1, 4, 9, 34, 36

Script


#!/usr/bin/perl

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

use v5.26;    # The Weekly Challenge - 2025-02-17
use utf8;     # Week 309 - task 1 - Min gap
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';

min_gap(2, 8, 10, 11, 15);
min_gap(1, 5, 6, 7, 14);
min_gap(8, 20, 25, 28);

my @ints;
push @ints, int(rand(1000)) for 0 .. 11;
@ints = sort {$a <=> $b} @ints;
min_gap(@ints);

sub min_gap {
    
    my (@ints, $min_gap, $gap, $j, $before);
    
    # initialise
    @ints = @_; 
    $min_gap = 1e9;
    
    # loop over @ints starting at the second element
    for $j (1 .. $#ints) {
        $gap = $ints[$j] - $ints[$j - 1];
        next if $gap >= $min_gap;
        
        # found the smallest so far
        $min_gap = $gap;
        $before = $ints[$j];
    }
    
    say qq[\nInput:  \@ints = (] . join(', ', @ints) . ')';
    say qq[Output: minimum gap ($min_gap) is before $before];
}

Output


Input:  @ints = (2, 8, 10, 11, 15)
Output: minimum gap (1) is before 11

Input:  @ints = (1, 5, 6, 7, 14)
Output: minimum gap (1) is before 6

Input:  @ints = (8, 20, 25, 28)
Output: minimum gap (3) is before 28

Input:  @ints = (33, 150, 353, 387, 425, 594, 631, 765,
   772, 775, 818, 826)
Output: minimum gap (3) is before 775

 

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