diff options
| author | Polgár Márton <polgar@astron.hu> | 2023-02-06 01:30:39 +0100 |
|---|---|---|
| committer | Polgár Márton <polgar@astron.hu> | 2023-02-06 01:30:39 +0100 |
| commit | f6bc104b4e56555b940ee35b4cb27b54e8b98ea7 (patch) | |
| tree | 958f7e44a9f911e6be1ac90a39beef37816cb6c9 /challenge-202 | |
| parent | 3b2c7ff15dabaa4fa421ae8667e775786b0498a4 (diff) | |
| download | perlweeklychallenge-club-f6bc104b4e56555b940ee35b4cb27b54e8b98ea7.tar.gz perlweeklychallenge-club-f6bc104b4e56555b940ee35b4cb27b54e8b98ea7.tar.bz2 perlweeklychallenge-club-f6bc104b4e56555b940ee35b4cb27b54e8b98ea7.zip | |
Weeklies by 2colours
Diffstat (limited to 'challenge-202')
| -rwxr-xr-x | challenge-202/2colours/raku/ch-1.raku | 19 | ||||
| -rwxr-xr-x | challenge-202/2colours/raku/ch-2.raku | 58 |
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; +} + |
