Skip to content

Instantly share code, notes, and snippets.

@nd3i
Last active February 7, 2023 16:28
Show Gist options
  • Save nd3i/1c15e7a34935148e29d0a4721295a646 to your computer and use it in GitHub Desktop.
Save nd3i/1c15e7a34935148e29d0a4721295a646 to your computer and use it in GitHub Desktop.
# https://theweeklychallenge.org/blog/perl-weekly-challenge-202/#TASK2
#
# Given a profile as a list of altitudes, return the leftmost widest
# valley. A valley is defined as a subarray of the profile consisting
# of two parts: the first part is non-increasing and the second part
# is non-decreasing. Either part can be empty.
# encode: convert list of Int to Arry of symbols:
# (1 5 5 2 8) --> [< = > <]
#
sub encode (@in) {
constant @symbols = '<', '=', '>'; # up, equal, down
@in.rotor(2 => -1) # list of two-element lists: ((1 5) (5 5) ...)
.map( -> ($a, $b) { @symbols[ 1+sign($a-$b) ] });
}
# search String of symbols for 'valley' pattern
#
sub best_match ($s) {
my regex not-up { <-[\<]> };
my regex not-down { <-[\>]> };
my regex valley { <not-up>+ |
<not-down>+ |
<not-up>+ <not-down>+ };
# array of match objects
my @m = $s.match(:g, :ov, / <valley> /);
# return only one, the leftmost longest match
@m.sort({ .chars, -.from })[@m.end]
}
-> @in {
my $m = best_match(encode(@in).join);
my @matched_elements = @in[$m.from .. $m.to];
my @matched_symbols = $m.comb;
say @in, " --> ",
$m.from, "-", $m.to, ": ",
roundrobin(@matched_elements, @matched_symbols).flat.join;
} for
(1, 5, 5, 2, 8), # 5, 5, 2, 8
(2, 6, 8, 5), # 2, 6, 8
(9, 8, 13, 13, 2, 2, 15, 17), # 13, 13, 2, 2, 15, 17
(2, 1, 2, 1, 3), # 2, 1, 2
(1, 3, 3, 2, 1, 2, 3, 3, 2), # 3, 3, 2, 1, 2, 3, 3
(0..15).pick xx (1..12).pick # ??
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment