diff options
| author | Mohammad S Anwar <mohammad.anwar@yahoo.com> | 2023-02-05 00:33:40 +0000 |
|---|---|---|
| committer | Mohammad S Anwar <mohammad.anwar@yahoo.com> | 2023-02-05 00:33:40 +0000 |
| commit | bb49ce568aa7451728b149870379bbc8dbf6632d (patch) | |
| tree | 7888c780378fb7442e135992e8ee171f57b89d01 | |
| parent | 8d9cfd8d2ac39bb5d0b0f7452bf57d200bbdd62f (diff) | |
| parent | 1b765079cf83f8f6421d9b508cba813da02f07e0 (diff) | |
| download | perlweeklychallenge-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.txt | 1 | ||||
| -rwxr-xr-x | challenge-202/arne-sommer/raku/ch-1.raku | 28 | ||||
| -rwxr-xr-x | challenge-202/arne-sommer/raku/ch-2.raku | 43 | ||||
| -rwxr-xr-x | challenge-202/arne-sommer/raku/consecutive-odds | 28 | ||||
| -rwxr-xr-x | challenge-202/arne-sommer/raku/widest-valley | 56 | ||||
| -rwxr-xr-x | challenge-202/arne-sommer/raku/widest-valley-shorter | 43 | ||||
| -rw-r--r-- | challenge-202/carlos-oliveira/perl/ch-1.pl | 22 | ||||
| -rw-r--r-- | challenge-202/carlos-oliveira/perl/ch-2.pl | 45 | ||||
| -rw-r--r-- | challenge-202/jo-37/blog.txt | 1 | ||||
| -rw-r--r-- | challenge-202/jo-37/ch-202.md | 32 | ||||
| -rw-r--r-- | challenge-202/polettix/blog.txt | 1 | ||||
| -rw-r--r-- | challenge-202/polettix/blog1.txt | 1 | ||||
| -rw-r--r-- | challenge-202/polettix/perl/ch-1.pl | 33 | ||||
| -rw-r--r-- | challenge-202/polettix/perl/ch-2.pl | 49 | ||||
| -rw-r--r-- | challenge-202/polettix/raku/ch-1.raku | 31 | ||||
| -rw-r--r-- | challenge-202/polettix/raku/ch-2.raku | 47 |
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 |
