Peter’s blog ✴ Week 269 ✴ 13 May 2024

THE WEEKLY CHALLENGE
Bits distribution

The Perl Camel

Task 2

Distribute elements

You are given an array of distinct integers, @ints.

Write a script to distribute the elements as described below:

  1. Put the 1st element of the given array in a new array @arr1.
  2. Put the 2nd element of the given array in a new array @arr2.

Once you have one element in each array @arr1 and @arr2, then follow the rule below:

If the last element of the array @arr1 is greater than the last element of the array @arr2 then add the next* element of the given array to @arr1 or otherwise to the array @arr2.

When done with the distribution, return the concatenated arrays @arr1 and @arr2.

* The task description says 'first' but it is clear from the examples that 'next' is intended.

Examples


Example 1
Input: @ints = (2, 1, 3, 4, 5)
Output: (2, 3, 4, 5, 1)
1st operation:
Add 1 to @arr1 = (2)
2nd operation:
Add 2 to @arr2 = (1)
3rd operation:
Now the last element of @arr1 is greater than the last 
element of @arr2, add 3 to @arr1 = (2, 3).
4th operation:
Again the last element of @arr1 is greate than the last 
element of @arr2, add 4 to @arr1 = (2, 3, 4)
5th operation:
Finally, the last element of @arr1 is again greater than 
the last element of @arr2, add 5 to @arr1 = (2, 3, 4, 5)
Now we have two arrays:
@arr1 = (2, 3, 4, 5)
@arr2 = (1)
Concatenate the two arrays and return the final array: 
(2, 3, 4, 5, 1).

Example 2
Input: @ints = (3, 2, 4)
Output: (3, 4, 2)
1st operation:
Add 1 to @arr1 = (3)
2nd operation:
Add 2 to @arr2 = (2)
3rd operation:
Now the last element of @arr1 is greater than the last 
element of @arr2, add 4 to @arr1 = (3, 4).
Now we have two arrays:
@arr1 = (3, 4)
@arr2 = (2)
Concatenate the two arrays and return the final array: 
(3, 4, 2).

Example 3
Input: @ints = (5, 4, 3 ,8)
Output: (5, 3, 4, 8)
1st operation:
Add 1 to @arr1 = (5)
2nd operation:
Add 2 to @arr2 = (4)
3rd operation:
Now the last element of @arr1 is greater than the last 
element of @arr2, add 3 to @arr1 = (5, 3).
4th operation:
Again the last element of @arr2 is greate than the last 
element of @arr1, add 8 to @arr2 = (4, 8)
Now we have two arrays:
@arr1 = (5, 3)
@arr2 = (4, 8)
Concatenate the two arrays and return the final array: 
(5, 3, 4, 8).

Analysis

There's probably some clever way of doing this in 1 or 2 lines, but I took the easy route of just following the task description.

Note that in order to have a single push in the do loop I first established a reference to the approriate array - $arr - and then dereferenced that to assign the next value to the appropriate @arr1 or @arr2.

Perl Weekly’s review

from PW issue 669

DIY Tool as always with engaging discussion. Highly recommended.

This review may cover either or both challenges for this week.

Try it 

Try running the script with any input:



example: 3, 1, 4, 1, 5, 9

Script


#!/usr/bin/perl

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

use v5.26;    # The Weekly Challenge - 2024-05-13
use utf8;     # Week 269 - task 2 - Distribute elements
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';

distribute_elements(2, 1, 3, 4, 5);
distribute_elements(3, 2, 4);
distribute_elements(5, 4, 3, 8);
distribute_elements(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
distribute_elements(10, 9, 8, 7, 6, 5, 4, 3, 2, 1);

sub distribute_elements {

    my (@ints, @arr1, @arr2, $j, $arr);

    @ints = @_;
    
    # push the first two elements of @ints onto @arr1 and @arr2
    ($arr1[0], $arr2[0]) = @ints[0 .. 1];
    $j = 2;
    
    # push subsequent elements of @ints onto @arr1 or @arr2 
    do {
        $arr = $arr1[-1] > $arr2[-1] ? \@arr1 : \@arr2;
        push @$arr, $ints[$j];
    } until ++ $j == @ints;
    
    printf(qq[\nInput:  \@ints = (%s)\n], join(', ', @ints));
    printf(qq[Output: (%s)\n], join(', ', (@arr1, @arr2)));
}

11 lines of code

Output from script


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

Input:  @ints = (3, 2, 4)
Output: (3, 4, 2)

Input:  @ints = (5, 4, 3, 8)
Output: (5, 3, 4, 8)

Input:  @ints = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Output: (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

Input:  @ints = (10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
Output: (10, 8, 6, 4, 2, 9, 7, 5, 3, 1)

 

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