ETOOBUSY 🚀 minimal blogging for the impatient
PWC - Left Rotation
TL;DR
The solution to task #2 of the Perl Weekly Challenge for this week, and additional reflections.
In last post Leader element I shared a trivial thought about how the Perl Weekly Challenge tasks can be a good excercise for thinking about the problems beyond providing a quick answer for them.
This is also the case for the task #2 in this week’s challenge:
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.
My solution is pretty straightforward (most is scaffolding for testing):
1 #!/usr/bin/env perl
2 use 5.024;
3 use warnings;
4 use experimental qw< postderef signatures >;
5 no warnings qw< experimental::postderef experimental::signatures >;
6
7 sub shift_left_by ($n, @A) { (@A[$n..$#A], @A[0..($n-1)]) }
8 sub shift_left ($A, $B) { map { [shift_left_by($_, $A->@*)] } $B->@* }
9
10 for my $test (
11 [
12 'first test',
13 [qw< 10 20 30 40 50 >],
14 [qw< 3 4 >],
15 ],
16 [
17 'second test',
18 [qw< 7 4 2 6 3 >],
19 [qw< 1 3 4 >]
20 ],
21 ) {
22 my ($title, $A, $B) = $test->@*;
23 say {*STDERR} $title;
24 say {*STDOUT} '[', join(', ', $_->@*), ']' for shift_left($A, $B);
25 }
Function shift_left
iterates over the indexes in $B
(which is a
reference to @B
) and calls the actual left-shifting function
shift_left_by
. This, in turn, takes the relevant parts out of the
array and arranges them as requested.
There’s a lot that might be discussed, e.g.:
- this solution assumes that it’s OK to create copies of the
@A
array around, which should be double checked; - it might be interesting to understand whether a solution that “starts
from the previous iteration” might go better (e.g. speed-wise) with
respect to this, especially if we’re not allowed to make copies of
@A
but have to do the shifting in-place (in this case, we would have to do some moduloscalar(@A)
arithmetic over the indices in@B
); - what should the functions/script do in case of wrong inputs (e.g. an
index in
@B
that is not present in@A
).
Cheers!