aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xchallenge-214/feng-chang/raku/ch-1.raku12
-rwxr-xr-xchallenge-214/feng-chang/raku/ch-2.raku37
-rwxr-xr-xchallenge-214/feng-chang/raku/ch-2a.raku65
-rwxr-xr-xchallenge-214/feng-chang/raku/test.raku46
4 files changed, 160 insertions, 0 deletions
diff --git a/challenge-214/feng-chang/raku/ch-1.raku b/challenge-214/feng-chang/raku/ch-1.raku
new file mode 100755
index 0000000000..d1ebae04a5
--- /dev/null
+++ b/challenge-214/feng-chang/raku/ch-1.raku
@@ -0,0 +1,12 @@
+#!/bin/env raku
+
+unit sub MAIN(*@N where @N.all ≥ 1);
+
+@N = @N».Int.Array;
+
+my %ndx;
+for @N.sort({ $^a < $^b }).antipairs -> $p {
+ %ndx{$p.key} = $p.value + 1 unless %ndx{$p.key}.defined;
+}
+
+put %ndx{@N}.map({ .trans('123' => 'GSB') }).join(', ');
diff --git a/challenge-214/feng-chang/raku/ch-2.raku b/challenge-214/feng-chang/raku/ch-2.raku
new file mode 100755
index 0000000000..448ab3b9f7
--- /dev/null
+++ b/challenge-214/feng-chang/raku/ch-2.raku
@@ -0,0 +1,37 @@
+#!/bin/env raku
+
+unit sub MAIN(*@N);
+
+my %G = @N.join(',') => 0;
+my $score = 0;
+
+while True {
+ my %G_;
+
+ for %G.keys -> $k {
+ my @nums = $k.comb(/\d+/)».Int;
+ my $total = %G{$k};
+
+ my ($i, $j) = 0, 0;
+ while $j + 1 ≤ +@nums {
+ ++$j while @nums[$j+1].defined and @nums[$j+1] == @nums[$i];
+ my @nums_ = @nums;
+ my $score_ = $total + ($j - $i + 1)²;
+
+ @nums_.splice($i, $j - $i + 1);
+ my $k_ = @nums_.join(',');
+
+ $score_ = max($score_, %G_{$k_} // 0);
+ %G_{$k_} = $score_;
+
+ $score = $score_ if $score_ > $score;
+
+ $i = ++$j;
+ }
+ }
+
+ last unless +%G_;
+ %G = %G_;
+}
+
+put $score;
diff --git a/challenge-214/feng-chang/raku/ch-2a.raku b/challenge-214/feng-chang/raku/ch-2a.raku
new file mode 100755
index 0000000000..de853864a6
--- /dev/null
+++ b/challenge-214/feng-chang/raku/ch-2a.raku
@@ -0,0 +1,65 @@
+#!/bin/env raku
+
+unit sub MAIN(*@N);
+
+class Group {
+ has Int $.number;
+ has UInt $.count;
+
+ method score() { $.count * $.count }
+ method Str() { "{$.number} {$.count}" }
+ method eq(Group:D $g) { $.number == $g.number && $.count == $g.count }
+}
+
+@N = @N».Int.Array;
+
+my @g;
+my ($i, $j) = 0, 0;
+while $j + 1 ≤ +@N {
+ ++$j while @N[$j+1].defined and @N[$j+1] == @N[$i];
+ @g.push(Group.new(:number(@N[$i]), :count($j-$i+1)));
+ $i = ++$j;
+}
+
+my @G = [@g, 0],;
+my $score = 0;
+
+while True {
+ my @G_;
+
+ for ^+@G -> $i {
+ my $groups = @G[$i][0];
+ my $total = @G[$i][1];
+
+ for ^+$groups -> $j {
+ my $g_ = $groups[$j];
+
+ my $score_ = $total + $g_.score;
+ $score = $score_ if $score_ > $score;
+ last if +$groups ≤ 1;
+
+ # remove sequence after scoring
+ my $groups_ = $groups.clone;
+ $groups_.splice($j, 1);
+
+ if 0 < $j < +$groups_ and $groups_[$j-1].number == $groups_[$j].number {
+ # merge if possible
+ $groups_[$j-1] = Group.new(:number($groups_[$j].number), :count($groups_[$j-1].count + $groups_[$j].count));
+ $groups_.splice($j, 1);
+ }
+
+ my $k = @G_.grep({ $_ eqv $groups }, :k).first;
+ if $k.defined {
+ # found duplicate
+ @G_[$k][1] = max(@G_[$k][1], $score_);
+ } else {
+ @G_.push([$groups_, $score_]);
+ }
+ }
+ }
+
+ last unless +@G_;
+ @G = @G_;
+}
+
+put $score;
diff --git a/challenge-214/feng-chang/raku/test.raku b/challenge-214/feng-chang/raku/test.raku
new file mode 100755
index 0000000000..c09291ebf4
--- /dev/null
+++ b/challenge-214/feng-chang/raku/test.raku
@@ -0,0 +1,46 @@
+#!/bin/env raku
+
+use Test;
+
+# The Weekly Challenge 214
+
+# Task 1, Rank Score
+my $p = run <./ch-1.raku 1 2 4 3 5>, :out;
+is $p.out.slurp(:close).chomp, '5, 4, S, B, G', 'Rank Score: 1,2,4,3,5 => 5, 4, S, B, G';
+
+$p = run <./ch-1.raku 8 5 6 7 4>, :out;
+is $p.out.slurp(:close).chomp, 'G, 4, B, S, 5', 'Rank Score: 8,5,6,7,4 => G, 4, B, S, 5';
+
+$p = run <./ch-1.raku 3 5 4 2>, :out;
+is $p.out.slurp(:close).chomp, 'B, G, S, 4', 'Rank Score: 3,5,4,2 => B, G, S, 4';
+
+$p = run <./ch-1.raku 2 5 2 1 7 5 1>, :out;
+is $p.out.slurp(:close).chomp, '4, S, 4, 6, G, S, 6', 'Rank Score: 2,5,2,1,7,5,1 => 4, S, 4, 6, G, S, 6';
+
+# Task 2, Collect Points
+$p = run <./ch-2.raku 2 4 3 3 3 4 5 4 2>, :out;
+is $p.out.slurp(:close).chomp, 23, 'Collect Points: 2,4,3,3,3,4,5,4,2 => 23';
+
+$p = run <./ch-2.raku 1 2 2 2 2 1>, :out;
+is $p.out.slurp(:close).chomp, 20, 'Collect Points: 1,2,2,2,2,1 => 20';
+
+$p = run <./ch-2.raku 1>, :out;
+is $p.out.slurp(:close).chomp, 1, 'Collect Points: 1 => 1';
+
+$p = run <./ch-2.raku 2 2 2 1 1 2 2 2>, :out;
+is $p.out.slurp(:close).chomp, 40, 'Collect Points: 2,2,2,1,1,2,2,2 => 40';
+
+# Task 2, Collect Points, Solution 2
+$p = run <./ch-2a.raku 2 4 3 3 3 4 5 4 2>, :out;
+is $p.out.slurp(:close).chomp, 23, 'Collect Points, Solution 2: 2,4,3,3,3,4,5,4,2 => 23';
+
+$p = run <./ch-2a.raku 1 2 2 2 2 1>, :out;
+is $p.out.slurp(:close).chomp, 20, 'Collect Points, Solution 2: 1,2,2,2,2,1 => 20';
+
+$p = run <./ch-2a.raku 1>, :out;
+is $p.out.slurp(:close).chomp, 1, 'Collect Points, Solution 2: 1 => 1';
+
+$p = run <./ch-2a.raku 2 2 2 1 1 2 2 2>, :out;
+is $p.out.slurp(:close).chomp, 40, 'Collect Points, Solution 2: 2,2,2,1,1,2,2,2 => 40';
+
+done-testing;