aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-258/mark-anderson/raku/ch-1.raku6
-rw-r--r--challenge-258/mark-anderson/raku/ch-2.raku75
2 files changed, 81 insertions, 0 deletions
diff --git a/challenge-258/mark-anderson/raku/ch-1.raku b/challenge-258/mark-anderson/raku/ch-1.raku
new file mode 100644
index 0000000000..a0d78a080c
--- /dev/null
+++ b/challenge-258/mark-anderson/raku/ch-1.raku
@@ -0,0 +1,6 @@
+#!/usr/bin/env raku
+use Test;
+
+is (10,1,111,24,1000).grep(*.chars %% 2).elems, 3;
+is (111,1,11111) .grep(*.chars %% 2).elems, 0;
+is (2,8,1024,256) .grep(*.chars %% 2).elems, 1;
diff --git a/challenge-258/mark-anderson/raku/ch-2.raku b/challenge-258/mark-anderson/raku/ch-2.raku
new file mode 100644
index 0000000000..3cdcc4fd35
--- /dev/null
+++ b/challenge-258/mark-anderson/raku/ch-2.raku
@@ -0,0 +1,75 @@
+#!/usr/bin/env raku
+use Test;
+
+is sum-of-values([2,5,9,11,3], 1), 17;
+is sum-of-values([2,5,9,11,3], 2), 11;
+is sum-of-values([2,5,9,11,3], 0), 2;
+is sum-of-values([^100], 4), 1555;
+is sum-of-values([99...0], 4), 1019;
+is sum-of-values([^1e6], 8), 52104319732;
+
+sub postfix:<!>($n) { [*] 1..$n }
+
+sub sum-of-values(@ints, $k)
+{
+ my $end = @ints.end;
+
+ loop
+ {
+ last if $end.base(2) ~~ m:g/1/ == $k;
+ $end--
+ }
+
+ my $rank = rank($end.base(2));
+ my $chars = $end.base(2).chars;
+ my @ones = 1 xx $chars;
+ my $combs = $chars-$k;
+
+ return @ints[$end] unless $combs;
+
+ my $channel = Channel.new;
+
+ for ^$chars .combinations($combs)
+ {
+ last if $++ == $rank;
+ $channel.send($_)
+ }
+
+ $channel.close;
+
+ my @promises = gather for ^$*KERNEL.cpu-cores
+ {
+ take start process()
+ }
+
+ await @promises;
+
+ return sum @promises.map(*.result);
+
+ sub process
+ {
+ sum gather while $channel.poll -> $combination
+ {
+ my @a = @ones;
+ $combination.map({ @a[$_] = 0 });
+ my $i = ([~] @a).parse-base(2);
+ take @ints[$i]
+ }
+ }
+}
+
+sub rank($s)
+{
+ my @a = $s.comb;
+ my @ranks = @a.sort.squish.antipairs.Map{@a}>>.succ;
+ my $bag = @ranks.BagHash;
+
+ my @n = gather for @ranks -> $r
+ {
+ my @less-than = $bag.keys.grep(* < $r);
+ take ([+] $bag{@less-than}) / ([*] $bag.values>>!);
+ $bag{$r}--
+ }
+
+ 1 + [+] @n Z* (@ranks.end...0)>>!
+}