Peter’s blog ✴ Week 268 ✴ 6 May 2024

THE WEEKLY CHALLENGE
Magic and scrambled numbers

The Perl Camel

Task 1

Magic numbers

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 element of the first array gives the second array. The elements' order is not important.

Examples


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

Analysis

I have given in to the temptation of a one-line answer, which may require a few lines of explanation.

Firstly, I have taken the task literally to the extent that I am not testing the assertion that all the elements of @y are indeed those of @x incremented by a constant amount. In a production environment I would of course check that.

So if we sort @x and @y the answer is simply $y[0] - $x[0].

My code works because:

  • the second argument to the sub is $_[1], which is a reference to @y,
  • so @{$_[1]} is @y,
  • and sort {$a <=> $b} @{$_[1]} returns an array which is @y sorted,
  • and [sort {$a <=> $b} @{$_[1]}] is an anonymous reference to that sorted @y,
  • and [sort {$a <=> $b} @{$_[1]}]->[0] returns the first and smallest element of sorted @y,
  • and the smallest value in @x is derived in the same way,
  • so the answer is the difference between these two.

You might argue that that isn't very readable, and I would agree with you. In production code I would almost certainly have expanded it to a few lines to make it easier to read, but in The Weekly Challenge brevity is often seen as praiseworthy!

Perl Weekly’s review

from Perl Weekly issue 668

Peter finally gave in and created one-liner in Perl. It is so much fun to see how powerful it is.

Try it 

Try running the script with any input:



example: 1, 2, 3, 4, 5



example: 9, 8, 7, 6, 5

Script


#!/usr/bin/perl

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

use v5.26;    # The Weekly Challenge - 2024-05-06
use utf8;     # Week 268 - task 1 - Magic number
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';

magic_number([3, 7, 5], [9, 5, 7]);
magic_number([1, 2, 1], [5, 4, 4]);
magic_number([2], [5]);
magic_number([9, 10, 11, 12], [2, 1, 0, -1]);

sub magic_number {
    
    # show input
    say qq[\nInput: ] . sprintf('@x = (%s), @y = (%s)',
        join(', ', @{$_[0]}), join(', ', @{$_[1]}));
        
    # show output   
    say qq[Output: ] . 
        ([sort {$a <=> $b} @{$_[1]}]->[0] - 
         [sort {$a <=> $b} @{$_[0]}]->[0]);
}

6 lines of code

Output from script


Input: @x = (3, 7, 5), @y = (9, 5, 7)
Output: 2

Input: @x = (1, 2, 1), @y = (5, 4, 4)
Output: 3

Input: @x = (2), @y = (5)
Output: 3

Input: @x = (9, 10, 11, 12), @y = (2, 1, 0, -1)
Output: -10

 

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