Peter’s blog ✴ Week 186 ✴ 10 October 2022

THE WEEKLY CHALLENGE
Merge like a zip and Unidecode

The Perl Camel

Task 1

Zip list

You are given two lists @a and @b of the same size. Create a subroutine sub zip(@a, @b) that merge the two list as shown in the example below.

Examples

Example
Input:  @a = qw/1 2 3/; @b = qw/a b c/;
Output: zip(@a, @b) should return qw/1 a 2 b 3 c/;
        zip(@b, @a) should return qw/a 1 b 2 c 3/;

Analysis

Travelling in New Zealand we noticed that when two lanes of traffic merge into one, the road sign says 'Merge like a zip'. And that's what's needed here.

This could be achieved in a single line, but it would be a rather messy one, hard to understand or maintain. So let's not.

As stated, zip(@a, @b) will create a single array @_ which is the concatenation of @a and @b. Lets' start by splitting that into the two equal length @a and @b. We can then create the desired output as:

push @result, $a[$_], $b[$_] for 0 .. @a - 1;

And that's it.

Perl Weekly’s review

from PW issue 586

Smart hack and clever solutions to both the tasks. Loved it. Thank you.

Try it 

Try running the script with any input:



example: 1, 3, 5



example: 2, 4, 6

Script


#!/usr/bin/perl

# Peter Campbell Smith - 2022-10-10
# PWC 186 task 1

use v5.28;
use utf8;
use warnings;
binmode(STDOUT, ':utf8');

zip(qw/1 2 3/, qw/a b c/);
zip(qw/c r e t a s e/, qw/o r c - n w r/);

sub zip {
    
    my (@a, @b, $n, @result);
    
    # create output
    $n = @_ / 2;
    @a = @_[0 .. $n - 1];
    @b = @_[$n .. @_ - 1];
    push @result, $a[$_], $b[$_] for 0 .. @a - 1;
    
    # print it
    say qq[\nInput:  (] . join(', ', @a) . qq[), (] . join(', ', @b) . qq[)];
    say qq[Output: (] . join(', ', @result)  . ')';
}

8 lines of code

Output from script


Input:  (1, 2, 3), (a, b, c)
Output: (1, a, 2, b, 3, c)

Input:  (c, r, e, t, a, s, e), (o, r, c, -, n, w, r)
Output: (c, o, r, r, e, c, t, -, a, n, s, w, e, r)

 

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