aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad Sajid Anwar <Mohammad.Anwar@yahoo.com>2023-05-28 23:39:55 +0100
committerGitHub <noreply@github.com>2023-05-28 23:39:55 +0100
commit394979f6929fa0d2db0c7934b0d0027a69c58777 (patch)
tree97427e98a64939652dcdd6679cb571e27deab8ae
parent10779f8221b6231230028af21ae7b874407f747c (diff)
parentf6a6cea4b1f736b511072170beae118bb1ee243f (diff)
downloadperlweeklychallenge-club-394979f6929fa0d2db0c7934b0d0027a69c58777.tar.gz
perlweeklychallenge-club-394979f6929fa0d2db0c7934b0d0027a69c58777.tar.bz2
perlweeklychallenge-club-394979f6929fa0d2db0c7934b0d0027a69c58777.zip
Merge pull request #8154 from 0rir/218
218
-rw-r--r--challenge-218/0rir/raku/ch-1.raku113
-rw-r--r--challenge-218/0rir/raku/ch-2.raku121
2 files changed, 234 insertions, 0 deletions
diff --git a/challenge-218/0rir/raku/ch-1.raku b/challenge-218/0rir/raku/ch-1.raku
new file mode 100644
index 0000000000..287fd175f5
--- /dev/null
+++ b/challenge-218/0rir/raku/ch-1.raku
@@ -0,0 +1,113 @@
+#!/usr/bin/env raku
+# :vim ft=raku sw=4 expandtab # 🦋 ∅∪∩∋∈∉ ≡ ≢ «␤ » ∴
+use v6.d;
+use lib $?FILE.IO.parent(2).add("lib");
+use Test;
+
+=begin comment
+218-1: Maximum Product Submitted by: Mohammad S Anwar
+Given a list of 3 or more integers, find the 3 integers whose product
+is the maximum and return it.
+
+Example 1
+Input: @list = (3, 1, 2)
+Output: 6
+
+1 x 2 x 3 => 6
+Example 2
+Input: @list = (4, 1, 3, 2)
+Output: 24
+
+2 x 3 x 4 => 24
+Example 3
+Input: @list = (-1, 0, 1, 3, 1)
+Output: 3
+
+1 x 1 x 3 => 3
+Example 4
+Input: @list = (-8, 2, -9, 0, -4, 3)
+Output: 216
+
+-9 × -8 × 3 => 216
+=end comment
+
+my @Test =
+ # in exp
+ (3, 1, 2), 6, # given
+ (4, 1, 3, 2), 24,
+ (-8, 2, -9, 0, -4, 3), 216,
+ (-1, 0, 1, 3, 1), 3,
+
+ (-2, 3, 5), -30, # three elems
+
+ ( 0, 1, 2, 3), 6, # quads
+ ( 1, 2, 3, 4), 24,
+ (-3, -2, -1, 0), 0,
+ (-4, -3, -2, -1), -6,
+ (-1, 1, 2, 3), 6,
+ (-1, -1, -2, 3), 6,
+ (-1, -1, 2, 3), 3,
+ (-3, -2, 3, 3), 18,
+ (-3, -3, 3, 3), 27,
+
+ ( 0, 1, 2, 3, 4), 24, # all pos
+ ( 1, 2, 3, 4, 5), 60,
+ (-4, -3, -2, -1, 0), 0, # max zed
+ (-5, -4, -3, -2, -1), -6, # all neg
+ (-2, 0, 1, 2, 3), 6, # 1 neg
+ (-2, 1, 2, 3, 4), 24, # 1 neg
+ (-2, -3, -1, -1, 4), 24, # 1 pos
+
+ (-1, -1, 2, 3, 4), 24, # 2 neg
+ (-3, -2, 1, 3, 3), 18,
+ (-3, -2, 3, 3, 3), 27,
+ (-3, -2, 1, 3, 3, 3), 27,
+
+ (-2, -1, -1, 3, 4), 8, # 2 pos
+ (-3, -2, -1, 3, 3), 18,
+ (-3, -2, -1, -1, 1, 2), 12,
+ (-3, -2, 1, 3, 3, 3), 3³,
+
+ (-9, -2, -2, 2, 3, 6), 108, # default
+ (-8, -4, -2, 2, 4, 9), 288,
+ (-8, -4, -2, 5, 6, 9), 288,
+ (-8, -4, -2, 5, 7, 9), 315,
+ (-8, -5, -2, 5, 7, 9), 360,
+ ;
+plan @Test ÷ 2 + 1 + 1000;
+
+multi max3prod( @a where *.elems < 3) { die( 'oospec') }
+multi max3prod( @a ) {
+ multi func {…}
+ return func @a.sort;
+
+ multi func( @a where 0 ≤ *[0]) { [×] @a[*-3..*-1] } # all pos
+ multi func( @a where *[*-1] < 0) { [×] @a[*-3..*-1] } # all neg
+ # mixed signs
+ multi func( @a){ max ([×] @a[0,1,*-1]), ([×] @a[*-3..*-1]); }
+}
+
+for @Test -> @in, $exp {
+ is max3prod(@in), $exp, "$exp\t<- @in.sort() sorted";
+}
+srand(102);
+for 1..1_000 {
+ my @t;
+ for 1..4 + (^5).pick -> $l {
+ for (^20).pick - 10 -> $r {
+ @t.push: $r;
+ }
+ }
+ my $res = @t.combinations(3).map( {[*] $_} ).max; # brute
+ is max3prod(@t), $res, "$res\t<- @t.sort() sorted";
+}
+
+dies-ok { max3prod( (1,2)) }, "(1,2) dies-ok";
+done-testing;
+
+my $list = (-8, 2, -9, 0, -4, 3);
+say "\nInput: @list = @$list[]\nOutput: &max3prod(@$list).sort()";
+
+
+exit;
+
diff --git a/challenge-218/0rir/raku/ch-2.raku b/challenge-218/0rir/raku/ch-2.raku
new file mode 100644
index 0000000000..2decd60d85
--- /dev/null
+++ b/challenge-218/0rir/raku/ch-2.raku
@@ -0,0 +1,121 @@
+#!/usr/bin/env raku
+# :vim ft=raku sw=4 expandtab # 🦋 ∅∪∩∋∈∉ ≡ ≢ «␤ » ∴
+use v6.d;
+use Test;
+
+=begin comment
+Task 2: Matrix Score Submitted by: Mohammad S Anwar
+Given a m x n binary matrix i.e. having only 1 and 0, make as many
+moves as you want to get the highest score.
+
+A move can be either toggling all values in a row or column.
+
+To get the score, convert each row's binary value to decimal and
+return the sum.
+
+Example 1:
+Input: @matrix = [ [0,0,1,1], [1,0,1,0], [1,1,0,0], ]
+Output: 39
+
+Move #1: convert row #1 => 1100
+ [ [1,1,0,0], [1,0,1,0], [1,1,0,0], ]
+
+Move #2: convert col #3 => 101
+ [ [1,1,1,0], [1,0,0,0], [1,1,1,0], ]
+
+Move #3: convert col #4 => 111
+ [ [1,1,1,1], [1,0,0,1], [1,1,1,1], ]
+
+Score: 0b1111 + 0b1001 + 0b1111 => 15 + 9 + 15 => 39
+Example 2:
+Input: @matrix = [ [0] ]
+Output: 1
+=end comment
+
+my @Test =
+ [ [0,0,0,1], [0,0,0,1], [0,0,0,1],], 45,
+ [ [0,0,1,1], [1,0,1,0], [1,1,0,0],], 39,
+ [ [0],], 1,
+ [ [1,0], [0,1], [0,0],], 8,
+ [ [1,0], [0,1], [1,0], [0,0],], 11,
+ [ [0,0,1,1], [1,0,1,0], [1,1,0,0], [ 0,1,0,1],], 48,
+ [ [0,1,0,1,1], [1,0,1,1,0], [1,1,0,0,1], [ 0,1,0,0,1],], 107,
+ [ [0,0,0,0,1], [1,0,0,0,0], [0,0,0,0,0], [ 1,0,0,0,1],], 94,
+;
+
+plan @Test ÷ 2;
+
+sub max-row-base2( @m -->Int) {
+ my @mat = @m.raku.EVAL;
+ for @mat -> @row {
+ if @row[0] == 0 { invert @row;}
+ }
+ for ^@mat[0] -> $c {
+ my @col := bind-col( @mat, $c);
+ if +@col.grep(1) < +@col.grep(0) { invert @col; }
+ }
+ return [+] @mat.map( { parse-base .join, 2});
+
+ sub invert( @a -->Nil) { for @a -> $e is rw { $e = (!$e.Bool).Int }}
+}
+
+sub bind-col( @m, $col-num -->Array) {
+ my @col;
+ @col[$_] := @m[$_][$col-num] for ^@m;
+ @col
+}
+
+# A very stupid, stupid brute. Was I redundent?
+#
+# Every row and column is named. Rows use their index and columns are
+# named with the @matrix.end + the value of the index into @matrix[0].
+# Permute this list; go thru each list; toggle each column or row; update
+# score and repeat. Quit early if theoretical best score is found.
+sub brute( @matrix -->Int) {
+ my $ct = 0;
+ my @mat = @matrix.raku.EVAL;
+ my $theo-best = theo-best(@mat);
+ my $best = score( @mat);
+ my @plan = ( ^(@mat.elems +@mat[0])).Array.permutations;
+ for @plan -> @p {
+ my @m = @mat;
+ for @p -> $id {
+ toggle( $id, @m);
+ my $s = score @m;
+ $best = $s if $best < $s;
+ }
+ return $best if $best == $theo-best;
+ }
+ return $best;
+
+ sub score( @m -->Int) { [+] @m.map: {parse-base .join, 2 }}
+ sub theo-best( @m -->Int) { @m.elems × ( 2**@m[0].elems - 1) }
+}
+
+sub toggle( UInt $id, @a -->Nil) {
+ if is-row( @a, $id) {
+ for ^@a[0] -> $i {
+ @a[$id][$i] = (!@a[$id][$i].Bool).Int;
+ }
+ } else {
+ my $cid = $id - @a.elems;
+ for ^@a -> $r {
+ @a[$r][$cid] = (!@a[$r][$cid].Bool).Int;
+ }
+ }
+ sub is-row( @m, UInt $i -->Bool) { $i < @m.elems }
+}
+
+for @Test -> @in, $exp {
+ is max-row-base2( @in), $exp, "$exp <-\t@in.raku()";
+# is brute( @in), $exp, "$exp <-\t@in.raku()";
+}
+
+done-testing;
+
+my @matrix = [ [0,0,1,1], [1,0,1,0], [1,1,0,0], ];
+my $preface = "Input: @matrix = [";
+
+print "\n$preface [";
+print @matrix.join( "],\n " ~ (' ' x $preface.chars) ~ '[' );
+say "], ]" ~ "\nOutput: &max-row-base2( @matrix)";