aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUtil <bruce.gray@acm.org>2022-12-25 15:56:54 -0600
committerUtil <bruce.gray@acm.org>2022-12-25 15:56:54 -0600
commitbb07b243bd10655b94998d929466377ac9255487 (patch)
tree263a472eb795cef54b624bf43cb4d5d9f92f9245
parentcfa0021bbaa682829341bf134823454b9c4d148f (diff)
downloadperlweeklychallenge-club-bb07b243bd10655b94998d929466377ac9255487.tar.gz
perlweeklychallenge-club-bb07b243bd10655b94998d929466377ac9255487.tar.bz2
perlweeklychallenge-club-bb07b243bd10655b94998d929466377ac9255487.zip
Add TWC 196 solutions by Bruce Gray (Raku only).
-rw-r--r--challenge-196/bruce-gray/raku/ch-1.raku93
-rw-r--r--challenge-196/bruce-gray/raku/ch-2.raku31
2 files changed, 124 insertions, 0 deletions
diff --git a/challenge-196/bruce-gray/raku/ch-1.raku b/challenge-196/bruce-gray/raku/ch-1.raku
new file mode 100644
index 0000000000..0478f377ef
--- /dev/null
+++ b/challenge-196/bruce-gray/raku/ch-1.raku
@@ -0,0 +1,93 @@
+# CAUTION: Written with Vacation Brain.
+
+# Simplest, and always correct,
+# but slow since it does not allow for short-circuiting.
+sub task1 ( @a ) {
+ return @a.combinations(3).first({ [<] .[0,2,1] }) // [];
+}
+
+# O(N³) worst case, but short-circuiting speeds up the common cases.
+sub task1_ak_then_j ( @a ) {
+ for @a.kv -> $i, $ai {
+ for $i+2 .. @a.end -> $k {
+ my $ak = @a[$k];
+ next unless $ai < $ak;
+ for @a[$i ^..^ $k] -> $aj {
+ return $ai, $aj, $ak if $ai < $ak < $aj;
+ }
+ }
+ }
+ return [];
+}
+
+# Trades two extra linear passes,
+# for (I think) a O(N²/4) worst case
+# and a much better average case.
+# Idea comes from the Water Collected problem.
+sub task1_faster ( @a ) {
+ my @R = [\min] @a;
+ my @L = reverse [\min] reverse @a;
+ my @LR = @L Zmax @R;
+
+ my @js = (@a Z> @LR).grep: :k, *.so;
+ return [] if not @js;
+
+ for @js -> $j {
+ my $aj = @a[$j];
+ for @a[ 0 ..^ $j ] -> $ai {
+ for @a[ $j ^.. @a.end ] -> $ak {
+ return $ai, $aj, $ak if $ai < $ak < $aj;
+ }
+ }
+ }
+ die "Can't happen";
+}
+
+# Translation of https://ayoubomari.medium.com/132-pattern-1b890c763bd5 ,
+# , which is well worth reading for the walkthrough!
+# It works perfectly to quickly (linear time!) find no-answer or some-132,
+# but it does not give us the *first* 132 as the task requires.
+sub find132pattern ( @ns ) {
+ my @stack;
+ for @ns -> $n {
+ my $min_i = $n;
+ if @stack and $n >= @stack.tail.min {
+ $min_i = @stack.tail.min;
+ pop @stack while @stack and $n > @stack.tail.max;
+ return |@stack.tail.bounds, $n if @stack and $n ~~ @stack.tail;
+ }
+ push @stack, $min_i ^..^ $n;
+ }
+ return [];
+}
+
+
+my @subs =
+ :&task1,
+ :&task1_ak_then_j,
+ :&task1_faster,
+ :&find132pattern,
+;
+my @tests =
+ ( (3, 1, 4, 2) , (1,4,2) ),
+ ( (1, 2, 3, 4) , [] ),
+ ( (1, 3, 2, 4, 6, 5) , (1,3,2) ),
+ ( (1, 3, 4, 2) , (1,3,2), (1,4,2) ),
+
+ ( (3, 5, 0, 2, 8, 7) , (3,8,7), (0,8,7) ),
+ ( (3, 5, 0, 2, 8, 4) , (3,5,4), (0,8,4) ),
+
+ ( (2,9,|(1 xx 100), |(1 xx 100),3), (2, 9, 3) ),
+ ( ( |(1 xx 100), 2,9,|(1 xx 100),3), (1, 9, 3) ),
+ ( ( |(9 xx 100),1,2,9,|(1 xx 100),3), (1, 9, 3) ),
+;
+use Test;
+for @tests.kv -> $test_num, ($in, $expected, $expected_alt?) {
+ for @subs -> $s {
+ my ($sub_name, $sub_code) = $s.kv;
+
+ my $exp = ($sub_name eq 'find132pattern' and $expected_alt.defined) ?? $expected_alt !! $expected;
+
+ is $sub_code.($in), $exp, "{$test_num + 1} $sub_name";
+ }
+}
diff --git a/challenge-196/bruce-gray/raku/ch-2.raku b/challenge-196/bruce-gray/raku/ch-2.raku
new file mode 100644
index 0000000000..97ef78b8b8
--- /dev/null
+++ b/challenge-196/bruce-gray/raku/ch-2.raku
@@ -0,0 +1,31 @@
+sub task2 ( @ns ) {
+ return Empty unless @ns;
+ die unless @ns.all ~~ Int and [<] @ns;
+
+ return gather {
+ my $temp = [];
+ for @ns.rotor(2 => -1) -> ($a, $b) {
+ if $a+1 == $b {
+ $temp[0] //= $a;
+ $temp[1] = $b;
+ }
+ elsif +$temp {
+ take $temp;
+ $temp = [];
+ }
+ }
+ take $temp if +$temp;
+ }
+}
+
+
+my @tests =
+ ( (1,3,4,5,7 ) , ( [3,5], ) ),
+ ( (1,2,3,6,7,9 ) , ( [1,3], [6,7] ) ),
+ ( (0,1,2,4,5,6,8,9) , ( [0,2], [4,6], [8,9] ) ),
+;
+use Test;
+plan +@tests;
+for @tests -> ($in, $expected) {
+ is-deeply task2($in), $expected;
+}