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
Written on May 6, 2024