aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad S Anwar <mohammad.anwar@yahoo.com>2023-02-05 00:33:40 +0000
committerMohammad S Anwar <mohammad.anwar@yahoo.com>2023-02-05 00:33:40 +0000
commitbb49ce568aa7451728b149870379bbc8dbf6632d (patch)
tree7888c780378fb7442e135992e8ee171f57b89d01
parent8d9cfd8d2ac39bb5d0b0f7452bf57d200bbdd62f (diff)
parent1b765079cf83f8f6421d9b508cba813da02f07e0 (diff)
downloadperlweeklychallenge-club-bb49ce568aa7451728b149870379bbc8dbf6632d.tar.gz
perlweeklychallenge-club-bb49ce568aa7451728b149870379bbc8dbf6632d.tar.bz2
perlweeklychallenge-club-bb49ce568aa7451728b149870379bbc8dbf6632d.zip
Merge branch 'master' of https://github.com/manwar/perlweeklychallenge-club
-rw-r--r--challenge-202/arne-sommer/blog.txt1
-rwxr-xr-xchallenge-202/arne-sommer/raku/ch-1.raku28
-rwxr-xr-xchallenge-202/arne-sommer/raku/ch-2.raku43
-rwxr-xr-xchallenge-202/arne-sommer/raku/consecutive-odds28
-rwxr-xr-xchallenge-202/arne-sommer/raku/widest-valley56
-rwxr-xr-xchallenge-202/arne-sommer/raku/widest-valley-shorter43
-rw-r--r--challenge-202/carlos-oliveira/perl/ch-1.pl22
-rw-r--r--challenge-202/carlos-oliveira/perl/ch-2.pl45
-rw-r--r--challenge-202/jo-37/blog.txt1
-rw-r--r--challenge-202/jo-37/ch-202.md32
-rw-r--r--challenge-202/polettix/blog.txt1
-rw-r--r--challenge-202/polettix/blog1.txt1
-rw-r--r--challenge-202/polettix/perl/ch-1.pl33
-rw-r--r--challenge-202/polettix/perl/ch-2.pl49
-rw-r--r--challenge-202/polettix/raku/ch-1.raku31
-rw-r--r--challenge-202/polettix/raku/ch-2.raku47
16 files changed, 461 insertions, 0 deletions
diff --git a/challenge-202/arne-sommer/blog.txt b/challenge-202/arne-sommer/blog.txt
new file mode 100644
index 0000000000..6a16e391af
--- /dev/null
+++ b/challenge-202/arne-sommer/blog.txt
@@ -0,0 +1 @@
+https://raku-musings.com/odd-valleys.html
diff --git a/challenge-202/arne-sommer/raku/ch-1.raku b/challenge-202/arne-sommer/raku/ch-1.raku
new file mode 100755
index 0000000000..c38186afca
--- /dev/null
+++ b/challenge-202/arne-sommer/raku/ch-1.raku
@@ -0,0 +1,28 @@
+#! /usr/bin/env raku
+
+unit sub MAIN (*@array where @array.elems && all(@array) ~~ /^\-?<[0..9]>*$/, :v(:$verbose));
+
+my $consecutive = 0;
+my $start_index = 0;
+
+for ^@array.elems -> $i
+{
+ if (@array[$i] %% 2)
+ {
+ $consecutive = 0;
+ $start_index++;
+ }
+ else
+ {
+ $consecutive++;
+ }
+
+ if ($consecutive == 3)
+ {
+ say ":Consecutives: [{ @array[$start_index .. $start_index+2].join(",") }] starting at undex $start_index" if $verbose;
+ say 1;
+ exit;
+ }
+}
+
+say 0;
diff --git a/challenge-202/arne-sommer/raku/ch-2.raku b/challenge-202/arne-sommer/raku/ch-2.raku
new file mode 100755
index 0000000000..96d5a58b52
--- /dev/null
+++ b/challenge-202/arne-sommer/raku/ch-2.raku
@@ -0,0 +1,43 @@
+#! /usr/bin/env raku
+
+unit sub MAIN (*@array where @array.elems && all(@array) ~~ /^<[0..9]>*$/, :v(:$verbose));
+
+my @valleys;
+
+for ^@array.elems -> $start
+{
+ my @c = @array[$start..Inf].clone;
+
+ say ":Starting at offset $start; values [ { @c.join(",") } ]" if $verbose;
+
+ my @current = (@c.shift.Int,);
+
+ say ":First: @current[0]" if $verbose;
+
+ my $non-inc = True;
+
+ while (@c.elems)
+ {
+ my $curr = @c.shift.Int;
+
+ if $non-inc && $curr > @current.tail
+ {
+ $non-inc = False;
+ }
+ elsif ! $non-inc && $curr < @current.tail
+ {
+ @valleys.push: @current.clone;
+ @current = ();
+ last;
+ }
+
+ say ":Add: $curr ({ $non-inc ?? "!inc" !! "!desc" })" if $verbose;
+ @current.push: $curr;
+ }
+ @valleys.push: @current if @current.elems;
+}
+
+say ":Valleys: { @valleys.raku; }" if $verbose;
+say ":Widest: { @valleys>>.elems.max }" if $verbose;
+
+say @valleys.grep({ $_.elems == @valleys>>.elems.max }).first.join(", ");
diff --git a/challenge-202/arne-sommer/raku/consecutive-odds b/challenge-202/arne-sommer/raku/consecutive-odds
new file mode 100755
index 0000000000..c38186afca
--- /dev/null
+++ b/challenge-202/arne-sommer/raku/consecutive-odds
@@ -0,0 +1,28 @@
+#! /usr/bin/env raku
+
+unit sub MAIN (*@array where @array.elems && all(@array) ~~ /^\-?<[0..9]>*$/, :v(:$verbose));
+
+my $consecutive = 0;
+my $start_index = 0;
+
+for ^@array.elems -> $i
+{
+ if (@array[$i] %% 2)
+ {
+ $consecutive = 0;
+ $start_index++;
+ }
+ else
+ {
+ $consecutive++;
+ }
+
+ if ($consecutive == 3)
+ {
+ say ":Consecutives: [{ @array[$start_index .. $start_index+2].join(",") }] starting at undex $start_index" if $verbose;
+ say 1;
+ exit;
+ }
+}
+
+say 0;
diff --git a/challenge-202/arne-sommer/raku/widest-valley b/challenge-202/arne-sommer/raku/widest-valley
new file mode 100755
index 0000000000..e16312e61b
--- /dev/null
+++ b/challenge-202/arne-sommer/raku/widest-valley
@@ -0,0 +1,56 @@
+#! /usr/bin/env raku
+
+unit sub MAIN (*@array where @array.elems && all(@array) ~~ /^<[0..9]>*$/, :v(:$verbose));
+
+my @valleys;
+
+for ^@array.elems -> $start
+{
+ my @c = @array[$start..Inf].clone;
+
+ say ":Starting at offset $start; values [ { @c.join(",") } ]" if $verbose;
+
+ my @current = (@c.shift.Int,);
+
+ say ":First: @current[0]" if $verbose;
+
+ my $non-inc = True;
+
+ while (@c.elems)
+ {
+ my $curr = @c.shift.Int;
+
+ if $non-inc
+ {
+ if $curr <= @current.tail
+ {
+ ;
+ }
+ else
+ {
+ $non-inc = False;
+ }
+ }
+ else
+ {
+ if $curr >= @current.tail
+ {
+ ;
+ }
+ else
+ {
+ @valleys.push: @current.clone;
+ @current = ();
+ last;
+ }
+ }
+ say ":Add: $curr ({ $non-inc ?? "!inc" !! "!desc" })" if $verbose;
+ @current.push: $curr;
+ }
+ @valleys.push: @current if @current.elems;
+}
+
+say ":Valleys: { @valleys.raku; }" if $verbose;
+say ":Widest: { @valleys>>.elems.max }" if $verbose;
+
+say @valleys.grep({ $_.elems == @valleys>>.elems.max }).first.join(", ");
diff --git a/challenge-202/arne-sommer/raku/widest-valley-shorter b/challenge-202/arne-sommer/raku/widest-valley-shorter
new file mode 100755
index 0000000000..96d5a58b52
--- /dev/null
+++ b/challenge-202/arne-sommer/raku/widest-valley-shorter
@@ -0,0 +1,43 @@
+#! /usr/bin/env raku
+
+unit sub MAIN (*@array where @array.elems && all(@array) ~~ /^<[0..9]>*$/, :v(:$verbose));
+
+my @valleys;
+
+for ^@array.elems -> $start
+{
+ my @c = @array[$start..Inf].clone;
+
+ say ":Starting at offset $start; values [ { @c.join(",") } ]" if $verbose;
+
+ my @current = (@c.shift.Int,);
+
+ say ":First: @current[0]" if $verbose;
+
+ my $non-inc = True;
+
+ while (@c.elems)
+ {
+ my $curr = @c.shift.Int;
+
+ if $non-inc && $curr > @current.tail
+ {
+ $non-inc = False;
+ }
+ elsif ! $non-inc && $curr < @current.tail
+ {
+ @valleys.push: @current.clone;
+ @current = ();
+ last;
+ }
+
+ say ":Add: $curr ({ $non-inc ?? "!inc" !! "!desc" })" if $verbose;
+ @current.push: $curr;
+ }
+ @valleys.push: @current if @current.elems;
+}
+
+say ":Valleys: { @valleys.raku; }" if $verbose;
+say ":Widest: { @valleys>>.elems.max }" if $verbose;
+
+say @valleys.grep({ $_.elems == @valleys>>.elems.max }).first.join(", ");
diff --git a/challenge-202/carlos-oliveira/perl/ch-1.pl b/challenge-202/carlos-oliveira/perl/ch-1.pl
new file mode 100644
index 0000000000..6094ad697e
--- /dev/null
+++ b/challenge-202/carlos-oliveira/perl/ch-1.pl
@@ -0,0 +1,22 @@
+use strict;
+use warnings;
+use v5.36;
+
+use List::MoreUtils qw(slideatatime all);
+use Const::Fast;
+
+sub has_three_consecutive_odds {
+ const my $step_size => 1;
+ const my $window_size => 3;
+ my $it = slideatatime $step_size, $window_size, @_;
+ my @vals;
+ while (@vals = $it->() and @vals == $window_size) {
+ return 1 if all { $_ % 2 } @vals;
+ }
+ return 0;
+}
+
+say has_three_consecutive_odds 1, 5, 3, 6;
+say has_three_consecutive_odds 2, 6, 3, 5;
+say has_three_consecutive_odds 1, 2, 3, 4;
+say has_three_consecutive_odds 2, 3, 5, 7;
diff --git a/challenge-202/carlos-oliveira/perl/ch-2.pl b/challenge-202/carlos-oliveira/perl/ch-2.pl
new file mode 100644
index 0000000000..75ac9a291e
--- /dev/null
+++ b/challenge-202/carlos-oliveira/perl/ch-2.pl
@@ -0,0 +1,45 @@
+use strict;
+use warnings;
+use v5.36;
+
+use Const::Fast;
+use List::MoreUtils qw(slideatatime firstidx slide all);
+
+sub pick_widest_valley {
+ return @_ if @_ < 3;
+ const my $step_size => 1;
+ for my $window_size (reverse 3 .. @_) {
+ my $it = slideatatime $step_size, $window_size, @_;
+ my @vals;
+ while (@vals = $it->() and @vals == $window_size) {
+ # where the non-increasing part necessarily stops? we'll start after it
+ my $abyss = firstidx { $_ } slide { $a < $b } @vals;
+ $abyss++;
+ return @vals
+ # firstidx returns -1 when an element is not found, 0 after our increment:
+ # this slice only has the non-increasing part and either part can be empty
+ if $abyss == 0
+ # the $abyss can't be the last element because the slide function needs at least two elements
+ || $abyss == $#vals
+ # everything after the $abyss must be non-decreasing
+ || all { $_ } slide { $a <= $b } @vals[$abyss..$#vals];
+ }
+ }
+ # any two elements shall suffice if the windows above didn't solve
+ return @_[0,1];
+}
+
+say join ", ", pick_widest_valley 1, 5, 5, 2, 8;
+say join ", ", pick_widest_valley 2, 6, 8, 5;
+say join ", ", pick_widest_valley 9, 8, 13, 13, 2, 2, 15, 17;
+say join ", ", pick_widest_valley 2, 1, 2, 1, 3;
+say join ", ", pick_widest_valley 1, 3, 3, 2, 1, 2, 3, 3, 2;
+say join ", ", pick_widest_valley 5, 8, 6, 2;
+
+# see results for short lists
+say join ", ", pick_widest_valley 1, 3;
+say join ", ", pick_widest_valley 3, 1;
+say join ", ", pick_widest_valley 3, 3;
+say join ", ", pick_widest_valley 5;
+say join ", ", pick_widest_valley 1, 5, 1;
+say pick_widest_valley == 0 ? 'empty' : 'not empty';
diff --git a/challenge-202/jo-37/blog.txt b/challenge-202/jo-37/blog.txt
new file mode 100644
index 0000000000..3578dee2d1
--- /dev/null
+++ b/challenge-202/jo-37/blog.txt
@@ -0,0 +1 @@
+https://github.com/jo-37/perlweeklychallenge-club/blob/master/challenge-202/jo-37/ch-202.md
diff --git a/challenge-202/jo-37/ch-202.md b/challenge-202/jo-37/ch-202.md
new file mode 100644
index 0000000000..a0843b564a
--- /dev/null
+++ b/challenge-202/jo-37/ch-202.md
@@ -0,0 +1,32 @@
+# Sequential adjacent consecutive second-next neighbors
+
+**Preface:**
+I wrote this text *after* I submitted my solution to the week 202's challenge *and* I looked throught all other solutions that were submitted so far.
+
+I was surprised to see other interpretations of task 1 that I hadn't thought about. To restate:
+
+> Write a script to print 1 if there are THREE consecutive odds in the given array otherwise print 0.
+
+Sounds clear: three consecutive odds. But wait: What is the meaning of "consecutive"?
+I interpreted this as "three odd numbers consecutive in the list". Another valid interpretation would be: "three consecutive odd numbers contained in the list". Something completely different!
+
+An example for my interpretation:
+
+ 2, 4, 9, 3, 7, 22
+has three consecutive odds: 9, 3, 7.
+
+On the other hand:
+
+ 4, 9, 2, 11, 6, 7
+has three consecutive odds: 7, 9, 11.
+
+I refuse to interpret the task as: three consecutive consecutive odds, i.e.
+
+ 2, 3, 5, 7, 8
+
+regarding as valid but refusing
+
+ 7, 2, 5, 8, 3
+
+
+
diff --git a/challenge-202/polettix/blog.txt b/challenge-202/polettix/blog.txt
new file mode 100644
index 0000000000..09838de191
--- /dev/null
+++ b/challenge-202/polettix/blog.txt
@@ -0,0 +1 @@
+https://etoobusy.polettix.it/2023/02/02/pwc202-consecutive-odds/
diff --git a/challenge-202/polettix/blog1.txt b/challenge-202/polettix/blog1.txt
new file mode 100644
index 0000000000..2039f2b51d
--- /dev/null
+++ b/challenge-202/polettix/blog1.txt
@@ -0,0 +1 @@
+https://etoobusy.polettix.it/2023/02/03/pwc202-widest-valley/
diff --git a/challenge-202/polettix/perl/ch-1.pl b/challenge-202/polettix/perl/ch-1.pl
new file mode 100644
index 0000000000..c0a97fb1dd
--- /dev/null
+++ b/challenge-202/polettix/perl/ch-1.pl
@@ -0,0 +1,33 @@
+#!/usr/bin/env perl
+use v5.24;
+use warnings;
+use experimental 'signatures';
+no warnings 'experimental::signatures';
+
+my ($n_streaks, $longest_streak) = consecutive_odds(@ARGV);
+
+# strict
+say {*STDERR} '(one single streak of exactly three odds, no other odd)';
+say {*STDOUT} $n_streaks == 1 && $longest_streak == 3 ? 1 : 0;
+
+# lax
+say {*STDERR} 'at least three odds in a row';
+say {*STDOUT} $longest_streak >= 3 ? 1 : 0;
+
+sub consecutive_odds (@array) {
+ my $longest_streak = 0;
+ my $current_streak = 0;
+ my $n_streaks = 0;
+ for my $item (@array) {
+ if ($item % 2) {
+ ++$current_streak;
+ ++$longest_streak if $longest_streak < $current_streak;
+ }
+ else {
+ ++$n_streaks if $current_streak;
+ $current_streak = 0;
+ }
+ }
+ ++$n_streaks if $current_streak;
+ return ($n_streaks, $longest_streak);
+}
diff --git a/challenge-202/polettix/perl/ch-2.pl b/challenge-202/polettix/perl/ch-2.pl
new file mode 100644
index 0000000000..22d26f76a3
--- /dev/null
+++ b/challenge-202/polettix/perl/ch-2.pl
@@ -0,0 +1,49 @@
+#!/usr/bin/env perl
+use v5.24;
+use warnings;
+use experimental 'signatures';
+no warnings 'experimental::signatures';
+
+my @valley =
+ widest_valley(grep { defined } map { split m{\D+}mxs, } @ARGV);
+say join ', ', @valley;
+
+sub widest_valley (@altitudes) {
+ return @altitudes if @altitudes < 2; # trivial cases
+
+ my $db = 0; # start of a valley
+ my $lb = 0; # start of a level
+ my $going_up = 0; # start going down
+ my ($vb, $vl) = (0, 1); # best valley so far
+
+ my $previous = $altitudes[0];
+ for my $i (1 .. $#altitudes) {
+ my $current = $altitudes[$i];
+
+ if ($previous < $current) { # going up
+ $lb = $i; # reset the level begin
+ $going_up = 1; # record the direction
+ }
+
+ # do nothing if $previous == $current
+
+ elsif ($previous > $current) { # going down
+ if ($going_up) { # leaving the top, "close" a valley
+ my $length = $i - $db;
+ ($vb, $vl) = ($db, $length) if $length > $vl;
+
+ $db = $lb; # record the start of the new valley
+ $going_up = 0; # record the direction
+ } ## end if ($going_up)
+ $lb = $i; # reset the level begin
+ } ## end elsif ($previous > $current)
+
+ $previous = $current; # prepare for the next iteration
+ } ## end for my $i (1 .. $#altitudes)
+
+ # anyway, close the last segment
+ my $length = @altitudes - $db;
+ ($vb, $vl) = ($db, $length) if $length > $vl;
+
+ return @altitudes[$vb .. ($vb + $vl - 1)];
+} ## end sub widest_valley
diff --git a/challenge-202/polettix/raku/ch-1.raku b/challenge-202/polettix/raku/ch-1.raku
new file mode 100644
index 0000000000..ea49384754
--- /dev/null
+++ b/challenge-202/polettix/raku/ch-1.raku
@@ -0,0 +1,31 @@
+#!/usr/bin/env raku
+use v6;
+sub MAIN (*@args) {
+ my ($n-streaks, $longest-streak) = consecutive-odds(@args);
+
+ # strict
+ $*ERR.put('(one single streak of exactly three odds, no other odd)');
+ $*OUT.put(($n-streaks == 1 && $longest-streak == 3) ?? 1 !! 0);
+
+ # lax
+ $*ERR.put('at least three odds in a row');
+ $*OUT.put(($longest-streak >= 3) ?? 1 !! 0);
+}
+
+sub consecutive-odds (@array) {
+ my $longest-streak = 0;
+ my $current-streak = 0;
+ my $n-streaks = 0;
+ for @array -> $item {
+ if $item %% 2 {
+ ++$n-streaks if $current-streak;
+ $current-streak = 0;
+ }
+ else {
+ ++$current-streak;
+ ++$longest-streak if $longest-streak < $current-streak;
+ }
+ }
+ ++$n-streaks if $current-streak;
+ return $n-streaks, $longest-streak;
+}
diff --git a/challenge-202/polettix/raku/ch-2.raku b/challenge-202/polettix/raku/ch-2.raku
new file mode 100644
index 0000000000..2e8bf02415
--- /dev/null
+++ b/challenge-202/polettix/raku/ch-2.raku
@@ -0,0 +1,47 @@
+#!/usr/bin/env raku
+use v6;
+sub MAIN (*@args) {
+ my @valley = widest-valley([@args.map({.comb(/\d+/)}).flatĀ».Int]);
+ put @valley.join(', ');
+}
+
+
+sub widest-valley (@altitudes) {
+ return @altitudes if @altitudes < 2; # trivial cases
+
+ my $db = 0; # start of a valley
+ my $lb = 0; # start of a level
+ my $going_up = 0; # start going down
+ my ($vb, $vl) = 0, 1; # best valley so far
+
+ my $previous = @altitudes[0];
+ for 1 ..^ @altitudes -> $i {
+ my $current = @altitudes[$i];
+
+ if $previous < $current { # going up
+ $lb = $i; # reset the level begin
+ $going_up = 1; # record the direction
+ }
+
+ # do nothing if $previous == $current
+
+ elsif $previous > $current { # going down
+ if ($going_up) { # leaving the top, "close" a valley
+ my $length = $i - $db;
+ ($vb, $vl) = $db, $length if $length > $vl;
+
+ $db = $lb; # record the start of the new valley
+ $going_up = 0; # record the direction
+ } ## end if ($going_up)
+ $lb = $i; # reset the level begin
+ } ## end elsif ($previous > $current)
+
+ $previous = $current; # prepare for the next iteration
+ } ## end for my $i (1 .. $#altitudes)
+
+ # anyway, close the last segment
+ my $length = @altitudes - $db;
+ ($vb, $vl) = $db, $length if $length > $vl;
+
+ return @altitudes[$vb .. ($vb + $vl - 1)];
+} ## end sub widest_valley