aboutsummaryrefslogtreecommitdiff
path: root/challenge-073
diff options
context:
space:
mode:
authorMohammad S Anwar <mohammad.anwar@yahoo.com>2020-08-14 23:51:20 +0100
committerMohammad S Anwar <mohammad.anwar@yahoo.com>2020-08-14 23:51:20 +0100
commit5630d4ba0b2fdd9762cbceb0f276811a5e4f469f (patch)
tree865ea6dd9d6890fdb5ba26bc1472a962ed95637a /challenge-073
parent555ef839539023195076d37846e2a8baa4305b3b (diff)
downloadperlweeklychallenge-club-5630d4ba0b2fdd9762cbceb0f276811a5e4f469f.tar.gz
perlweeklychallenge-club-5630d4ba0b2fdd9762cbceb0f276811a5e4f469f.tar.bz2
perlweeklychallenge-club-5630d4ba0b2fdd9762cbceb0f276811a5e4f469f.zip
- Added solutions by Colin Crain.
Diffstat (limited to 'challenge-073')
-rw-r--r--challenge-073/colin-crain/blog.txt1
-rw-r--r--challenge-073/colin-crain/perl/ch-1.pl70
-rw-r--r--challenge-073/colin-crain/perl/ch-2.pl110
-rw-r--r--challenge-073/colin-crain/raku/ch-1.raku46
-rw-r--r--challenge-073/colin-crain/raku/ch-2.raku93
5 files changed, 320 insertions, 0 deletions
diff --git a/challenge-073/colin-crain/blog.txt b/challenge-073/colin-crain/blog.txt
new file mode 100644
index 0000000000..ba0424382b
--- /dev/null
+++ b/challenge-073/colin-crain/blog.txt
@@ -0,0 +1 @@
+https://colincrain.wordpress.com/2020/08/15/open-the-window-just-a-little-bit-so-your-smallest-smaller-neighbor-can-get-in/
diff --git a/challenge-073/colin-crain/perl/ch-1.pl b/challenge-073/colin-crain/perl/ch-1.pl
new file mode 100644
index 0000000000..370ad1ca0c
--- /dev/null
+++ b/challenge-073/colin-crain/perl/ch-1.pl
@@ -0,0 +1,70 @@
+#! /opt/local/bin/perl
+#
+# open-the-window-a-little-bit.pl
+#
+# 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)
+#
+#
+# method:
+#
+# array slices to the rescue! Iterate over 0 to (last - window size)
+# find min and push to output array.
+#
+# 2020 colin crain
+## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
+
+
+
+use warnings;
+use strict;
+use feature ":5.26";
+
+## ## ## ## ## MAIN:
+
+
+my ($S, @A) = @ARGV;
+
+# $S = 3;
+# @A = (1, 5, 0, 2, 9, 3, 7, 6, 4, 8);
+
+my $end = @A - $S;
+my @output;
+
+for ( 0..$end ){
+ my $min = minimum( @A[$_..$_+$S-1] );
+ push @output, $min;
+}
+
+
+say "input: @A window size $S";
+say "output: @output";
+
+## ## ## ## ## SUBS:
+
+sub minimum {
+ my $min = "inf";
+ $_ < $min and $min = $_ for @_;
+ return $min;
+}
+
+
+
+
diff --git a/challenge-073/colin-crain/perl/ch-2.pl b/challenge-073/colin-crain/perl/ch-2.pl
new file mode 100644
index 0000000000..20e2066a77
--- /dev/null
+++ b/challenge-073/colin-crain/perl/ch-2.pl
@@ -0,0 +1,110 @@
+#! /opt/local/bin/perl
+#
+# smallest_smaller_neighbor.pl
+#
+# TASK #2 › Smallest (Smaller) 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]
+# is none, so we put 0.
+# For index 1, the smallest number to the left of $A[1]
+# in (7), is 7 so we put 7.
+# For index 2, the smallest number to the left of $A[2]
+# in (7, 8) is none, so we put 0.
+# For index 3, the smallest number to the left of $A[3]
+# in (7, 8, 3) is 3, so we put 3.
+# For index 4, the smallest number to the left of $A[4]
+# is (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]
+# in (4) is 4, so we put 4.
+# For index 2, the smallest number to the left of $A[2]
+# in (4, 6) is 4, so we put 4 again.
+#
+# method:
+# smallest neighbor is a confusing title, as we are not
+# looking for the smallest element to the left of a
+# given index, but rather the smallest element to the
+# left of the index that is smaller than that element.
+# Or stated another way, the minimum item of the slice
+# A[0..$i-1] that is less than A[$i]. When we put it
+# like that the challenge really resembles the
+# previous, only the size of the window is dynamic and
+# there is some additional comparison going on. But the
+# process is very similar: iterate acrosss the field,
+# selecting a slice for each index, and determine the
+# minimum value within that slice. Instead of just
+# taking the minimum value, though, in the case we can
+# add some additional processing in the function
+# called.
+#
+# As there are never any elements to the left of index
+# 0, the first digit will always be 0 and hence can be
+# inserted from the get-go. After that, starting at
+# index 1, the slice from 0 to the current index is
+# passed to our smallest_neighbor function, where the
+# indexed value immediately popped off the end. The
+# minimum of the remaining slice is found, and if that
+# value is less than the index value it is returned,
+# else 0. There is no need to make more than one pass
+# over the list, as the minimum will be the minimum no
+# matter its value.
+#
+# As 0 is a real value that is right in the middle of
+# the potential range (as negative values are not
+# disallowed), using it to label a target miss could be
+# a bit confusing. With that in mind i have taken the
+# liberty to substitute the null set sign '∅' instead,
+# which looks a lot like '0' in my preferred font, but
+# isn't, as it makes understanding what's happening
+# just a little bit easier.
+#
+# 2020 colin crain
+## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
+
+
+
+use warnings;
+use strict;
+use feature ":5.26";
+
+## ## ## ## ## MAIN:
+
+my @input = @ARGV;
+@input = (7, 8, -3, 12, -10);
+my @output = ('∅');
+
+for (1..@input-1) {
+ my @slice = @input[0..$_];
+ my $smallest = smallest_neighbor( @slice );
+ push @output, $smallest;
+}
+
+say "Input: @input";
+say "Output: ", join ', ', @output;
+
+## ## ## ## ## SUBS:
+
+sub smallest_neighbor {
+## find the minimum value to the left and return it if
+## min < given value, else 0
+ my $value = pop @_;
+ my $min = "inf";
+ $_ < $min and $min = $_ for @_;
+ $min < $value ? $min : '∅';
+} \ No newline at end of file
diff --git a/challenge-073/colin-crain/raku/ch-1.raku b/challenge-073/colin-crain/raku/ch-1.raku
new file mode 100644
index 0000000000..810f075bf0
--- /dev/null
+++ b/challenge-073/colin-crain/raku/ch-1.raku
@@ -0,0 +1,46 @@
+#!/usr/bin/env perl6
+#
+#
+# open-the-window.raku
+#
+# 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)
+#
+#
+#
+# 2020 colin crain
+## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
+
+
+
+unit sub MAIN (Int $S where $S > 0 = 3, *@A );
+
+## default array
+@A = 1, 5, 0, 2, 9, 3, 7, 6, 4, 8 if @A.elems == 0;
+
+## make windows and find min within each to output
+my @windows = @A.rotor($S=>-$S+1);
+my @output = @windows.map( *.min );
+
+## output
+say "input: ", @A, " window size $S";
+say "windows: ", |@windows;
+say "output: ", @output;
+
diff --git a/challenge-073/colin-crain/raku/ch-2.raku b/challenge-073/colin-crain/raku/ch-2.raku
new file mode 100644
index 0000000000..2b0cb747a9
--- /dev/null
+++ b/challenge-073/colin-crain/raku/ch-2.raku
@@ -0,0 +1,93 @@
+#!/usr/bin/env perl6
+#
+#
+# smallest_smaller_neighbor.raku
+#
+# TASK #2 › Smallest (Smaller) 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]
+# is none, so we put 0.
+# For index 1, the smallest number to the left of $A[1]
+# in (7), is 7 so we put 7.
+# For index 2, the smallest number to the left of $A[2]
+# in (7, 8) is none, so we put 0.
+# For index 3, the smallest number to the left of $A[3]
+# in (7, 8, 3) is 3, so we put 3.
+# For index 4, the smallest number to the left of $A[4]
+# is (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]
+# in (4) is 4, so we put 4.
+# For index 2, the smallest number to the left of $A[2]
+# in (4, 6) is 4, so we put 4 again.
+#
+# method:
+#
+# smallest neighbor is a confusing title, as we are not
+# looking for the smallest element to the left of a
+# given index, but rather the smallest element to the
+# left of the index that is smaller than that at the index.
+#
+# “triangular comma” produces a list of lists, each with
+# one more element of the original array appended. Which,
+# incidentally, is exactly what we need. Well almost,
+# because each element is a list, rather than an array.
+# By coercing it as such before we hand it off to our
+# smallest_neighbor() sub we can then pop off the
+# rightmost value and compute the output from there,
+# using min and a comparison check to see whether the
+# value of the minimum is less than the last element.
+#
+# As 0 is a real value that is right in the middle of
+# the potential range (as negative values are not
+# disallowed), using it to label a target miss could be
+# a bit confusing. With that in mind I have taken the
+# liberty to substitute the null set sign '∅',
+# which looks a lot like '0' in my preferred font, but
+# isn't, as it makes understanding what's happening
+# just a little bit easier.
+
+
+# 2020 colin crain
+## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ##
+
+
+
+unit sub MAIN () ;
+
+my @input = 7, 8, 3, 12, 10;
+my @output;
+
+for [\,] @input { ## triangular comma
+ push @output, smallest_neighbor( $_.Array ); # $_ is List
+}
+
+sub smallest_neighbor( @slice ) {
+## find the minimum value to the left of last value not inclusive
+## return it if less than last, else ∅
+ my $val = @slice.pop;
+ my $min = @slice.min;
+ $min < $val ?? $min !! '∅';
+}
+
+@input .say;
+@output.say;
+
+
+