Perl Weekly Challenge 309.

My solutions (task 1 and task 2 ) to the The Weekly Challenge - 309.

Task 1: Min Gap

Submitted by: Mohammad Sajid Anwar
You are given an array of integers, @ints, increasing order.

Write a script to return the element before which you find the smallest gap.

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.

I make a kind of Schwartzian transform building pairs of the form [gap, element], I find the minimum with the min_by routine of List::UtilsBy, using the gap to compare pairs, and extract the corresponding element. min_by yields the first minimum in case of degeneracy. The code fits a oneliner. The task makes sense even if the list is not ordered.

Example 1:

perl -MList::UtilsBy=min_by -E '
@a=@ARGV;say "@ARGV -> ", (min_by {$_->[0]} map{[$a[$_]-$a[$_-1], $a[$_]]} 1..@a-1)->[1];
' 2 8 10 11 15

Results:

2 8 10 11 15 -> 11

Example 2:

perl -MList::UtilsBy=min_by -E '
@a=@ARGV;say "@ARGV -> ", (min_by {$_->[0]} map{[$a[$_]-$a[$_-1], $a[$_]]} 1..@a-1)->[1];
' 1 5 6 7 14

Results:

1 5 6 7 14 -> 6

Example 3:

perl -MList::UtilsBy=min_by -E '
@a=@ARGV;say "@ARGV -> ", (min_by {$_->[0]} map{[$a[$_]-$a[$_-1], $a[$_]]} 1..@a-1)->[1];
' 8 20 25 28

Results:

8 20 25 28 -> 28

The full code is:

 1  # Perl weekly challenge 309
 2  # Task 1:  Min Gap
 3  #
 4  # See https://wlmb.github.io/2025/02/16/PWC309/#task-1-min-gap
 5  use v5.36;
 6  use List::UtilsBy qw(min_by);
 7  die <<~"FIN" unless @ARGV>=2;
 8      Usage: $0 N0 N1...
 9      to find the element that is closest to its predecessor in the ordered list N0 N1...
10      FIN
11  say "@ARGV -> ", (min_by {$_->[0]} map{[$ARGV[$_]-$ARGV[$_-1], $ARGV[$_]]} 1..@ARGV-1)->[1];

Examples:

./ch-1.pl 2 8 10 11 15
./ch-1.pl 1 5 6 7 14
./ch-1.pl 8 20 25 28

Results:

2 8 10 11 15 -> 11
1 5 6 7 14 -> 6
8 20 25 28 -> 28

Task 2: Min Diff

Submitted by: Mohammad Sajid Anwar
You are given an array of integers, @ints.

Write a script to find the minimum difference between any two elements.

Example 1
Input: @ints = (1, 5, 8, 9)
Output: 1

1, 5 => 5 - 1 => 4
1, 8 => 8 - 1 => 7
1, 9 => 9 - 1 => 8
5, 8 => 8 - 5 => 3
5, 9 => 9 - 5 => 4
8, 9 => 9 - 8 => 1
Example 2
Input: @ints = (9, 4, 1, 7)
Output: 2

9, 4 => 9 - 4 => 5
9, 1 => 9 - 1 => 8
9, 7 => 9 - 7 => 2
4, 1 => 4 - 1 => 3
4, 7 => 7 - 4 => 3
1, 7 => 7 - 1 => 6

The minimum difference magnitude between any two elements is equal to the minimum difference between consecutive sorted elements. Thus, I sort the array, compute the differences between consecutive elements and search for the minumum using min from List::Util. The code fits a oneliner:

Example 1:

perl -MList::Util=min -E '
@s=sort{$a<=>$b}@ARGV; say "@ARGV -> ", min map{$s[$_]-$s[$_-1]}(1..@s-1)
' 1 5 8 9

Results:

1 5 8 9 -> 1

Example 2:

perl -MList::Util=min -E '
@s=sort{$a<=>$b}@ARGV; say "@ARGV -> ", min map{$s[$_]-$s[$_-1]}(1..@s-1)
' 9 4 1 7

Results:

9 4 1 7 -> 2

The full code is:

 1  # Perl weekly challenge 309
 2  # Task 2:  Min Diff
 3  #
 4  # See https://wlmb.github.io/2025/02/16/PWC309/#task-2-min-diff
 5  use v5.36;
 6  use List::Util qw(min);
 7  die <<~"FIN" unless @ARGV >= 2;
 8      Usage: $0 N0 N1...
 9      to find the minimum difference between the numbers N0, N1...
10      FIN
11  my @sorted=sort {$a<=>$b} @ARGV;
12  say "@ARGV -> ", min map{$sorted[$_]-$sorted[$_-1]}(1..@sorted-1);

Examples:

./ch-2.pl 1 5 8 9
./ch-2.pl 9 4 1 7

Results:

1 5 8 9 -> 1
9 4 1 7 -> 2

/;

Written on February 16, 2025