aboutsummaryrefslogtreecommitdiff
path: root/challenge-202
diff options
context:
space:
mode:
authorPolgár Márton <polgar@astron.hu>2023-02-06 01:30:39 +0100
committerPolgár Márton <polgar@astron.hu>2023-02-06 01:30:39 +0100
commitf6bc104b4e56555b940ee35b4cb27b54e8b98ea7 (patch)
tree958f7e44a9f911e6be1ac90a39beef37816cb6c9 /challenge-202
parent3b2c7ff15dabaa4fa421ae8667e775786b0498a4 (diff)
downloadperlweeklychallenge-club-f6bc104b4e56555b940ee35b4cb27b54e8b98ea7.tar.gz
perlweeklychallenge-club-f6bc104b4e56555b940ee35b4cb27b54e8b98ea7.tar.bz2
perlweeklychallenge-club-f6bc104b4e56555b940ee35b4cb27b54e8b98ea7.zip
Weeklies by 2colours
Diffstat (limited to 'challenge-202')
-rwxr-xr-xchallenge-202/2colours/raku/ch-1.raku19
-rwxr-xr-xchallenge-202/2colours/raku/ch-2.raku58
2 files changed, 77 insertions, 0 deletions
diff --git a/challenge-202/2colours/raku/ch-1.raku b/challenge-202/2colours/raku/ch-1.raku
new file mode 100755
index 0000000000..d63efc5770
--- /dev/null
+++ b/challenge-202/2colours/raku/ch-1.raku
@@ -0,0 +1,19 @@
+#!/usr/bin/env raku
+
+use v6.*;
+my token unsigned-integer { 0 | <[1..9]><[0..9]>* };
+my token integer { '-'? <unsigned-integer> };
+subset IntList of Str where /^ '(' <integer>* % ',' ')' $/;
+
+
+sub MAIN(Str $array) {
+ die 'Please supply a valid list of integers.' unless $array.subst(/\s/, '', :g) ~~ IntList;
+ my Int() @array = $<integer>;
+ my $streak = 0;
+ my $output is default(0) = do for @array {
+ $streak = $_ %% 2 ?? 0 !! $streak + 1;
+ last 1 if $streak == 3;
+ }.head;
+ say $output;
+}
+
diff --git a/challenge-202/2colours/raku/ch-2.raku b/challenge-202/2colours/raku/ch-2.raku
new file mode 100755
index 0000000000..7d8150cdd0
--- /dev/null
+++ b/challenge-202/2colours/raku/ch-2.raku
@@ -0,0 +1,58 @@
+#!/usr/bin/env raku
+
+my token unsigned-integer { 0 | <[1..9]><[0..9]>* };
+my token integer { '-'? <unsigned-integer> };
+subset IntList of Str where /^ '(' <integer>* % ',' ')' $/;
+
+
+sub MAIN(Str $array) { #using only integer altitudes but the algorithm should work on any real numbers as well
+ die 'Please supply a valid list of integers.' unless $array.subst(/\s/, '', :g) ~~ IntList;
+ my Int() @array = $<integer>;
+ my @comparative = @array.rotor(2 => -1).map({ .[0] <=> .[1] });
+ enum <START PREFIX DESC >;
+ my @candidate-starts = gather for @comparative.kv -> $pos, $comp-to-next {
+ state $fsm-state = START;
+ state $possible-start-position;
+ when $fsm-state == START && $comp-to-next == Same { # we may start a valley, not sure yet
+ $fsm-state = PREFIX;
+ $possible-start-position = $pos;
+ }
+ when $fsm-state == PREFIX && $comp-to-next == Less { # the possible valley failed
+ $possible-start-position = Nil;
+ $fsm-state = START;
+ }
+ when $fsm-state == START && $comp-to-next == More { # the valley just started with a slope
+ $fsm-state = DESC;
+ take $pos;
+ }
+ when $fsm-state == PREFIX && $comp-to-next == More { # the possible valley turned out to be real, going downhill...
+ take $possible-start-position;
+ $possible-start-position = Nil;
+ $fsm-state = DESC;
+ }
+ # Note: as long as we are going downhill, there is no point in "starting" a new valley because that would not be optimal
+ when $fsm-state == DESC && $comp-to-next == Less { # the downhill part is surely over; we may start looking for new starter positions...
+ $fsm-state = START;
+ }
+ };
+ # The starting position should always be considered a starter.
+ # Normally, a valley starting by going upwards cannot be optimal because it's better extended in front, with a downwards bit.
+ # But what if there is no downwards bit because the values are monotone increasing at the beginning?
+ # As a corner case, that needs to be taken into account, hence the first element will always be a starter candidate:
+ # - either because a valley starts by going downwards, the usual way
+ # - or because the valley starts by going upwards and cannot be improved, simply because there is nothing in front to extend it :)
+ @candidate-starts.unshift(0) unless @candidate-starts[0] == 0;
+
+ my @candidate-ranges = gather for @candidate-starts.rotor(2 => -1, :partial) -> ($start, $trivial-end?) {
+ without $trivial-end {
+ take $start .. @comparative;
+ next;
+ }
+ my $end = $trivial-end;
+ $end++ while @comparative[$end] == Same;
+ take $start .. $end;
+ }
+ my $best-range = @candidate-ranges.max(*.elems);
+ @array[|$best-range].join(', ').say;
+}
+