PERL WEEKLY CHALLENGE – 073

This is my 43rd week participating into the weekly challenge.



TASK #1 › Min Sliding Window

Submitted by: Mohammad S Anwar

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)
[1 5 (0 2 9) 3 7 6 4 8] = Min (0)
[1 5 0 (2 9 3) 7 6 4 8] = Min (2)
[1 5 0 2 (9 3 7) 6 4 8] = Min (3)
[1 5 0 2 9 (3 7 6) 4 8] = Min (3)
[1 5 0 2 9 3 (7 6 4) 8] = Min (4)
[1 5 0 2 9 3 7 (6 4 8)] = Min (4)

I didn’t have time for the challenge this week.

For the first challenge it was just a matter of iterating through the array and and finding the min value. I used Perl’s List::Util and Raku’s native min function to do the dirty work.

Perl 5 solution

#!/usr/bin/perl
# Test: ./ch-1.pl
use Modern::Perl;
use List::Util qw /min/;

my @out;
my @A = (1, 5, 0, 2, 9, 3, 7, 6, 4, 8);
my $S = 3;

for my $i (2 .. scalar(@A) - 1) {
	push @out, min $A[$i], $A[$i - 1], $A[$i - 2];
}

say '(' . (join ', ', @out) . ')';

Output: perl ./ch-1.pl

(0, 0, 0, 2, 3, 3, 4, 4)

Raku solution

# Test: perl6 ch-1.p6
sub MAIN() {
	my @out;
	my @A = (1, 5, 0, 2, 9, 3, 7, 6, 4, 8);
	my $S = 3;

	for (2 .. @A.elems - 1) -> $i {
		push @out, min @A[$i], @A[$i - 1], @A[$i - 2];
	}

	say '(' ~ @out.join(", ") ~ ')';
}

Output perl6 ch-1.p6

(0, 0, 0, 2, 3, 3, 4, 4)

TASK #2 › Smallest Neighbour

Submitted by: Mohammad S Anwar

You are given an array of integers @A.

Write a script to create an array that represents the smallest element to the left of each corresponding index. If none found then use 0.

Example 1

Input: @A = (7, 8, 3, 12, 10)

Output: (0, 7, 0, 3, 3)

For index 0, the smallest number to the left of $A[0] i.e. 7 is none, so we put 0.
For index 1, the smallest number to the left of $A[1] as compare to 8, in (7) is 7 so we put 7.
For index 2, the smallest number to the left of $A[2] as compare to 3, in (7, 8) is none, so we put 0.
For index 3, the smallest number to the left of $A[3] as compare to 12, in (7, 8, 3) is 3, so we put 3.
For index 4, the smallest number to the left of $A[4] as compare to 10, in (7, 8, 3, 12) is 3, so we put 3 again.

Example 2

Input: @A = (4, 6, 5)

Output: (0, 4, 4)

For index 0, the smallest number to the left of $A[0] is none, so we put 0.
For index 1, the smallest number to the left of $A[1] as compare to 6, in (4) is 4, so we put 4.
For index 2, the smallest number to the left of $A[2] as compare to 5, in (4, 6) is 4, so we put 4 again.

For this task I just iterated through the array and kept track of the smallest neighbor to the left of the array


Perl 5 solution

#!/usr/bin/perl
# Test: ./ch-2.pl
use Modern::Perl;

say smallest_neighbor(7, 8, 3, 12, 10);
say smallest_neighbor(4, 6, 5);

sub smallest_neighbor {
	my @A = @_;
	my @out;
	my $smallest_so_far;

	for my $i (0 .. scalar(@A) - 1) {
		if ( defined($smallest_so_far) &&
		     $A[$i] > $smallest_so_far ) {
			push @out, $smallest_so_far;
		} else {
			push @out, 0;
		}

		$smallest_so_far = $A[$i]
			unless (defined($smallest_so_far));

		$smallest_so_far = $A[$i]
			if ($smallest_so_far > $A[$i]);
	}

	return '(' . (join ', ', @out) . ')';
}

Output ./ch-2.pl

(0, 7, 0, 3, 3)
(0, 4, 4)

Raku solution

# Test: perl6 ch-2.p6
sub MAIN() {
	say smallest-neighbor((7, 8, 3, 12, 10));
	say smallest-neighbor((4, 6, 5));
}

sub smallest-neighbor(@A) {
	my @out;
	my $smallest_so_far;

	for (0 .. @A.elems - 1) -> $i {
		if ( defined($smallest_so_far) &&
		     @A[$i] > $smallest_so_far ) {
			@out.push($smallest_so_far);
		} else {
			@out.push(0);
		}
		
		$smallest_so_far = @A[$i]
			unless (defined($smallest_so_far));

		$smallest_so_far = @A[$i]
			if ($smallest_so_far > @A[$i]);
	}

	return '(' ~ @out.join(', ') ~ ')';
}

Output perl6 ch-2.p6

(0, 7, 0, 3, 3)
(0, 4, 4)

One thought on “PERL WEEKLY CHALLENGE – 073

Leave a comment