aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad Sajid Anwar <Mohammad.Anwar@yahoo.com>2023-08-06 20:37:24 +0100
committerGitHub <noreply@github.com>2023-08-06 20:37:24 +0100
commit7e719c7e41b50a80c397f7542e2bb7eeae3d6068 (patch)
treeb55b5af11651e92e7e70b23fed5b6aeabf02d38f
parente26dc5c4bdc22e99de7aa3032cd3320cb87f5848 (diff)
parent9d5bac530f464cef9d19eac68a94e67e04a60acb (diff)
downloadperlweeklychallenge-club-7e719c7e41b50a80c397f7542e2bb7eeae3d6068.tar.gz
perlweeklychallenge-club-7e719c7e41b50a80c397f7542e2bb7eeae3d6068.tar.bz2
perlweeklychallenge-club-7e719c7e41b50a80c397f7542e2bb7eeae3d6068.zip
Merge pull request #8510 from Util/c228
Add TWC 228 solutions by Bruce Gray (Raku only).
-rw-r--r--challenge-228/bruce-gray/raku/ch-1.raku42
-rw-r--r--challenge-228/bruce-gray/raku/ch-2.raku65
2 files changed, 107 insertions, 0 deletions
diff --git a/challenge-228/bruce-gray/raku/ch-1.raku b/challenge-228/bruce-gray/raku/ch-1.raku
new file mode 100644
index 0000000000..51b9505529
--- /dev/null
+++ b/challenge-228/bruce-gray/raku/ch-1.raku
@@ -0,0 +1,42 @@
+# Bag, iterated by Pairs:
+sub task1a ( @ns --> UInt ) {
+ return @ns.Bag.map({ .key if .value == 1 }).sum;
+}
+
+# Set difference:
+sub task1b ( @ns --> UInt ) {
+ return ( @ns (-) @ns.repeated ).keys.sum;
+}
+
+# Single-pass:
+sub task1c ( @ns --> UInt ) {
+ my Bool %seen; # tri-state
+ my UInt $total = 0;
+
+ for @ns -> $n {
+ my $c = %seen{$n};
+
+ if $c { next }
+ elsif $c.defined { $total -= $n; %seen{$n} = True; }
+ else { $total += $n; %seen{$n} = False; }
+ }
+
+ return $total;
+}
+
+# Single-pass single-statement / Cosmic Horror with anonymous %seen hash:
+sub task1Z ( @ns --> UInt ) {
+ return sum map { $_ * (1,-1,0)[ %.{$_}++ min 2 ] }, @ns;
+}
+
+constant @tests = map { Hash.new: <in expected> Z=> .list },
+ ( (2, 1, 3, 2), 4 ),
+ ( (1, 1, 1, 1), 0 ),
+ ( (2, 1, 3, 4), 10 ),
+;
+constant @fs = :&task1a, :&task1b, :&task1c, :&task1Z;
+use Test;
+plan @fs*@tests;
+for @fs -> ( :key($f_name), :value(&f) ) {
+ is f(.<in>), .<expected>, "{$f_name} : {.<in>}" for @tests;
+}
diff --git a/challenge-228/bruce-gray/raku/ch-2.raku b/challenge-228/bruce-gray/raku/ch-2.raku
new file mode 100644
index 0000000000..286f9c130b
--- /dev/null
+++ b/challenge-228/bruce-gray/raku/ch-2.raku
@@ -0,0 +1,65 @@
+# Efficient - uses .sort to get all the minimums at once; no re-scanning for .min .
+sub task2a ( @ns --> UInt ) {
+ my @a = @ns;
+ my @s = @ns.sort;
+ my $r = 0;
+ while @a {
+ while @a[0] != @s[0] {
+ @a .= rotate;
+ $r++;
+ }
+ $r++;
+ shift @a;
+ shift @s;
+ }
+ return $r;
+}
+
+# Clearer/denser, but needs inefficient repeated calls to .min.
+sub task2b ( @ns ) {
+ my @a = @ns;
+
+ return sum gather while @a {
+ my $head = @a.shift;
+ @a.push: $head if $head > @a.min;
+ take 1;
+ }
+}
+
+# Concise evil; inefficent *and* overly subtle.
+# Note well the addition of the @ns element count
+# to the gathered sum!
+sub task2c ( @ns ) {
+ my @a = @ns;
+
+ return @ns + sum gather while @a {
+ @a = @a.rotate( take @a.minpairs[0].key ).skip;
+ }
+}
+
+# Hybrid evil; efficient and dense,
+# but uses side-effects and a
+# non-intuitive .first instead of a counter.
+sub task2d ( @ns ) {
+ my @a = @ns;
+ my @s = @ns.sort;
+
+ return first {
+ my $a_head = @a.shift;
+ if $a_head > @s.head { @a.push: $a_head }
+ else { @s.shift }
+ !@a;
+ }, 1..Inf;
+}
+
+
+constant @tests = map { Hash.new: <in expected> Z=> .list },
+ ( (3, 4, 2), 5 ),
+ ( (1, 2, 3), 3 ),
+;
+constant @fs = :&task2a, :&task2b, :&task2c, :&task2d;
+use Test;
+plan @fs * @tests;
+for @fs -> ( :key($f_name), :value(&f) ) {
+ is f(.<in>), .<expected>, "{$f_name} : {.<in>}" for @tests;
+}