Peter’s blog ✴ Week 240 ✴ 23 October 2023

THE WEEKLY CHALLENGE
Initialisms and contorted arrays

The Perl Camel

Task 2

Build array

You are given an array of integers. Write a script to create an array such that new[i] = old[old[i]] where 0 <= i < new.length.

Examples


Example 1
Input: @int = (0, 2, 1, 5, 3, 4)
Output: (0, 1, 2, 4, 5, 3)

Example 2
Input: @int = (5, 0, 1, 2, 3, 4)
Output: (4, 5, 0, 1, 2, 3)

Analysis

The essence of this task is in the task statement: it is only necessary to evaluate:

$new[$_] = $old[$old[$_]] for (0 .. @old - 1)

This task can only be done for certain arrays, that is, arrays containing all the integers from 0 to (length - 1) in any order. So I check for that by sorting @old, checking that $old[0] is zero and every other $old[$i] equals old[$i - 1] + 1.

I am sorry that the 'Try it' feature is currently working very slowly or not at all owing to some issue with my web hosting provider.

Try it 

Try running the script with any input:



example: 0, 2, 1, 5, 3, 4

Script


#!/usr/bin/perl

use v5.16;    # The Weekly Challenge - 2023-10-23
use utf8;     # Week 240 task 2 - Build array
use strict;   # Peter Campbell Smith
use warnings; # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge

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

sub build_array {
    
    my (@old, @new, $last, @check, $good);
    
    # need to make sure the task is possible
    @old = @_;
    $last = @old - 1;
    @check = sort {$a <=> $b} @old;
    $good = $check[0] == 0;
    $good &= $check[$_] == $check[$_ - 1] + 1 for (1 .. $last);
    
    # show results
    say qq[\nInput:  \@old = (] . join(q[, ], @old) . q[)];
    if ($good) {
        $new[$_] = $old[$old[$_]] for (0 .. $last);
        say qq[Output: \@new = (] . join(', ', @new) . ')';

    } else {
        say qq[Output: impossible];
    }
}
    

13 lines of code

Output from script



Input:  @old = (0, 2, 1, 5, 3, 4)
Output: @new = (0, 1, 2, 4, 5, 3)

Input:  @old = (5, 0, 1, 2, 3, 4)
Output: @new = (4, 5, 0, 1, 2, 3)

Input:  @old = (5, 6, 1, 2, 3, 4)
Output: impossible

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


 

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