aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-121/mark-anderson/raku/ch-1.raku27
-rw-r--r--challenge-121/mark-anderson/raku/ch-2.raku78
2 files changed, 105 insertions, 0 deletions
diff --git a/challenge-121/mark-anderson/raku/ch-1.raku b/challenge-121/mark-anderson/raku/ch-1.raku
new file mode 100644
index 0000000000..e028a2e1e0
--- /dev/null
+++ b/challenge-121/mark-anderson/raku/ch-1.raku
@@ -0,0 +1,27 @@
+#!/usr/bin/env raku
+
+use Test;
+plan 9;
+
+my $tests :=
+<
+ 12 3 8
+ 18 4 26
+ 0 1 1
+ 1 1 0
+ 1 2 3
+ 1 3 5
+ 255 6 223
+ 255 7 191
+ 255 8 127
+>;
+
+for $tests
+{
+ is invert-bit($^a, $^b), $^c
+}
+
+sub invert-bit($m where * ~~ ^256, $n where * ~~ 1..8)
+{
+ $m +^ (1 +< ($n - 1))
+}
diff --git a/challenge-121/mark-anderson/raku/ch-2.raku b/challenge-121/mark-anderson/raku/ch-2.raku
new file mode 100644
index 0000000000..c492deba65
--- /dev/null
+++ b/challenge-121/mark-anderson/raku/ch-2.raku
@@ -0,0 +1,78 @@
+#!/usr/bin/env raku
+
+my @matrix = [ ∞, 5, 2, 7 ],
+ [ 5, ∞, 5, 3 ],
+ [ 3, 1, ∞, 6 ],
+ [ 4, 5, 4, ∞ ];
+
+my ($cost, @reduced) = get-cost-and-reduced(@matrix);
+
+say branch-and-bound([1], @reduced);
+
+sub branch-and-bound(@path, @matrix)
+{
+ return $cost if @path.elems == @matrix.elems;
+
+ my %h = Empty;
+
+ for get-paths(@path) -> @p
+ {
+ my @m = prepare(@p, @matrix.duckmap(*.clone));
+ (my $c, @m) = get-cost-and-reduced(@m);
+ my $total = [+] $cost, @matrix[@p[*-2]-1;@p[*-1]-1] + $c;
+
+ %h{$total}<path> = @p;
+ %h{$total}<matrix> = @m;
+ }
+
+ $cost = .key with min %h;
+ branch-and-bound(.value<path>, .value<matrix>) with min %h;
+}
+
+sub get-cost-and-reduced(@matrix)
+{
+ my @cost;
+ my @m = @matrix.duckmap(*.clone);
+
+ for ^2
+ {
+ for @m -> @r
+ {
+ my $min = @r.min;
+ $min = 0 if $min == ∞;
+ @cost.push: $min;
+
+ for @r -> $n is rw
+ {
+ $n -= $min;
+ $n = ∞ if $n ~~ NaN;
+ }
+ }
+
+ @m = [Z] @m;
+ @m .= map(*.Array);
+ }
+
+ @cost.sum, |@m;
+}
+
+sub get-paths(@a)
+{
+ my @nodes = 1..@matrix.elems;
+ my @copy = (@nodes (-) @a).keys;
+ my @p = @a xx @copy;
+
+ @p.map({ $_ = [ |$_, @copy.pop ] }).Array;
+}
+
+sub prepare(@path, @matrix)
+{
+ my @m = @matrix.duckmap(*.clone);
+ my $r = @path[*-2]-1;
+ my $c = @path[*-1]-1;
+
+ @m[$r].map({ $_ = ∞ });
+ @m.map({ .[$c] = ∞ });
+ @m[$c;@path[0]-1] = ∞;
+ @m;
+}