Advent Calendar 2020
| Day 14 | Day 15 | Day 16 |
The gift is presented by Laurent Rosenfeld, the first champion of the weekly challenge. Today he is talking about his solution to the task Left Rotation
of “The Weekly Challenge - 078”. This is re-produced for Advent Calendar 2020 from the original post by Laurent Rosenfeld.
Left Rotation
You are given array @A
containing positive numbers and @B
containing one or more indices from the array @A
.
Write a script to left rotate @A
so that the number at the first index of @B
becomes the first element in the array. Similary, left rotate @A
again so that the number at the second index of @B
becomes the first element in the array.
Example 1:
Input:
@A = (10 20 30 40 50)
@B = (3 4)
Explanation:
a) We left rotate the 3rd index element (40) in the @A to make it 0th index member in the array.
[40 50 10 20 30]
b) We left rotate the 4th index element (50) in the @A to make it 0th index member in the array.
[50 10 20 30 40]
Output:
[40 50 10 20 30]
[50 10 20 30 40]
Example 2:
Input:
@A = (7 4 2 6 3)
@B = (1 3 4)
Explanation:
a) We left rotate the 1st index element (4) in the @A to make it 0th index member in the array.
[4 2 6 3 7]
b) We left rotate the 3rd index element (6) in the @A to make it 0th index member in the array.
[6 3 7 4 2]
c) We left rotate the 4th index element (3) in the @A to make it 0th index member in the array.
[3 7 4 2 6]
Output:
[4 2 6 3 7]
[6 3 7 4 2]
[3 7 4 2 6]
Left Rotation in Raku
We can simply use array slices to get what we need. The only slight difficulty is that we need to flatten the two index slices into a single list.
use v6;
my @a = 10, 20, 30, 40, 50;
my @indices = 3, 4;
say "Input array: ", @a;
for @indices -> $i {
my @out = @a[($i..@a.end, 0..$i -1).flat];
say @out;
}
Output:
$ raku left_rotate.raku
Input array: [10 20 30 40 50]
[40 50 10 20 30]
[50 10 20 30 40]
Left Rotation in Perl
Again, we use array slices. Here, the only slight difficulty is the relatively heavy use of nested array references.
use strict;
use warnings;
use feature "say";
my @a = ( [[10, 20, 30, 40, 50],[3, 4]],
[[7, 4, 2, 6, 3], [1, 3, 4]] );
left_rotate($_) for @a;
sub left_rotate {
my $inref = shift;
my ($in, $indices) = @$inref;
say "\nInput array: @$in - Indices: @$indices";
for my $i (@$indices){
my @out = @$in[$i..$#{$in}, 0..$i -1];
say "@out";
}
}
Output:
$ perl left_rotate.pl
Input array: 10 20 30 40 50 - Indices: 3 4
40 50 10 20 30
50 10 20 30 40
Input array: 7 4 2 6 3 - Indices: 1 3 4
4 2 6 3 7
6 3 7 4 2
3 7 4 2 6
If you have any suggestion then please do share with us perlweeklychallenge@yahoo.com.