Perl Weekly Challenge 264: Target Array
These are some answers to the Week 264, Task 2, of the Perl Weekly Challenge organized by Mohammad S. Anwar.
Spoiler Alert: This weekly challenge deadline is due in a few days from now (on April 14, 2024 at 23:59). This blog post provides some solutions to this challenge. Please don’t read on if you intend to complete the challenge on your own.
Task 2: Target Array
You are given two arrays of integers, @source
and @indices
. The @indices
can only contains integers 0 <= i < size of @source
.
Write a script to create target array by insert at index $indices[i]
the value $source[i]
.
Example 1
Input: @source = (0, 1, 2, 3, 4)
@indices = (0, 1, 2, 2, 1)
Output: (0, 4, 1, 3, 2)
@source @indices @target
0 0 (0)
1 1 (0, 1)
2 2 (0, 1, 2)
3 2 (0, 1, 3, 2)
4 1 (0, 4, 1, 3, 2)
Example 2
Input: @source = (1, 2, 3, 4, 0)
@indices = (0, 1, 2, 3, 0)
Output: (0, 1, 2, 3, 4)
@source @indices @target
1 0 (1)
2 1 (1, 2)
3 2 (1, 2, 3)
4 3 (1, 2, 3, 4)
0 0 (0, 1, 2, 3, 4)
Example 3
Input: @source = (1)
@indices = (0)
Output: (1)
The way the target array is constructed (as detailed in the examples) is somewhat weird, so that we cannot use array slices as I was originally hoping. We have to build the target array iteratively, item by item.
Also note that we are not told what to do if the @source
and @indices
arrays don't have the same size, so we will assume they have the same size.
Target Array in Raku
In order to built the target array in accordance with the rules explained in the examples, the easiest is to use the splice routine, which can add, remove or replace elements of an array. In this specific case, we don't remove or replace items of the array (this is why the third parameter of the splice
function call is set to 0), but just add one value at a time.
sub target-array (@source, @indices) {
my @target;
for 0..@source.end -> $i {
splice @target, @indices[$i], 0, @source[$i];
}
return @target;
}
my @tests = ( (0, 1, 2, 3, 4), (0, 1, 2, 2, 1) ),
( (1, 2, 3, 4, 0), (0, 1, 2, 3, 0) ),
( (1,), (0,) );
for @tests -> @test {
printf "%-10s - %-10s => ", "@test[0]", "@test[1]";
say target-array @test[0], @test[1];
}
This program displays the following output:
$ raku ./target-array.raku
0 1 2 3 4 - 0 1 2 2 1 => [0 4 1 3 2]
1 2 3 4 0 - 0 1 2 3 0 => [0 1 2 3 4]
1 - 0 => [1]
Target Array in Perl
This is a port to Perl of the above Raku program. For our practical purpose, Perl's splice
function behaves essentially the same way as Raku's splice
routine.
use strict;
use warnings;
use feature 'say';
sub target_array {
my @source = @{$_[0]};
my @indices = @{$_[1]};
my @target;
for my $i (0..$#source) {
splice @target, $indices[$i], 0, $source[$i];
}
return @target;
}
my @tests = ( [ [0, 1, 2, 3, 4], [0, 1, 2, 2, 1] ],
[ [1, 2, 3, 4, 0], [0, 1, 2, 3, 0] ],
[ [1,], [0,] ] );
for my $test (@tests) {
printf "%-10s - %-10s => ", "@{$test->[0]}", "@{$test->[1]}";
say join " ", target_array $test->[0], $test->[1];
}
This program displays the following output:
$ perl ./target-array.pl
0 1 2 3 4 - 0 1 2 2 1 => 0 4 1 3 2
1 2 3 4 0 - 0 1 2 3 0 => 0 1 2 3 4
1 - 0 => 1
Wrapping up
The next week Perl Weekly Challenge will start soon. If you want to participate in this challenge, please check https://perlweeklychallenge.org/ and make sure you answer the challenge before 23:59 BST (British summer time) on April 21, 2024. And, please, also spread the word about the Perl Weekly Challenge if you can.
Leave a comment