Perl Weekly Challenge 268.
My solutions (task 1 and task 2 ) to the The Weekly Challenge - 268.
Task 1: Magic Number
Submitted by: Mohammad Sajid Anwar
You are given two arrays of integers of same size, @x and @y.
Write a script to find the magic number that when added to each elements of one
of the array gives the second array. Elements order is not important.
Example 1
Input: @x = (3, 7, 5)
@y = (9, 5, 7)
Output: 2
The magic number is 2.
@x = (3, 7, 5)
+ 2 2 2
@y = (5, 9, 7)
Example 2
Input: @x = (1, 2, 1)
@y = (5, 4, 4)
Output: 3
The magic number is 3.
@x = (1, 2, 1)
+ 3 3 3
@y = (5, 4, 4)
Example 3
Input: @x = (2)
@y = (5)
Output: 3
The simplest solution is to take the difference between the maxima or the minima of the arrays, as it should equal the difference between the second largest or second smaller elements, the third largest or the third smallest, etc.
Example 1:
perl -MList::Util=min -E '
($x,$y)=map {min split " "} @ARGV; say "($ARGV[0]),($ARGV[1])->",$y-$x
' "3 7 5" "9 5 7"
Results:
(3 7 5),(9 5 7)->2
Example 2:
perl -MList::Util=min -E '
($x,$y)=map {min split " "} @ARGV; say "($ARGV[0]),($ARGV[1])->",$y-$x
' "1 2 1" "5 4 4"
Results:
(1 2 1),(5 4 4)->3
Example 3:
perl -MList::Util=min -E '
($x,$y)=map {min split " "} @ARGV; say "($ARGV[0]),($ARGV[1])->",$y-$x
' 2 5
Results:
(2),(5)->3
The problem is that there might be no magic number, so a test should
be performed. The simplest solution would then be to sort the arrays,
run-length encode their difference and checking there is only one
distinct value. This may be done with the Perl Data Language PDL
Example 1:
perl -MPDL -E '
($x,$y)=map{pdl $_}@ARGV;($r,$v)=($y->qsort-$x->qsort)->rle; say "@ARGV -> ", $v->dim(0)==1?$v:"None"
' "[3 7 5]" "[9 5 7]"
Results:
[3 7 5] [9 5 7] -> [2]
Example 2:
perl -MPDL -E '
($x,$y)=map{pdl $_}@ARGV;($r,$v)=($y->qsort-$x->qsort)->rle; say "@ARGV -> ", $v->dim(0)==1?$v:"None"
' "[1 2 1]" "[5 4 4]"
Results:
[1 2 1] [5 4 4] -> [3]
Example 3:
perl -MPDL -E '
($x,$y)=map{pdl $_}@ARGV;($r,$v)=($y->qsort-$x->qsort)->rle; say "@ARGV -> ", $v->dim(0)==1?$v:"None"
' "[2]" "[5]"
Results:
2 5 -> [3]
Example with inconsistent data:
perl -MPDL -E '
($x,$y)=map{pdl $_}@ARGV;($r,$v)=($y->qsort-$x->qsort)->rle; say "@ARGV -> ", $v->dim(0)==1?$v:"None"
' "[3 7 5]" "[9 5 8]"
Results:
[3 7 5] [9 5 8] -> None
Full code:
1 # Perl weekly challenge 268
2 # Task 1: Magic Number
3 #
4 # See https://wlmb.github.io/2024/05/06/PWC268/#task-1-magic-number
5 use v5.36;
6 use PDL;
7 die <<~"FIN" unless @ARGV==2;
8 Usage: $0 X Y
9 where X is "[x1 x2...]" and Y=[y1 y2...]
10 to find the magic number M which added to the elements
11 of X yields the elements of Y
12 FIN
13 my ($x,$y)=map{pdl $_}@ARGV;
14 my (undef, $values)=($y->qsort-$x->qsort)->rle;
15 say "@ARGV -> ", $values->dim(0)==1?$values:"None"
Examples:
./ch-1.pl "[3 7 5]" "[9 5 7]"
./ch-1.pl "[1 2 1]" "[5 4 4]"
./ch-1.pl "[2]" "[5]"
./ch-1.pl "[3 7 5]" "[9 5 8]"
Results:
[3 7 5] [9 5 7] -> [2]
[1 2 1] [5 4 4] -> [3]
[2] [5] -> [3]
[3 7 5] [9 5 8] -> None
Task 2: Number Game
Submitted by: Mohammad Sajid Anwar
You are given an array of integers, @ints, with even number of elements.
Write a script to create a new array made up of elements of the given array. Pick the two smallest integers and add it to new array in decreasing order i.e. high to low. Keep doing until the given array is empty.
Example 1
Input: @ints = (2, 5, 3, 4)
Output: (3, 2, 5, 4)
Round 1: we picked (2, 3) and push it to the new array (3, 2)
Round 2: we picked the remaining (4, 5) and push it to the new array (5, 4)
Example 2
Input: @ints = (9, 4, 1, 3, 6, 4, 6, 1)
Output: (1, 1, 4, 3, 6, 4, 9, 6)
Example 3
Input: @ints = (1, 2, 2, 3)
Output: (2, 1, 3, 2)
This is easily solved by sorting the array in ascending order and
looking at the elements two at a time using the new for_list
and
sorting them in descending order.
Example 1:
perl -Mexperimental=for_list -E '
for my($x, $y)(sort {$a<=>$b} @ARGV){push @r, sort{$b<=>$a}($x,$y)} say "@ARGV -> @r";
' 2 5 3 4
Results:
2 5 3 4 -> 3 2 5 4
Example 2:
perl -Mexperimental=for_list -E '
for my($x, $y)(sort {$a<=>$b} @ARGV){push @r, sort{$b<=>$a}($x,$y)} say "@ARGV -> @r";
' 9 4 1 3 6 4 6 1
Results:
9 4 1 3 6 4 6 1 -> 1 1 4 3 6 4 9 6
Example 3:
perl -Mexperimental=for_list -E '
for my($x, $y)(sort {$a<=>$b} @ARGV){push @r, sort{$b<=>$a}($x,$y)} say "@ARGV -> @r";
' 1 2 2 3
Results:
1 2 2 3 -> 2 1 3 2
Full code:
1 # Perl weekly challenge 268
2 # Task 2: Number Game
3 #
4 # See https://wlmb.github.io/2024/05/06/PWC268/#task-2-number-game
5 use v5.36;
6 use experimental qw(for_list);
7 die <<~"FIN" unless @ARGV and @ARGV%2==0;
8 Usage: $0 N1 N2... N2m
9 to print array even sized array N1..N2m in zig-zag order
10 (decreasing pairs of increasing value)
11 FIN
12 my @result;
13 for my($x, $y)(sort {$a<=>$b} @ARGV){
14 push @result, sort{$b<=>$a}($x,$y)
15 }
16 say "@ARGV -> @result";
Examples:
./ch-2.pl 2 5 3 4
./ch-2.pl 9 4 1 3 6 4 6 1
./ch-2.pl 1 2 2 3
Results:
2 5 3 4 -> 3 2 5 4
9 4 1 3 6 4 6 1 -> 1 1 4 3 6 4 9 6
1 2 2 3 -> 2 1 3 2