diff options
| -rw-r--r-- | challenge-121/mark-anderson/raku/ch-1.raku | 27 | ||||
| -rw-r--r-- | challenge-121/mark-anderson/raku/ch-2.raku | 78 |
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; +} |
