diff options
| author | Mohammad S Anwar <mohammad.anwar@yahoo.com> | 2020-08-14 23:51:20 +0100 |
|---|---|---|
| committer | Mohammad S Anwar <mohammad.anwar@yahoo.com> | 2020-08-14 23:51:20 +0100 |
| commit | 5630d4ba0b2fdd9762cbceb0f276811a5e4f469f (patch) | |
| tree | 865ea6dd9d6890fdb5ba26bc1472a962ed95637a /challenge-073 | |
| parent | 555ef839539023195076d37846e2a8baa4305b3b (diff) | |
| download | perlweeklychallenge-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.txt | 1 | ||||
| -rw-r--r-- | challenge-073/colin-crain/perl/ch-1.pl | 70 | ||||
| -rw-r--r-- | challenge-073/colin-crain/perl/ch-2.pl | 110 | ||||
| -rw-r--r-- | challenge-073/colin-crain/raku/ch-1.raku | 46 | ||||
| -rw-r--r-- | challenge-073/colin-crain/raku/ch-2.raku | 93 |
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; + + + |
