aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad Sajid Anwar <Mohammad.Anwar@yahoo.com>2025-09-02 13:31:21 +0100
committerGitHub <noreply@github.com>2025-09-02 13:31:21 +0100
commitc259465268655197faba309d2f25f3d4ea9aed8e (patch)
tree2f687e2dd3840e0c83b52c433573485a99155317
parentd9c3e9bfe9042e96da151b666faa28e08a2bb5dc (diff)
parent7a82574a741ed3fa340a24b8ad6cfdb9c93a78a9 (diff)
downloadperlweeklychallenge-club-c259465268655197faba309d2f25f3d4ea9aed8e.tar.gz
perlweeklychallenge-club-c259465268655197faba309d2f25f3d4ea9aed8e.tar.bz2
perlweeklychallenge-club-c259465268655197faba309d2f25f3d4ea9aed8e.zip
Merge pull request #12620 from Firedrake/rogerbw-challenge-337
RogerBW solutions for challenge no. 337
-rwxr-xr-xchallenge-337/roger-bell-west/crystal/ch-1.cr31
-rwxr-xr-xchallenge-337/roger-bell-west/crystal/ch-2.cr39
-rwxr-xr-xchallenge-337/roger-bell-west/javascript/ch-1.js73
-rwxr-xr-xchallenge-337/roger-bell-west/javascript/ch-2.js52
-rw-r--r--challenge-337/roger-bell-west/kotlin/ch-1.kt45
-rw-r--r--challenge-337/roger-bell-west/kotlin/ch-2.kt52
-rwxr-xr-xchallenge-337/roger-bell-west/lua/ch-1.lua85
-rwxr-xr-xchallenge-337/roger-bell-west/lua/ch-2.lua65
-rwxr-xr-xchallenge-337/roger-bell-west/perl/ch-1.pl24
-rwxr-xr-xchallenge-337/roger-bell-west/perl/ch-2.pl32
-rw-r--r--challenge-337/roger-bell-west/postscript/ch-1.ps267
-rw-r--r--challenge-337/roger-bell-west/postscript/ch-2.ps73
-rwxr-xr-xchallenge-337/roger-bell-west/python/ch-1.py31
-rwxr-xr-xchallenge-337/roger-bell-west/python/ch-2.py36
-rwxr-xr-xchallenge-337/roger-bell-west/raku/ch-1.p622
-rwxr-xr-xchallenge-337/roger-bell-west/raku/ch-2.p629
-rwxr-xr-xchallenge-337/roger-bell-west/ruby/ch-1.rb38
-rwxr-xr-xchallenge-337/roger-bell-west/ruby/ch-2.rb68
-rwxr-xr-xchallenge-337/roger-bell-west/rust/ch-1.rs41
-rwxr-xr-xchallenge-337/roger-bell-west/rust/ch-2.rs50
-rw-r--r--challenge-337/roger-bell-west/scala/ch-1.scala47
-rw-r--r--challenge-337/roger-bell-west/scala/ch-2.scala55
-rw-r--r--challenge-337/roger-bell-west/tests.json73
-rw-r--r--challenge-337/roger-bell-west/typst/ch-1.typ35
-rw-r--r--challenge-337/roger-bell-west/typst/ch-2.typ43
25 files changed, 1406 insertions, 0 deletions
diff --git a/challenge-337/roger-bell-west/crystal/ch-1.cr b/challenge-337/roger-bell-west/crystal/ch-1.cr
new file mode 100755
index 0000000000..28347ee415
--- /dev/null
+++ b/challenge-337/roger-bell-west/crystal/ch-1.cr
@@ -0,0 +1,31 @@
+#! /usr/bin/crystal
+
+def smallerthancurrent(a)
+ b = a.sort()
+ m = Hash(Int32, Int32).new
+ b.each_with_index do |v, i|
+ if !m.has_key?(v)
+ m[v] = i
+ end
+ end
+ a.map{|x| m[x]}
+end
+
+require "spec"
+describe "smallerthancurrent" do
+ it "test_ex1" do
+ smallerthancurrent([6, 5, 4, 8]).should eq [2, 1, 0, 3]
+ end
+ it "test_ex2" do
+ smallerthancurrent([7, 7, 7, 7]).should eq [0, 0, 0, 0]
+ end
+ it "test_ex3" do
+ smallerthancurrent([5, 4, 3, 2, 1]).should eq [4, 3, 2, 1, 0]
+ end
+ it "test_ex4" do
+ smallerthancurrent([-1, 0, 3, -2, 1]).should eq [1, 2, 4, 0, 3]
+ end
+ it "test_ex5" do
+ smallerthancurrent([0, 1, 1, 2, 0]).should eq [0, 2, 2, 4, 0]
+ end
+end
diff --git a/challenge-337/roger-bell-west/crystal/ch-2.cr b/challenge-337/roger-bell-west/crystal/ch-2.cr
new file mode 100755
index 0000000000..92301cc1ab
--- /dev/null
+++ b/challenge-337/roger-bell-west/crystal/ch-2.cr
@@ -0,0 +1,39 @@
+#! /usr/bin/crystal
+
+def oddmatrix(rows, cols, points)
+ rm = Set(Int32).new
+ cm = Set(Int32).new
+ points.each do |p|
+ if rm.includes?(p[0])
+ rm.delete(p[0])
+ else
+ rm.add(p[0])
+ end
+ if cm.includes?(p[1])
+ cm.delete(p[1])
+ else
+ cm.add(p[1])
+ end
+ end
+ rm.size * (cols - cm.size) +
+ cm.size * (rows - rm.size)
+end
+
+require "spec"
+describe "oddmatrix" do
+ it "test_ex1" do
+ oddmatrix(2, 3, [[0, 1], [1, 1]]).should eq 6
+ end
+ it "test_ex2" do
+ oddmatrix(2, 2, [[1, 1], [0, 0]]).should eq 0
+ end
+ it "test_ex3" do
+ oddmatrix(3, 3, [[0, 0], [1, 2], [2, 1]]).should eq 0
+ end
+ it "test_ex4" do
+ oddmatrix(1, 5, [[0, 2], [0, 4]]).should eq 2
+ end
+ it "test_ex5" do
+ oddmatrix(4, 2, [[1, 0], [3, 1], [2, 0], [0, 1]]).should eq 8
+ end
+end
diff --git a/challenge-337/roger-bell-west/javascript/ch-1.js b/challenge-337/roger-bell-west/javascript/ch-1.js
new file mode 100755
index 0000000000..9c51c05c65
--- /dev/null
+++ b/challenge-337/roger-bell-west/javascript/ch-1.js
@@ -0,0 +1,73 @@
+#! /usr/bin/node
+
+"use strict"
+
+function smallerthancurrent(a) {
+ let b = [...a];
+ b.sort(function(a, b) {return a-b});
+ let m = new Map;
+ b.forEach((v, i) => {
+ if (!m.has(v)) {
+ m.set(v, i);
+ }
+ });
+ return a.map( x => m.get(x) );
+}
+
+// by Frank Tan
+// https://stackoverflow.com/questions/38400594/javascript-deep-comparison
+function deepEqual(a,b)
+{
+ if( (typeof a == 'object' && a != null) &&
+ (typeof b == 'object' && b != null) )
+ {
+ var count = [0,0];
+ for( var key in a) count[0]++;
+ for( var key in b) count[1]++;
+ if( count[0]-count[1] != 0) {return false;}
+ for( var key in a)
+ {
+ if(!(key in b) || !deepEqual(a[key],b[key])) {return false;}
+ }
+ for( var key in b)
+ {
+ if(!(key in a) || !deepEqual(b[key],a[key])) {return false;}
+ }
+ return true;
+ }
+ else
+ {
+ return a === b;
+ }
+}
+
+if (deepEqual(smallerthancurrent([6, 5, 4, 8]), [2, 1, 0, 3])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (deepEqual(smallerthancurrent([7, 7, 7, 7]), [0, 0, 0, 0])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (deepEqual(smallerthancurrent([5, 4, 3, 2, 1]), [4, 3, 2, 1, 0])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (deepEqual(smallerthancurrent([-1, 0, 3, -2, 1]), [1, 2, 4, 0, 3])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (deepEqual(smallerthancurrent([0, 1, 1, 2, 0]), [0, 2, 2, 4, 0])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write("\n");
diff --git a/challenge-337/roger-bell-west/javascript/ch-2.js b/challenge-337/roger-bell-west/javascript/ch-2.js
new file mode 100755
index 0000000000..d1f0677096
--- /dev/null
+++ b/challenge-337/roger-bell-west/javascript/ch-2.js
@@ -0,0 +1,52 @@
+#! /usr/bin/node
+
+"use strict"
+
+function oddmatrix(rows, cols, points) {
+ let rm = new Set;
+ let cm = new Set;
+ for (let p of points) {
+ if (rm.has(p[0])) {
+ rm.delete(p[0]);
+ } else {
+ rm.add(p[0]);
+ }
+ if (cm.has(p[1])) {
+ cm.delete(p[1]);
+ } else {
+ cm.add(p[1]);
+ }
+ }
+ return rm.size * (cols - cm.size) + cm.size * (rows - rm.size);
+}
+
+if (oddmatrix(2, 3, [[0, 1], [1, 1]]) == 6) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (oddmatrix(2, 2, [[1, 1], [0, 0]]) == 0) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (oddmatrix(3, 3, [[0, 0], [1, 2], [2, 1]]) == 0) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (oddmatrix(1, 5, [[0, 2], [0, 4]]) == 2) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (oddmatrix(4, 2, [[1, 0], [3, 1], [2, 0], [0, 1]]) == 8) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write("\n");
diff --git a/challenge-337/roger-bell-west/kotlin/ch-1.kt b/challenge-337/roger-bell-west/kotlin/ch-1.kt
new file mode 100644
index 0000000000..2341884f7e
--- /dev/null
+++ b/challenge-337/roger-bell-west/kotlin/ch-1.kt
@@ -0,0 +1,45 @@
+fun smallerthancurrent(a: List<Int>): List<Int> {
+ val b = a.sorted()
+ var m = mutableMapOf<Int, Int>()
+ for ((i, v) in b.withIndex()) {
+ if (!m.contains(v)) {
+ m.put(v, i)
+ }
+ }
+ return a.map{ m.getValue(it) }.toList()
+}
+
+fun main() {
+
+ if (smallerthancurrent(listOf(6, 5, 4, 8)) == listOf(2, 1, 0, 3)) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (smallerthancurrent(listOf(7, 7, 7, 7)) == listOf(0, 0, 0, 0)) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (smallerthancurrent(listOf(5, 4, 3, 2, 1)) == listOf(4, 3, 2, 1, 0)) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (smallerthancurrent(listOf(-1, 0, 3, -2, 1)) == listOf(1, 2, 4, 0, 3)) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (smallerthancurrent(listOf(0, 1, 1, 2, 0)) == listOf(0, 2, 2, 4, 0)) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ println("")
+
+}
diff --git a/challenge-337/roger-bell-west/kotlin/ch-2.kt b/challenge-337/roger-bell-west/kotlin/ch-2.kt
new file mode 100644
index 0000000000..76cc20a5f1
--- /dev/null
+++ b/challenge-337/roger-bell-west/kotlin/ch-2.kt
@@ -0,0 +1,52 @@
+fun oddmatrix(rows: Int, cols: Int, points: List<List<Int>>): Int {
+ var rm = mutableSetOf<Int>()
+ var cm = mutableSetOf<Int>()
+ for (p in points) {
+ if (rm.contains(p[0])) {
+ rm.remove(p[0])
+ } else {
+ rm.add(p[0])
+ }
+ if (cm.contains(p[1])) {
+ cm.remove(p[1])
+ } else {
+ cm.add(p[1])
+ }
+ }
+ return rm.size * (cols - cm.size) + cm.size * (rows - rm.size)
+}
+
+fun main() {
+
+ if (oddmatrix(2, 3, listOf(listOf(0, 1), listOf(1, 1))) == 6) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (oddmatrix(2, 2, listOf(listOf(1, 1), listOf(0, 0))) == 0) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (oddmatrix(3, 3, listOf(listOf(0, 0), listOf(1, 2), listOf(2, 1))) == 0) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (oddmatrix(1, 5, listOf(listOf(0, 2), listOf(0, 4))) == 2) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (oddmatrix(4, 2, listOf(listOf(1, 0), listOf(3, 1), listOf(2, 0), listOf(0, 1))) == 8) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ println("")
+
+}
diff --git a/challenge-337/roger-bell-west/lua/ch-1.lua b/challenge-337/roger-bell-west/lua/ch-1.lua
new file mode 100755
index 0000000000..c0c8541010
--- /dev/null
+++ b/challenge-337/roger-bell-west/lua/ch-1.lua
@@ -0,0 +1,85 @@
+#! /usr/bin/lua
+
+function smallerthancurrent(a)
+ local b = {}
+ for _, x in ipairs(a) do
+ table.insert(b, x)
+ end
+ table.sort(b)
+ local m = {}
+ for i, v in ipairs(b) do
+ if m[v] == nil then
+ m[v] = i - 1
+ end
+ end
+ local out = {}
+ for _, x in ipairs(a) do
+ table.insert(out, m[x])
+ end
+ return out
+end
+
+-- by Michael Anderson at
+-- https://stackoverflow.com/questions/8722620/comparing-two-index-tables-by-index-value-in-lua
+-- modified by Roger
+function recursive_compare(t1,t2)
+ -- Use usual comparison first.
+ if t1==t2 then return true end
+ -- We only support non-default behavior for tables
+ if (type(t1)~="table") then return false end
+ -- They better have the same metatables
+ local mt1 = getmetatable(t1)
+ local mt2 = getmetatable(t2)
+ if( not recursive_compare(mt1,mt2) ) then return false end
+ -- Build list of all keys
+ local kk = {}
+ for k1, _ in pairs(t1) do
+ kk[k1] = true
+ end
+ for k2, _ in pairs(t2) do
+ kk[k2] = true
+ end
+ -- Check each key that exists in at least one table
+ for _, k in ipairs(kk) do
+ if (not recursive_compare(t1[k], t2[k])) then
+ return false
+ end
+ end
+ return true
+end
+
+if recursive_compare(smallerthancurrent({6, 5, 4, 8}), {2, 1, 0, 3}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if recursive_compare(smallerthancurrent({7, 7, 7, 7}), {0, 0, 0, 0}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if recursive_compare(smallerthancurrent({5, 4, 3, 2, 1}), {4, 3, 2, 1, 0}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if recursive_compare(smallerthancurrent({-1, 0, 3, -2, 1}), {1, 2, 4, 0, 3}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if recursive_compare(smallerthancurrent({0, 1, 1, 2, 0}), {0, 2, 2, 4, 0}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+print("")
+
diff --git a/challenge-337/roger-bell-west/lua/ch-2.lua b/challenge-337/roger-bell-west/lua/ch-2.lua
new file mode 100755
index 0000000000..946d52e7e8
--- /dev/null
+++ b/challenge-337/roger-bell-west/lua/ch-2.lua
@@ -0,0 +1,65 @@
+#! /usr/bin/lua
+
+function oddmatrix(rows, cols, points)
+ local rm = {}
+ local cm = {}
+ for _, p in ipairs(points) do
+ if rm[p[1]] == nil then
+ rm[p[1]] = true
+ else
+ rm[p[1]] = nil
+ end
+ if cm[p[2]] == nil then
+ cm[p[2]] = true
+ else
+ cm[p[2]] = nil
+ end
+ end
+ local cml = length(cm)
+ local rml = length(rm)
+ return rml * (cols - cml) + cml * (rows -rml)
+end
+
+function length(t)
+ local l = 0
+ for k, v in pairs(t) do
+ l = l + 1
+ end
+ return l
+end
+
+if oddmatrix(2, 3, {{0, 1}, {1, 1}}) == 6 then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if oddmatrix(2, 2, {{1, 1}, {0, 0}}) == 0 then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if oddmatrix(3, 3, {{0, 0}, {1, 2}, {2, 1}}) == 0 then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if oddmatrix(1, 5, {{0, 2}, {0, 4}}) == 2 then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if oddmatrix(4, 2, {{1, 0}, {3, 1}, {2, 0}, {0, 1}}) == 8 then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+print("")
+
diff --git a/challenge-337/roger-bell-west/perl/ch-1.pl b/challenge-337/roger-bell-west/perl/ch-1.pl
new file mode 100755
index 0000000000..4283c29a12
--- /dev/null
+++ b/challenge-337/roger-bell-west/perl/ch-1.pl
@@ -0,0 +1,24 @@
+#! /usr/bin/perl
+
+use strict;
+use warnings;
+use experimental 'signatures';
+
+use Test::More tests => 5;
+
+is_deeply(smallerthancurrent([6, 5, 4, 8]), [2, 1, 0, 3], 'example 1');
+is_deeply(smallerthancurrent([7, 7, 7, 7]), [0, 0, 0, 0], 'example 2');
+is_deeply(smallerthancurrent([5, 4, 3, 2, 1]), [4, 3, 2, 1, 0], 'example 3');
+is_deeply(smallerthancurrent([-1, 0, 3, -2, 1]), [1, 2, 4, 0, 3], 'example 4');
+is_deeply(smallerthancurrent([0, 1, 1, 2, 0]), [0, 2, 2, 4, 0], 'example 5');
+
+sub smallerthancurrent($a) {
+ my @b = sort {$::a <=> $::b} @{$a};
+ my %m;
+ while (my ($i, $v) = each @b) {
+ unless (exists $m{$v}) {
+ $m{$v} = $i;
+ }
+ }
+ return [map {$m{$_}} @{$a}];
+}
diff --git a/challenge-337/roger-bell-west/perl/ch-2.pl b/challenge-337/roger-bell-west/perl/ch-2.pl
new file mode 100755
index 0000000000..b9642dd43d
--- /dev/null
+++ b/challenge-337/roger-bell-west/perl/ch-2.pl
@@ -0,0 +1,32 @@
+#! /usr/bin/perl
+
+use strict;
+use warnings;
+use experimental 'signatures';
+
+use Test::More tests => 5;
+
+is(oddmatrix(2, 3, [[0, 1], [1, 1]]), 6, 'example 1');
+is(oddmatrix(2, 2, [[1, 1], [0, 0]]), 0, 'example 2');
+is(oddmatrix(3, 3, [[0, 0], [1, 2], [2, 1]]), 0, 'example 3');
+is(oddmatrix(1, 5, [[0, 2], [0, 4]]), 2, 'example 4');
+is(oddmatrix(4, 2, [[1, 0], [3, 1], [2, 0], [0, 1]]), 8, 'example 5');
+
+sub oddmatrix($rows, $cols, $points) {
+ my %rm;
+ my %cm;
+ foreach my $p (@{$points}) {
+ if (exists $rm{$p->[0]}) {
+ delete $rm{$p->[0]};
+ } else {
+ $rm{$p->[0]} = 1;
+ }
+ if (exists $cm{$p->[1]}) {
+ delete $cm{$p->[1]};
+ } else {
+ $cm{$p->[1]} = 1;
+ }
+ }
+ (scalar %rm) * ($cols - (scalar %cm)) +
+ (scalar %cm) * ($rows - (scalar %rm));
+}
diff --git a/challenge-337/roger-bell-west/postscript/ch-1.ps b/challenge-337/roger-bell-west/postscript/ch-1.ps
new file mode 100644
index 0000000000..4d07f49f91
--- /dev/null
+++ b/challenge-337/roger-bell-west/postscript/ch-1.ps
@@ -0,0 +1,267 @@
+%!PS
+
+% begin included library code
+% see https://codeberg.org/Firedrake/postscript-libraries/
+/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
+
+/quicksort {
+ { quicksort.cmp } quicksort.with_comparator
+} 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
+
+/keys { % dict -> array of dict keys
+ [ exch
+ {
+ pop
+ } forall
+ ]
+} bind def
+
+/enumerate.array {
+ 1 dict begin
+ /a exch def
+ [
+ 0 1 a length 1 sub {
+ [ exch dup a exch get ]
+ } 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
+
+/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
+
+/map { % array proc -> array
+ 2 dict begin
+ /p exch def
+ [ exch
+ {
+ p
+ } forall
+ ]
+ end
+} bind def
+
+/test.start {
+ print (:) print
+ /test.pass 0 def
+ /test.count 0 def
+} 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.cmp {
+ 2 copy
+ lt {
+ pop pop -1
+ } {
+ gt {
+ 1
+ } {
+ 0
+ } ifelse
+ } ifelse
+} 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
+
+/deepcopy {
+ 2 dict begin
+ /a exch def
+ a type /dicttype eq {
+ <<
+ a keys {
+ /k exch def
+ k
+ a k get deepcopy
+ } forall
+ >>
+ } {
+ a type /arraytype eq {
+ [
+ a {
+ deepcopy
+ } forall
+ ]
+ } {
+ a type /stringtype eq {
+ a dup length string cvs
+ } {
+ a
+ } ifelse
+ } ifelse
+ } 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
+
+
+% end included library code
+
+/smallerthancurrent {
+ 0 dict begin
+ /a exch def
+ /b a deepcopy quicksort def
+ /m 0 dict def
+ b enumerate.array {
+ aload pop
+ /v exch def
+ /i exch def
+ m v known not {
+ m v i put
+ } if
+ } forall
+ a { m exch get } map
+ end
+} bind def
+
+(smallerthancurrent) test.start
+[6 5 4 8] smallerthancurrent [2 1 0 3] deepeq test
+[7 7 7 7] smallerthancurrent [0 0 0 0] deepeq test
+[5 4 3 2 1] smallerthancurrent [4 3 2 1 0] deepeq test
+[-1 0 3 -2 1] smallerthancurrent [1 2 4 0 3] deepeq test
+[0 1 1 2 0] smallerthancurrent [0 2 2 4 0] deepeq test
+test.end
diff --git a/challenge-337/roger-bell-west/postscript/ch-2.ps b/challenge-337/roger-bell-west/postscript/ch-2.ps
new file mode 100644
index 0000000000..05832d6c6f
--- /dev/null
+++ b/challenge-337/roger-bell-west/postscript/ch-2.ps
@@ -0,0 +1,73 @@
+%!PS
+
+% begin included library code
+% see https://codeberg.org/Firedrake/postscript-libraries/
+/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 {
+ /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.start {
+ print (:) print
+ /test.pass 0 def
+ /test.count 0 def
+} bind def
+
+
+% end included library code
+
+/oddmatrix {
+ 0 dict begin
+ /points exch def
+ /cols exch def
+ /rows exch def
+ /rm 0 dict def
+ /cm 0 dict def
+ points {
+ aload pop
+ /p1 exch def
+ /p0 exch def
+ rm p0 known {
+ rm p0 undef
+ } {
+ rm p0 true put
+ } ifelse
+ cm p1 known {
+ cm p1 undef
+ } {
+ cm p1 true put
+ } ifelse
+ } forall
+ rm length cols cm length sub mul
+ cm length rows rm length sub mul
+ add
+ end
+} bind def
+
+(oddmatrix) test.start
+2 3 [[0 1] [1 1]] oddmatrix 6 eq test
+2 2 [[1 1] [0 0]] oddmatrix 0 eq test
+3 3 [[0 0] [1 2] [2 1]] oddmatrix 0 eq test
+1 5 [[0 2] [0 4]] oddmatrix 2 eq test
+4 2 [[1 0] [3 1] [2 0] [0 1]] oddmatrix 8 eq test
+test.end
diff --git a/challenge-337/roger-bell-west/python/ch-1.py b/challenge-337/roger-bell-west/python/ch-1.py
new file mode 100755
index 0000000000..7c7ba2fd5c
--- /dev/null
+++ b/challenge-337/roger-bell-west/python/ch-1.py
@@ -0,0 +1,31 @@
+#! /usr/bin/python3
+
+def smallerthancurrent(a):
+ b = a.copy()
+ b.sort()
+ m = dict()
+ for i, v in enumerate(b):
+ if v not in m:
+ m[v] = i
+ return [m[x] for x in a]
+
+import unittest
+
+class TestSmallerthancurrent(unittest.TestCase):
+
+ def test_ex1(self):
+ self.assertEqual(smallerthancurrent([6, 5, 4, 8]), [2, 1, 0, 3], 'example 1')
+
+ def test_ex2(self):
+ self.assertEqual(smallerthancurrent([7, 7, 7, 7]), [0, 0, 0, 0], 'example 2')
+
+ def test_ex3(self):
+ self.assertEqual(smallerthancurrent([5, 4, 3, 2, 1]), [4, 3, 2, 1, 0], 'example 3')
+
+ def test_ex4(self):
+ self.assertEqual(smallerthancurrent([-1, 0, 3, -2, 1]), [1, 2, 4, 0, 3], 'example 4')
+
+ def test_ex5(self):
+ self.assertEqual(smallerthancurrent([0, 1, 1, 2, 0]), [0, 2, 2, 4, 0], 'example 5')
+
+unittest.main()
diff --git a/challenge-337/roger-bell-west/python/ch-2.py b/challenge-337/roger-bell-west/python/ch-2.py
new file mode 100755
index 0000000000..1137f8491b
--- /dev/null
+++ b/challenge-337/roger-bell-west/python/ch-2.py
@@ -0,0 +1,36 @@
+#! /usr/bin/python3
+
+def oddmatrix(rows, cols, points):
+ rm = set()
+ cm = set()
+ for p in points:
+ if p[0] in rm:
+ rm.discard(p[0])
+ else:
+ rm.add(p[0])
+ if p[1] in cm:
+ cm.discard(p[1])
+ else:
+ cm.add(p[1])
+ return len(rm) * (cols - len(cm)) + len(cm) * (rows - len(rm))
+
+import unittest
+
+class TestOddmatrix(unittest.TestCase):
+
+ def test_ex1(self):
+ self.assertEqual(oddmatrix(2, 3, [[0, 1], [1, 1]]), 6, 'example 1')
+
+ def test_ex2(self):
+ self.assertEqual(oddmatrix(2, 2, [[1, 1], [0, 0]]), 0, 'example 2')
+
+ def test_ex3(self):
+ self.assertEqual(oddmatrix(3, 3, [[0, 0], [1, 2], [2, 1]]), 0, 'example 3')
+
+ def test_ex4(self):
+ self.assertEqual(oddmatrix(1, 5, [[0, 2], [0, 4]]), 2, 'example 4')
+
+ def test_ex5(self):
+ self.assertEqual(oddmatrix(4, 2, [[