aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPerlMonk Athanasius <PerlMonk.Athanasius@gmail.com>2020-08-14 04:41:57 -0700
committerPerlMonk Athanasius <PerlMonk.Athanasius@gmail.com>2020-08-14 04:41:57 -0700
commit939fffbc1b487b5cad792159b5cc829dcef4c630 (patch)
treed00b1e97eefe0ef3d0ab14bb401a5ac79ad9b092
parent2bdced5426c2957b7baeed1c4a4bba793ea93372 (diff)
downloadperlweeklychallenge-club-939fffbc1b487b5cad792159b5cc829dcef4c630.tar.gz
perlweeklychallenge-club-939fffbc1b487b5cad792159b5cc829dcef4c630.tar.bz2
perlweeklychallenge-club-939fffbc1b487b5cad792159b5cc829dcef4c630.zip
Perl & Raku solutions to Tasks 1 & 2 of the Perl Weekly Challenge #073
On branch branch-for-challenge-073 Changes to be committed: new file: challenge-073/athanasius/perl/ch-1.pl new file: challenge-073/athanasius/perl/ch-2.pl new file: challenge-073/athanasius/raku/ch-1.raku new file: challenge-073/athanasius/raku/ch-2.raku
-rw-r--r--challenge-073/athanasius/perl/ch-1.pl106
-rw-r--r--challenge-073/athanasius/perl/ch-2.pl145
-rw-r--r--challenge-073/athanasius/raku/ch-1.raku78
-rw-r--r--challenge-073/athanasius/raku/ch-2.raku131
4 files changed, 460 insertions, 0 deletions
diff --git a/challenge-073/athanasius/perl/ch-1.pl b/challenge-073/athanasius/perl/ch-1.pl
new file mode 100644
index 0000000000..0fb9a24dcf
--- /dev/null
+++ b/challenge-073/athanasius/perl/ch-1.pl
@@ -0,0 +1,106 @@
+#!perl
+
+################################################################################
+=comment
+
+Perl Weekly Challenge 073
+=========================
+
+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)
+
+=cut
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2020 PerlMonk Athanasius #
+#--------------------------------------#
+
+use strict;
+use warnings;
+use Const::Fast; # Exports const()
+use Getopt::Long; # Exports GetOptions()
+use List::Util qw( min );
+use PerlX::Window; # Exports window() and @window
+use Regexp::Common qw( number ); # Exports %RE{num}
+
+const my $USAGE =>
+"Usage:
+ perl $0 [-S <Natural>] [-A <Int> +]
+
+ -S <Natural> Sliding window size: 0 < S <= integers in A
+ -A <Int> + Sequence of one or more integers\n";
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 073, Task #1: Min Sliding Window (Perl)\n\n";
+}
+
+#===============================================================================
+MAIN:
+#===============================================================================
+{
+ my ($S, @A) = parse_command_line();
+
+ printf "Input: \@A = (%s) and \$S = %d\n", join(', ', @A), $S;
+
+ my @minima;
+ push @minima, min(@window) while window(@A, $S);
+
+ printf "Output: (%s)\n", join(', ', @minima);
+}
+
+#-------------------------------------------------------------------------------
+sub parse_command_line
+#-------------------------------------------------------------------------------
+{
+ my ($S, @A);
+
+ GetOptions
+ (
+ 'S=i' => \$S,
+ 'A=i{1,}' => \@A,
+ ) or die $USAGE;
+
+ scalar @ARGV == 0 or die $USAGE;
+ is_int($S) && $S > 0 or die $USAGE;
+ is_int($_) or die $USAGE for @A;
+ $S <= scalar @A or die $USAGE;
+
+ return ($S, @A);
+}
+
+#-------------------------------------------------------------------------------
+sub is_int
+#-------------------------------------------------------------------------------
+{
+ my ($n) = @_;
+
+ return defined($n) && $n =~ / \A $RE{num}{int} \z /x;
+}
+
+################################################################################
diff --git a/challenge-073/athanasius/perl/ch-2.pl b/challenge-073/athanasius/perl/ch-2.pl
new file mode 100644
index 0000000000..a62a6dec8e
--- /dev/null
+++ b/challenge-073/athanasius/perl/ch-2.pl
@@ -0,0 +1,145 @@
+#!perl
+
+################################################################################
+=comment
+
+Perl Weekly Challenge 073
+=========================
+
+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 smaller 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.
+
+=cut
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2020 PerlMonk Athanasius #
+#--------------------------------------#
+
+use strict;
+use warnings;
+use Const::Fast; # Exports const()
+use Regexp::Common qw( number ); # Exports %RE
+
+const my $USAGE =>
+"Usage:
+ perl $0 [<A> ...]
+
+ [<A> ...] Sequence of one or more integers\n";
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ $| = 1;
+ print "\nChallenge 073, Task #2: Smallest Neighbour (Perl)\n\n";
+}
+
+#===============================================================================
+MAIN:
+#===============================================================================
+{
+ my @A = parse_command_line();
+ my @out = (0); # The first element has no left-hand neighbours
+ # and so is always 0
+ my $min = $A[0]; # In the loop below, $min contains the smallest
+ # of the elements with index 0 .. $i-1
+
+ # For each element $A[$i] after the first: record the minimum of the ele-
+ # ments with index 0..$i-1 IFF that minimum is less than $A[$i]; otherwise,
+ # record 0
+
+ for my $i (1 .. $#A)
+ {
+ my $current = $A[$i];
+
+ push @out, $min < $current ? $min : 0;
+
+ $min = $current if $current < $min; # Update $min for next iteration
+ }
+
+ print_arrays(\@A, \@out);
+}
+
+#-------------------------------------------------------------------------------
+sub parse_command_line
+#-------------------------------------------------------------------------------
+{
+ scalar @ARGV > 0 or die $USAGE;
+
+ / \A $RE{num}{int} \z /x or die $USAGE for @ARGV;
+
+ return @ARGV;
+}
+
+#-------------------------------------------------------------------------------
+sub print_arrays
+#-------------------------------------------------------------------------------
+{
+ my ($input, $output) = @_;
+ my @widths;
+
+ # Calculate the print width for each element to facilitate vertical align-
+ # ment of corresponding elements in the input and output sequences
+
+ for my $i (0 .. $#$input)
+ {
+ my $len_in = length $input ->[$i];
+ my $len_out = length $output->[$i];
+
+ push @widths, $len_in > $len_out ? $len_in : $len_out;
+ }
+
+ # Print the input and output sequences
+
+ for my $args (['Input: @A =', $input ],
+ ['Output:', $output])
+ {
+ my $array = $args->[1];
+
+ printf "%-11s (%s)\n",
+ $args->[0],
+ join ', ', map
+ {
+ sprintf '%*d', $widths[$_], $array->[$_]
+
+ } 0 .. $#$array;
+ }
+}
+
+################################################################################
diff --git a/challenge-073/athanasius/raku/ch-1.raku b/challenge-073/athanasius/raku/ch-1.raku
new file mode 100644
index 0000000000..52526279a3
--- /dev/null
+++ b/challenge-073/athanasius/raku/ch-1.raku
@@ -0,0 +1,78 @@
+use v6d;
+
+################################################################################
+=begin comment
+
+Perl Weekly Challenge 073
+=========================
+
+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)
+
+=end comment
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2020 PerlMonk Athanasius #
+#--------------------------------------#
+
+subset Natural of UInt where * > 0;
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ "\nChallenge 073, Task #1: Min Sliding Window (Raku)\n".put;
+}
+
+#===============================================================================
+sub MAIN
+(
+ Natural:D :$S, #= Sliding window size: 0 < S <= integers in A
+
+ *@A where { @A.elems > 0 && #= Sequence of one or more integers
+ @A.elems >= $S &&
+ @A.all ~~ Int:D }
+)
+#===============================================================================
+{
+ "Input: @A = (%s) and \$S = %d\n".printf: @A.join(', '), $S;
+
+ my Int @minima;
+ @minima.push: min @A[$_ .. $_ + $S - 1] for 0 .. @A.elems - $S;
+
+ "Output: (%s)\n".printf: @minima.join: ', ';
+}
+
+#-------------------------------------------------------------------------------
+sub USAGE()
+#-------------------------------------------------------------------------------
+{
+ my Str $usage = $*USAGE;
+
+ $usage ~~ s/ ($*PROGRAM-NAME) /raku $0/;
+ $usage.put;
+}
+
+################################################################################
diff --git a/challenge-073/athanasius/raku/ch-2.raku b/challenge-073/athanasius/raku/ch-2.raku
new file mode 100644
index 0000000000..df2f74d872
--- /dev/null
+++ b/challenge-073/athanasius/raku/ch-2.raku
@@ -0,0 +1,131 @@
+use v6d;
+
+################################################################################
+=begin comment
+
+Perl Weekly Challenge 073
+=========================
+
+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 smaller 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.
+
+=end comment
+################################################################################
+
+#--------------------------------------#
+# Copyright © 2020 PerlMonk Athanasius #
+#--------------------------------------#
+
+#-------------------------------------------------------------------------------
+BEGIN
+#-------------------------------------------------------------------------------
+{
+ "\nChallenge 073, Task #2: Smallest Neighbour (Raku)\n".put;
+}
+
+#===============================================================================
+sub MAIN
+(
+ *@A where { @A.elems > 0 && #= Sequence of one or more integers
+ @A.all ~~ Int:D }
+)
+#===============================================================================
+{
+ my Int @out = (0); # The first element has no left-hand neighbours
+ # and so is always 0
+ my Int $min = @A[0]; # In the loop below, $min contains the smallest
+ # of the elements with index 0 .. $i-1
+
+ # For each element @A[$i] after the first: record the minimum of the ele-
+ # ments with index 0..$i-1 IFF that minimum is less than @A[$i]; otherwise,
+ # record 0
+
+ for 1 .. @A.end -> UInt $i
+ {
+ my Int $current = @A[$i];
+
+ @out.push: $min < $current ?? $min !! 0;
+
+ $min = $current if $current < $min; # Update $min for next iteration
+ }
+
+ print-arrays(@A, @out);
+}
+
+#-------------------------------------------------------------------------------
+sub USAGE()
+#-------------------------------------------------------------------------------
+{
+ my Str $usage = $*USAGE;
+
+ $usage ~~ s/ ($*PROGRAM-NAME) /raku $0/;
+ $usage.put;
+}
+
+#-------------------------------------------------------------------------------
+sub print-arrays(Array:D[Int:D] $input, Array:D[Int:D] $output)
+#-------------------------------------------------------------------------------
+{
+ my UInt @widths;
+
+ # Calculate the print width for each element to facilitate vertical align-
+ # ment of corresponding elements in the input and output sequences
+
+ for 0 .. $input.end -> UInt $i
+ {
+ my $len_in = $input[$i].chars;
+ my $len_out = $output[$i].chars;
+
+ @widths.push: $len_in > $len_out ?? $len_in !! $len_out;
+ }
+
+ # Print the input and output sequences
+
+ for ['Input: @A =', $input ],
+ ['Output:', $output] -> @args
+ {
+ my @array = @args[1].list;
+
+ "%-11s (%s)\n".printf:
+ @args[0],
+ (0 .. @array.end).map( { '%*d'.sprintf: @widths[$_], @array[$_] } )
+ .join: ', ';
+ }
+}
+
+################################################################################