I’ve been doing the Perl Weekly
Challenges. The
latest
involved finding minima in subsets of lists.
1. Min Sliding Window
You are given an array of integers @A
and sliding window size $S
.
Write a script to create an array of min from each sliding window.
Example
Input: @A = (1, 5, 0, 2, 9, 3, 7, 6, 4, 8) and $S = 3
Output: (0, 0, 0, 2, 3, 3, 4, 4)
[(1 5 0) 2 9 3 7 6 4 8] = Min (0)
[1 (5 0 2) 9 3 7 6 4 8] = Min (0)
(etc.)
So the first thing I wanted was a fast minimum-finding function:
use List::Util qw(min);
(More people should use List::Util
; it's great.)
Then it's just a matter of array-slicing the input and storing the
result. No point in using a ring buffer for something this small.
sub msw {
my $a=shift;
my $s=shift;
my @out;
foreach my $i (0..(scalar @{$a})-$s) {
push @out,min(@{$a}[$i..$i+$s-1]);
}
return \@out;
}
Raku is the same except for the usual array fiddliness.
sub msw(@a,$s) {
my @out;
for (0..(@a.elems-$s)) -> $i {
push @out,min(@a[$i..$i+$s-1]);
}
return @out.flat;
}
2. Smallest Neighbour
You are given an array of integers @A
.
Write a script to create an array that represents the smaller
element to the left of each corresponding index. If none found then
use 0.
Er, what?
But the examples made this clearer: "For each element N, if any
element to the left of N is smaller than N, return the smallest of
them; otherwise, return 0".
I'd love to know why one might want to do this (as with mystery
stories, I like some narrative with my puzzle).
Anyway. List::Util
again, obviously. At each step through the list
we update the minimum value of all-entries-to-the-left (unlike problem
we never remove anything from consideration so the minimum can only
get lower), then push either that or zero onto the output. We
short-circuit the first step since it's always zero.
sub sn {
my $a=shift;
my @out=(0);
my $wm;
foreach my $i (1..$#{$a}) {
if (!defined $wm) {
$wm=$a->[$i-1];
} else {
$wm=min($wm,$a->[$i-1]);
}
if ($wm < $a->[$i]) {
push @out,$wm;
} else {
push @out,0;
}
}
return \@out;
}
And Raku is mostly identical.
Comments on this post are now closed. If you have particular grounds for adding a late comment, comment on a more recent post quoting the URL of this one.