aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Bell_West <roger@firedrake.org>2025-08-26 10:37:53 +0100
committerRoger Bell_West <roger@firedrake.org>2025-08-26 10:37:53 +0100
commitdc8edbce44acf14d75959cb619be092b68f23c0c (patch)
treef87f305458cbd0b4e4560abe389aa924da82ce39
parentcfe111699674dcbdae6a9172888ec4a0cf5ca4c1 (diff)
downloadperlweeklychallenge-club-dc8edbce44acf14d75959cb619be092b68f23c0c.tar.gz
perlweeklychallenge-club-dc8edbce44acf14d75959cb619be092b68f23c0c.tar.bz2
perlweeklychallenge-club-dc8edbce44acf14d75959cb619be092b68f23c0c.zip
RogerBW solutions for challenge no. 336
-rwxr-xr-xchallenge-336/roger-bell-west/crystal/ch-1.cr44
-rwxr-xr-xchallenge-336/roger-bell-west/crystal/ch-2.cr36
-rwxr-xr-xchallenge-336/roger-bell-west/javascript/ch-1.js68
-rwxr-xr-xchallenge-336/roger-bell-west/javascript/ch-2.js54
-rw-r--r--challenge-336/roger-bell-west/kotlin/ch-1.kt57
-rw-r--r--challenge-336/roger-bell-west/kotlin/ch-2.kt55
-rwxr-xr-xchallenge-336/roger-bell-west/lua/ch-1.lua87
-rwxr-xr-xchallenge-336/roger-bell-west/lua/ch-2.lua61
-rwxr-xr-xchallenge-336/roger-bell-west/perl/ch-1.pl32
-rwxr-xr-xchallenge-336/roger-bell-west/perl/ch-2.pl31
-rw-r--r--challenge-336/roger-bell-west/postscript/ch-1.ps202
-rw-r--r--challenge-336/roger-bell-west/postscript/ch-2.ps136
-rwxr-xr-xchallenge-336/roger-bell-west/python/ch-1.py37
-rwxr-xr-xchallenge-336/roger-bell-west/python/ch-2.py36
-rwxr-xr-xchallenge-336/roger-bell-west/raku/ch-1.p627
-rwxr-xr-xchallenge-336/roger-bell-west/raku/ch-2.p632
-rwxr-xr-xchallenge-336/roger-bell-west/ruby/ch-1.rb53
-rwxr-xr-xchallenge-336/roger-bell-west/ruby/ch-2.rb43
-rwxr-xr-xchallenge-336/roger-bell-west/rust/ch-1.rs43
-rwxr-xr-xchallenge-336/roger-bell-west/rust/ch-2.rs47
-rw-r--r--challenge-336/roger-bell-west/scala/ch-1.scala58
-rw-r--r--challenge-336/roger-bell-west/scala/ch-2.scala57
-rw-r--r--challenge-336/roger-bell-west/tests.json68
-rw-r--r--challenge-336/roger-bell-west/typst/ch-1.typ54
-rw-r--r--challenge-336/roger-bell-west/typst/ch-2.typ39
25 files changed, 1457 insertions, 0 deletions
diff --git a/challenge-336/roger-bell-west/crystal/ch-1.cr b/challenge-336/roger-bell-west/crystal/ch-1.cr
new file mode 100755
index 0000000000..8516a2d885
--- /dev/null
+++ b/challenge-336/roger-bell-west/crystal/ch-1.cr
@@ -0,0 +1,44 @@
+#! /usr/bin/crystal
+
+def counterify(a)
+ cc = Hash(Int32, Int32).new(default_value: 0)
+ a.each do |x|
+ cc[x] += 1
+ end
+ return cc
+end
+
+def equalgroup(a)
+ s = counterify(a)
+ v = s.values.to_set.to_a.sort
+ l = v[0]
+ if l < 2
+ return false
+ end
+ 2.upto(l) do |t|
+ if v.all? { |c| c % t == 0 }
+ return true
+ end
+ end
+ false
+end
+
+require "spec"
+
+describe "equalgroup" do
+ it "test_ex1" do
+ equalgroup([1, 1, 2, 2, 2, 2]).should eq true
+ end
+ it "test_ex2" do
+ equalgroup([1, 1, 1, 2, 2, 2, 3, 3]).should eq false
+ end
+ it "test_ex3" do
+ equalgroup([5, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7]).should eq true
+ end
+ it "test_ex4" do
+ equalgroup([1, 2, 3, 4]).should eq false
+ end
+ it "test_ex5" do
+ equalgroup([8, 8, 9, 9, 10, 10, 11, 11]).should eq true
+ end
+end
diff --git a/challenge-336/roger-bell-west/crystal/ch-2.cr b/challenge-336/roger-bell-west/crystal/ch-2.cr
new file mode 100755
index 0000000000..52abdbaa38
--- /dev/null
+++ b/challenge-336/roger-bell-west/crystal/ch-2.cr
@@ -0,0 +1,36 @@
+#! /usr/bin/crystal
+
+def finalscore(a)
+ p = Array(Int32).new
+ a.each do |n|
+ if n == "C"
+ p.pop
+ elsif n == "D"
+ p.push(2 * p[-1])
+ elsif n == "+"
+ p.push(p[-2] + p[-1])
+ else
+ p.push(n.to_i)
+ end
+ end
+ p.sum
+end
+
+require "spec"
+describe "finalscore" do
+ it "test_ex1" do
+ finalscore(["5", "2", "C", "D", "+"]).should eq 30
+ end
+ it "test_ex2" do
+ finalscore(["5", "-2", "4", "C", "D", "9", "+", "+"]).should eq 27
+ end
+ it "test_ex3" do
+ finalscore(["7", "D", "D", "C", "+", "3"]).should eq 45
+ end
+ it "test_ex4" do
+ finalscore(["-5", "-10", "+", "D", "C", "+"]).should eq -55
+ end
+ it "test_ex5" do
+ finalscore(["3", "6", "+", "D", "C", "8", "+", "D", "-2", "C", "+"]).should eq 128
+ end
+end
diff --git a/challenge-336/roger-bell-west/javascript/ch-1.js b/challenge-336/roger-bell-west/javascript/ch-1.js
new file mode 100755
index 0000000000..b18dd189a3
--- /dev/null
+++ b/challenge-336/roger-bell-west/javascript/ch-1.js
@@ -0,0 +1,68 @@
+#! /usr/bin/node
+
+"use strict"
+
+function counterify(a) {
+ let cc = new Map;
+ for (let x of a) {
+ if (!cc.has(x)) {
+ cc.set(x, 0);
+ }
+ cc.set(x, cc.get(x) + 1);
+ }
+ return cc;
+}
+
+function equalgroup(a) {
+ const s = counterify(a);
+ let v = [...new Set(s.values())];
+ v.sort();
+ const l = v[0];
+ if (l < 2) {
+ return false;
+ }
+ for (let t = 2; t <= l; t++) {
+ let all = true;
+ for (let c of v) {
+ if (c % t != 0) {
+ all = false;
+ break;
+ }
+ }
+ if (all) {
+ return true;
+ }
+ }
+ return false;
+}
+
+if (equalgroup([1, 1, 2, 2, 2, 2])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (!equalgroup([1, 1, 1, 2, 2, 2, 3, 3])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (equalgroup([5, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (!equalgroup([1, 2, 3, 4])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (equalgroup([8, 8, 9, 9, 10, 10, 11, 11])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write("\n");
diff --git a/challenge-336/roger-bell-west/javascript/ch-2.js b/challenge-336/roger-bell-west/javascript/ch-2.js
new file mode 100755
index 0000000000..c5b57475ee
--- /dev/null
+++ b/challenge-336/roger-bell-west/javascript/ch-2.js
@@ -0,0 +1,54 @@
+#! /usr/bin/node
+
+"use strict"
+
+function finalscore(a) {
+ let p = [];
+ for (let n of a) {
+ switch (n) {
+ case 'C':
+ p.pop();
+ break;
+ case 'D':
+ p.push(2 * p.at(-1));
+ break;
+ case '+':
+ p.push(p.at(-2) + p.at(-1));
+ break;
+ default:
+ p.push(parseInt(n));
+ }
+ }
+ return p.reduce((x, y) => x + y)
+}
+
+if (finalscore(['5', '2', 'C', 'D', '+']) == 30) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (finalscore(['5', '-2', '4', 'C', 'D', '9', '+', '+']) == 27) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (finalscore(['7', 'D', 'D', 'C', '+', '3']) == 45) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (finalscore(['-5', '-10', '+', 'D', 'C', '+']) == -55) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (finalscore(['3', '6', '+', 'D', 'C', '8', '+', 'D', '-2', 'C', '+']) == 128) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write("\n");
diff --git a/challenge-336/roger-bell-west/kotlin/ch-1.kt b/challenge-336/roger-bell-west/kotlin/ch-1.kt
new file mode 100644
index 0000000000..e430091fbc
--- /dev/null
+++ b/challenge-336/roger-bell-west/kotlin/ch-1.kt
@@ -0,0 +1,57 @@
+fun counterify(a: List<Int>): Map<Int, Int> {
+ var cc = mutableMapOf<Int, Int>().withDefault({0})
+ for (x in a) {
+ cc.set(x, cc.getValue(x) + 1)
+ }
+ return cc
+}
+
+fun equalgroup(a: List<Int>): Boolean {
+ val s = counterify(a)
+ val v = s.values.toSet().toList().sorted()
+ val l = v[0]
+ if (l < 2) {
+ return false
+ }
+ for (t in 2 .. l) {
+ if (v.all{c -> c % t == 0}) {
+ return true
+ }
+ }
+ return false
+}
+
+fun main() {
+
+ if (equalgroup(listOf(1, 1, 2, 2, 2, 2))) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (!equalgroup(listOf(1, 1, 1, 2, 2, 2, 3, 3))) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (equalgroup(listOf(5, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7))) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (!equalgroup(listOf(1, 2, 3, 4))) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (equalgroup(listOf(8, 8, 9, 9, 10, 10, 11, 11))) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ println("")
+
+}
diff --git a/challenge-336/roger-bell-west/kotlin/ch-2.kt b/challenge-336/roger-bell-west/kotlin/ch-2.kt
new file mode 100644
index 0000000000..2a98496e5d
--- /dev/null
+++ b/challenge-336/roger-bell-west/kotlin/ch-2.kt
@@ -0,0 +1,55 @@
+fun finalscore(a: List<String>): Int {
+ var p = ArrayList<Int>()
+ for (n in a) {
+ when (n) {
+ "C" -> {
+ p.removeLast()
+ }
+ "D" -> {
+ p.add(2 * p.last())
+ }
+ "+" -> {
+ p.add(p[p.size - 2] + p.last())
+ }
+ else -> {
+ p.add(n.toInt())
+ }
+ }
+ }
+ return p.sum()
+}
+
+fun main() {
+
+ if (finalscore(listOf("5", "2", "C", "D", "+")) == 30) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (finalscore(listOf("5", "-2", "4", "C", "D", "9", "+", "+")) == 27) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (finalscore(listOf("7", "D", "D", "C", "+", "3")) == 45) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (finalscore(listOf("-5", "-10", "+", "D", "C", "+")) == -55) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (finalscore(listOf("3", "6", "+", "D", "C", "8", "+", "D", "-2", "C", "+")) == 128) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ println("")
+
+}
diff --git a/challenge-336/roger-bell-west/lua/ch-1.lua b/challenge-336/roger-bell-west/lua/ch-1.lua
new file mode 100755
index 0000000000..0633038749
--- /dev/null
+++ b/challenge-336/roger-bell-west/lua/ch-1.lua
@@ -0,0 +1,87 @@
+#! /usr/bin/lua
+
+function counterify(a)
+ local cc = {}
+ for _, c in ipairs(a) do
+ if cc[c] == nil then
+ cc[c] = 0
+ end
+ cc[c] = cc[c] + 1
+ end
+ return cc
+end
+
+function keys(t)
+ local a = {}
+ for k, v in pairs(t) do
+ table.insert(a, k)
+ end
+ return a
+end
+
+function all(tab, func)
+ for _, v in ipairs(tab) do
+ if not func(v) then
+ return false
+ end
+ end
+ return true
+end
+
+function equalgroup(a)
+ local s = counterify(a)
+ local vv = {}
+ for _, sv in pairs(s) do
+ vv[sv] = true
+ end
+ local v = keys(vv)
+ table.sort(v)
+ local l = v[1]
+ if l < 2 then
+ return false
+ end
+ for t = 2, l do
+ if all(v, function(c)
+ return c % t == 0
+ end) then
+ return true
+ end
+ end
+ return false
+end
+
+if equalgroup({1, 1, 2, 2, 2, 2}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if not equalgroup({1, 1, 1, 2, 2, 2, 3, 3}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if equalgroup({5, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if not equalgroup({1, 2, 3, 4}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if equalgroup({8, 8, 9, 9, 10, 10, 11, 11}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+print("")
+
diff --git a/challenge-336/roger-bell-west/lua/ch-2.lua b/challenge-336/roger-bell-west/lua/ch-2.lua
new file mode 100755
index 0000000000..ad37f25fe2
--- /dev/null
+++ b/challenge-336/roger-bell-west/lua/ch-2.lua
@@ -0,0 +1,61 @@
+#! /usr/bin/lua
+
+function sum(t)
+ local ss = 0
+ for i, k in ipairs(t) do
+ ss = ss + k
+ end
+ return ss
+end
+
+function finalscore(a)
+ local p = {}
+ for _, n in ipairs(a) do
+ if n == "C" then
+ table.remove(p, #p)
+ elseif n == "D" then
+ table.insert(p, 2 * p[#p])
+ elseif n == "+" then
+ table.insert(p, p[#p - 1] + p[#p])
+ else
+ table.insert(p, tonumber(n))
+ end
+ end
+ return sum(p)
+end
+
+if finalscore({"5", "2", "C", "D", "+"}) == 30 then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if finalscore({"5", "-2", "4", "C", "D", "9", "+", "+"}) == 27 then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if finalscore({"7", "D", "D", "C", "+", "3"}) == 45 then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if finalscore({"-5", "-10", "+", "D", "C", "+"}) == -55 then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if finalscore({"3", "6", "+", "D", "C", "8", "+", "D", "-2", "C", "+"}) == 128 then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+print("")
+
diff --git a/challenge-336/roger-bell-west/perl/ch-1.pl b/challenge-336/roger-bell-west/perl/ch-1.pl
new file mode 100755
index 0000000000..65cb57ca98
--- /dev/null
+++ b/challenge-336/roger-bell-west/perl/ch-1.pl
@@ -0,0 +1,32 @@
+#! /usr/bin/perl
+
+use strict;
+use warnings;
+use experimental 'signatures';
+
+use Test::More tests => 5;
+
+is(equalgroup([1, 1, 2, 2, 2, 2]), 1, 'example 1');
+is(equalgroup([1, 1, 1, 2, 2, 2, 3, 3]), 0, 'example 2');
+is(equalgroup([5, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7]), 1, 'example 3');
+is(equalgroup([1, 2, 3, 4]), 0, 'example 4');
+is(equalgroup([8, 8, 9, 9, 10, 10, 11, 11]), 1, 'example 5');
+
+use List::Util qw(all);
+use List::MoreUtils qw(uniq);
+
+sub equalgroup($a) {
+ my %s;
+ map {$s{$_}++} @{$a};
+ my @v = sort {$::a <=> $::b} uniq values %s;
+ my $l = $v[0];
+ if ($l < 2) {
+ return 0;
+ }
+ foreach my $t (2 .. $l) {
+ if (all {$_ % $t == 0} @v) {
+ return 1;
+ }
+ }
+ 0;
+}
diff --git a/challenge-336/roger-bell-west/perl/ch-2.pl b/challenge-336/roger-bell-west/perl/ch-2.pl
new file mode 100755
index 0000000000..11b1eddb2e
--- /dev/null
+++ b/challenge-336/roger-bell-west/perl/ch-2.pl
@@ -0,0 +1,31 @@
+#! /usr/bin/perl
+
+use strict;
+use warnings;
+use experimental 'signatures';
+
+use Test::More tests => 5;
+
+is(finalscore(['5', '2', 'C', 'D', '+']), 30, 'example 1');
+is(finalscore(['5', '-2', '4', 'C', 'D', '9', '+', '+']), 27, 'example 2');
+is(finalscore(['7', 'D', 'D', 'C', '+', '3']), 45, 'example 3');
+is(finalscore(['-5', '-10', '+', 'D', 'C', '+']), -55, 'example 4');
+is(finalscore(['3', '6', '+', 'D', 'C', '8', '+', 'D', '-2', 'C', '+']), 128, 'example 5');
+
+use List::Util qw(sum);
+
+sub finalscore($a) {
+ my @p;
+ foreach my $n (@{$a}) {
+ if ($n eq 'C') {
+ pop @p;
+ } elsif ($n eq 'D') {
+ push @p, $p[-1] * 2;
+ } elsif ($n eq '+') {
+ push @p, $p[-2] + $p[-1];
+ } else {
+ push @p, 0 + $n;
+ }
+ }
+ sum @p;
+}
diff --git a/challenge-336/roger-bell-west/postscript/ch-1.ps b/challenge-336/roger-bell-west/postscript/ch-1.ps
new file mode 100644
index 0000000000..17960ae906
--- /dev/null
+++ b/challenge-336/roger-bell-west/postscript/ch-1.ps
@@ -0,0 +1,202 @@
+%!PS
+
+% begin included library code
+% see https://codeberg.org/Firedrake/postscript-libraries/
+/keys { % dict -> array of dict keys
+ [ exch
+ {
+ pop
+ } forall
+ ]
+} bind def
+
+/test {
+ /test.count test.count 1 add def
+ {
+ /test.pass test.pass 1 add def
+ } {
+ ( ) print
+ test.count (....) cvs print
+ (-fail) print
+ } ifelse
+} bind def
+
+/toset { % array -> dict of (value, true)
+ << exch
+ {
+ true
+ } forall
+ >>
+} bind def
+
+/quicksort.main { % lo hi -> (null)
+ 3 dict begin
+ /hi exch def
+ /lo exch def
+ /xit false def
+ lo 0 lt {
+ /xit true def
+ } if
+ hi 0 lt {
+ /xit true def
+ } if
+ lo hi ge {
+ /xit true def
+ } if
+ xit not {
+ /p quicksort.partition def
+ lo p quicksort.main
+ p 1 add hi quicksort.main
+ } if
+ end
+} bind def
+
+/quicksort.partition {
+ 3 dict begin
+ /pivot arr hi lo add 2 idiv get def
+ /i lo 1 sub def
+ /j hi 1 add def
+ {
+ {
+ /i i 1 add def
+ arr i get pivot cmp 0 ge {
+ exit
+ } if
+ } loop
+ {
+ /j j 1 sub def
+ arr j get pivot cmp 0 le {
+ exit
+ } if
+ } loop
+ i j ge {
+ j
+ exit
+ } if
+ i j quicksort.swap
+ } loop
+ end
+} bind def
+
+/values { % dict -> array of dict values
+ [ exch
+ {
+ exch pop
+ } forall
+ ]
+} bind def
+
+/quicksort.with_comparator { % [ a c b ] { comparator } -> [ a b c ]
+ 2 dict begin
+ /cmp exch def
+ /arr exch def
+ arr length 0 gt {
+ 0 arr length 1 sub quicksort.main
+ } if
+ arr
+ end
+} bind def
+
+/all { % [a b] proc -> bool
+ 1 dict begin
+ /p exch def
+ true exch
+ {
+ p not {
+ pop false
+ exit
+ } if
+ } forall
+ end
+} bind def
+
+/test.end {
+ ( ) print
+ test.count 0 gt {
+ (Passed ) print
+ test.pass (...) cvs print
+ (/) print
+ test.count (...) cvs print
+ ( \() print
+ test.pass 100 mul test.count idiv (...) cvs print
+ (%\)) print
+ (\r\n) print
+ } if
+} bind def
+
+/quicksort.swap {
+ 2 dict begin
+ /bi exch def
+ /ai exch def
+ arr ai get
+ arr bi get
+ arr exch ai exch put
+ arr exch bi exch put
+ end
+} bind def
+
+/quicksort.cmp {
+ 2 copy
+ lt {
+ pop pop -1
+ } {
+ gt {
+ 1
+ } {
+ 0
+ } ifelse
+ } ifelse
+} bind def
+
+/quicksort {
+ { quicksort.cmp } quicksort.with_comparator
+} bind def
+
+/test.start {
+ print (:) print
+ /test.pass 0 def
+ /test.count 0 def
+} bind def
+
+
+% end included library code
+
+/counterify {
+ 2 dict begin
+ /c 0 dict def
+ {
+ /n exch def
+ c n known {
+ c n 2 copy get 1 add put
+ } {
+ c n 1 put
+ } ifelse
+ } forall
+ c
+ end
+} bind def
+
+/equalgroup {
+ 0 dict begin
+ counterify values toset keys quicksort /v exch def
+ /l v 0 get def
+ false
+ l 2 ge {
+ 2 1 l {
+ /t exch def
+ v { t mod 0 eq } all {
+ pop true
+ exit
+ } if
+ } for
+ } if
+ end
+} bind def
+
+(equalgroup) test.start
+[1 1 2 2 2 2] equalgroup test
+[1 1 1 2 2 2 3 3] equalgroup not test
+[5 5 5 5 5 5 7 7 7 7 7 7] equalgroup test
+[1 2 3 4] equalgroup not test
+[8 8 9 9 10 10 11 11] equalgroup test
+test.end
diff --git a/challenge-336/roger-bell-west/postscript/ch-2.ps b/challenge-336/roger-bell-west/postscript/ch-2.ps
new file mode 100644
index 0000000000..4b624ed995
--- /dev/null
+++ b/challenge-336/roger-bell-west/postscript/ch-2.ps
@@ -0,0 +1,136 @@
+%!PS
+
+% begin included library code
+% see https://codeberg.org/Firedrake/postscript-libraries/
+/reduce { % array proc -> value
+ 2 dict begin
+ /p exch def
+ /a exch def
+ a 0 get
+ 1 1 a length 1 sub {
+ a exch get
+ p
+ } for
+ end
+} bind def
+
+/deepeq {
+ 2 dict begin
+ /a exch def
+ /b exch def
+ a type b type eq {
+ a type /dicttype eq {
+ a length b length eq {
+ <<
+ a {
+ pop
+ true
+ } forall
+ b {
+ pop
+ true
+ } forall
+ >>
+ true exch
+ {
+ pop
+ dup a exch known {
+ dup b exch known {
+ dup a exch get exch b exch get deepeq not {
+ pop false
+ } if
+ } {
+ false
+ } ifelse
+ } {
+ false
+ } ifelse
+ } forall
+ } {
+ false
+ } ifelse
+ } {
+ a type dup /arraytype eq exch /stringtype eq or {
+ a length b length eq {
+ true
+ 0 1 a length 1 sub {
+ dup a exch get exch b exch get deepeq not {
+ pop false
+ exit
+ } if
+ } for
+ } {
+ false
+ } ifelse
+ } {
+ a b eq
+ } ifelse
+ } ifelse
+ } {
+ false
+ } ifelse
+ end
+} bind def
+
+/test {
+ /test.count test.count 1 add def
+ {
+ /test.pass test.pass 1 add def
+ } {
+ ( ) print
+ test.count (....) cvs print
+ (-fail) print
+ } ifelse
+} bind def
+
+/test.end {
+ ( ) print
+ test.count 0 gt {
+ (Passed ) print
+ test.pass (...) cvs print
+ (/) print
+ test.count (...) cvs print
+ ( \() print
+ test.pass 100 mul test.count idiv (...) cvs print
+ (%\)) print
+ (\r\n) print
+ } if
+} bind def
+
+/test.start {
+ print (:) print
+ /test.pass 0 def
+ /test.count 0 def
+} bind def
+
+
+% end included library code
+
+/finalscore {
+ [ exch
+ {
+ /n exch def
+ n (C) deepeq {
+ pop
+ } {
+ n (D) deepeq {
+ dup 2 mul
+ } {
+ n (+) deepeq {
+ 2 copy add
+ } {
+ n cvi
+ } ifelse
+ } ifelse
+ } ifelse
+ } forall
+ ] { add } reduce
+} bind def
+
+(finalscore) test.start
+[(5) (2) (C) (D) (+)] finalscore 30 eq test
+[(5) (-2) (4) (C) (D) (9) (+) (+)] finalscore 27 eq test
+[(7) (D) (D) (C) (+) (3)] finalscore 45 eq test
+[(-5) (-10) (+) (D) (C) (+)] finalscore -55 eq test
+[(3) (6) (+) (D) (C) (8) (+) (D) (-2) (C) (+)] finalscore 128 eq test
+test.end
diff --git a/challenge-336/roger-bell-west/python/ch-1.py b/challenge-336/roger-bell-west/python/ch-1.py
new file mode 100755
index 0000000000..9ba514782a
--- /dev/null
+++ b/challenge-336/roger-bell-west/python/ch-1.py
@@ -0,0 +1,37 @@
+#! /usr/bin/python3
+
+from collections import defaultdict
+
+def equalgroup(a):
+ s = defaultdict(lambda: 0)
+ for n in a:
+ s[n] += 1
+ v = sorted(list(set(s.values())))
+ l = v[0]
+ if l < 2:
+ return False
+ for t in range(2, l + 1):
+ if all(c % t == 0 for c in v):
+ return True
+ return False
+
+import unittest
+
+class TestEqualgroup(unittest.TestCase):
+
+ def test_ex1(self):
+ self.assertEqual(equalgroup([1, 1, 2, 2, 2, 2]), True, 'example 1')
+
+ def test_ex2(self):
+ self.assertEqual(equalgroup([1, 1, 1, 2, 2, 2, 3, 3]), False, 'example 2')
+
+ def test_ex3(self):
+ self.assertEqual(equalgroup([5, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7]), True, 'example 3')
+
+ def test_ex4(self):
+ self.assertEqual(equalgroup([1, 2, 3, 4]), False, 'example 4')
+
+ def test_ex5(self):
+ self.assertEqual(equalgroup([8, 8, 9, 9, 10, 10, 11, 11]), True, 'example 5')
+
+unittest.main()
diff --git a/challenge-336/roger-bell-west/python/ch-2.py b/challenge-336/roger-bell-west/python/ch-2.py
new file mode 100755
index 0000000000..da264be42b
--- /dev/null
+++ b/challenge-336/roger-bell-west/python/ch-2.py
@@ -0,0 +1,36 @@
+#! /usr/bin/python3
+
+def finalscore(a):
+ p = []
+ for n in a:
+ match n:
+ case "C":
+ p.pop()
+ case "D":
+ p.append(2 * p[-1])
+ case "+":
+ p.append(p[-2] + p[-1])
+ case _:
+ p.append(int(n))
+ return sum(p)
+
+import unittest
+
+class TestFinalscore(unittest.TestCase):
+
+ def test_ex1(self):
+ self.assertEqual(finalscore(["5", "2", "C", "D", "+"]), 30, 'example 1')
+
+ def test_ex2(self):
+ self.assertEqual(finalscore(["5", "-2", "4", "C", "D", "9", "+", "+"]), 27, 'example 2')
+
+ def test_ex3(self):
+ self.assertEqual(finalscore(["7", "D", "D", "C", "+", "3"]), 45, 'example 3')
+
+ def test_ex4(self):
+ self.assertEqual(finalscore(["-5", "-10", "+", "D", "C", "+"]), -55, 'example 4')
+
+ def test_ex5(self):
+ self.assertEqual(finalscore(["3", "6", "+", "D", "C", "8", "+", "D", "-2", "C", "+"]), 128, 'example 5')
+
+unittest.main()
diff --git a/challenge-336/roger-bell-west/raku/ch-1.p6 b/challenge-336/roger-bell-west/raku/ch-1.p6
new file mode 100755
index 0000000000..4e7b68ffef
--- /dev/null
+++ b/challenge-336/roger-bell-west/raku/ch-1.p6
@@ -0,0 +1,27 @@
+#! /usr/bin/raku