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
/;