aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad Sajid Anwar <Mohammad.Anwar@yahoo.com>2025-08-05 23:40:48 +0100
committerGitHub <noreply@github.com>2025-08-05 23:40:48 +0100
commita22bb8cbcd61aeacf38a434716538f112a6c6ad6 (patch)
tree665d07cc6b51402957d014c09f46683c0d2eb74d
parent153f22e7dc6b1860d8561da89efeeefdfa83eab9 (diff)
parenta57a3a568368c406944dd042728ed141b66a02a3 (diff)
downloadperlweeklychallenge-club-a22bb8cbcd61aeacf38a434716538f112a6c6ad6.tar.gz
perlweeklychallenge-club-a22bb8cbcd61aeacf38a434716538f112a6c6ad6.tar.bz2
perlweeklychallenge-club-a22bb8cbcd61aeacf38a434716538f112a6c6ad6.zip
Merge pull request #12473 from Firedrake/rogerbw-challenge-333
RogerBW solutions for challenge no. 333
-rwxr-xr-xchallenge-333/roger-bell-west/crystal/ch-1.cr44
-rwxr-xr-xchallenge-333/roger-bell-west/crystal/ch-2.cr37
-rwxr-xr-xchallenge-333/roger-bell-west/javascript/ch-1.js68
-rwxr-xr-xchallenge-333/roger-bell-west/javascript/ch-2.js78
-rw-r--r--challenge-333/roger-bell-west/kotlin/ch-1.kt55
-rw-r--r--challenge-333/roger-bell-west/kotlin/ch-2.kt51
-rwxr-xr-xchallenge-333/roger-bell-west/lua/ch-1.lua70
-rwxr-xr-xchallenge-333/roger-bell-west/lua/ch-2.lua83
-rwxr-xr-xchallenge-333/roger-bell-west/perl/ch-1.pl52
-rwxr-xr-xchallenge-333/roger-bell-west/perl/ch-2.pl30
-rw-r--r--challenge-333/roger-bell-west/postscript/ch-1.ps98
-rw-r--r--challenge-333/roger-bell-west/postscript/ch-2.ps115
-rwxr-xr-xchallenge-333/roger-bell-west/python/ch-1.py48
-rwxr-xr-xchallenge-333/roger-bell-west/python/ch-2.py34
-rwxr-xr-xchallenge-333/roger-bell-west/raku/ch-1.p650
-rwxr-xr-xchallenge-333/roger-bell-west/raku/ch-2.p628
-rwxr-xr-xchallenge-333/roger-bell-west/ruby/ch-1.rb52
-rwxr-xr-xchallenge-333/roger-bell-west/ruby/ch-2.rb44
-rwxr-xr-xchallenge-333/roger-bell-west/rust/ch-1.rs64
-rwxr-xr-xchallenge-333/roger-bell-west/rust/ch-2.rs47
-rw-r--r--challenge-333/roger-bell-west/scala/ch-1.scala58
-rw-r--r--challenge-333/roger-bell-west/scala/ch-2.scala49
-rw-r--r--challenge-333/roger-bell-west/tests.json44
-rw-r--r--challenge-333/roger-bell-west/typst/ch-1.typ47
-rw-r--r--challenge-333/roger-bell-west/typst/ch-2.typ40
25 files changed, 1386 insertions, 0 deletions
diff --git a/challenge-333/roger-bell-west/crystal/ch-1.cr b/challenge-333/roger-bell-west/crystal/ch-1.cr
new file mode 100755
index 0000000000..46e0894f1a
--- /dev/null
+++ b/challenge-333/roger-bell-west/crystal/ch-1.cr
@@ -0,0 +1,44 @@
+#! /usr/bin/crystal
+
+def straightline(a)
+ b = a.to_set.to_a
+ if b.size < 3
+ return true
+ end
+ p = b[0][0]
+ q = b[1][0] - b[0][0]
+ r = b[0][1]
+ s = b[1][1] - b[0][1]
+ b[2, b.size].each do |tpair|
+ if q == 0.0 && tpair[0] != b[0][0]
+ return false
+ end
+ if s == 0.0 && tpair[1] != b[0][1]
+ return false
+ end
+ if q != 0.0 && s != 0.0
+ n1 = (tpair[0] - p) / q
+ n2 = (tpair[1] - r) / s
+ if n1 != n2
+ return false
+ end
+ end
+ end
+ true
+end
+
+require "spec"
+describe "straightline" do
+ it "test_ex1" do
+ straightline([[2, 1], [2, 3], [2, 5]]).should eq true
+ end
+ it "test_ex2" do
+ straightline([[1, 4], [3, 4], [10, 4]]).should eq true
+ end
+ it "test_ex3" do
+ straightline([[0, 0], [1, 1], [2, 3]]).should eq false
+ end
+ it "test_ex4" do
+ straightline([[1, 1], [1, 1], [1, 1]]).should eq true
+ end
+end
diff --git a/challenge-333/roger-bell-west/crystal/ch-2.cr b/challenge-333/roger-bell-west/crystal/ch-2.cr
new file mode 100755
index 0000000000..0fd80ad1df
--- /dev/null
+++ b/challenge-333/roger-bell-west/crystal/ch-2.cr
@@ -0,0 +1,37 @@
+#! /usr/bin/crystal
+
+def duplicatezeros(a)
+ b = Array(Int32).new
+ a.each do |n|
+ b.push(n)
+ if a.size == b.size
+ break
+ end
+ if n == 0
+ b.push(0)
+ if a.size == b.size
+ break
+ end
+ end
+ end
+ b
+end
+
+require "spec"
+describe "duplicatezeros" do
+ it "test_ex1" do
+ duplicatezeros([1, 0, 2, 3, 0, 4, 5, 0]).should eq [1, 0, 0, 2, 3, 0, 0, 4]
+ end
+ it "test_ex2" do
+ duplicatezeros([1, 2, 3]).should eq [1, 2, 3]
+ end
+ it "test_ex3" do
+ duplicatezeros([1, 2, 3, 0]).should eq [1, 2, 3, 0]
+ end
+ it "test_ex4" do
+ duplicatezeros([0, 0, 1, 2]).should eq [0, 0, 0, 0]
+ end
+ it "test_ex5" do
+ duplicatezeros([1, 2, 0, 3, 4]).should eq [1, 2, 0, 0, 3]
+ end
+end
diff --git a/challenge-333/roger-bell-west/javascript/ch-1.js b/challenge-333/roger-bell-west/javascript/ch-1.js
new file mode 100755
index 0000000000..81a6e2af02
--- /dev/null
+++ b/challenge-333/roger-bell-west/javascript/ch-1.js
@@ -0,0 +1,68 @@
+#! /usr/bin/node
+
+"use strict"
+
+function straightline(a) {
+ let b = [];
+ for (let xy of a) {
+ let u = true;
+ for (let bxy of b) {
+ if (xy[0] == bxy[0] && xy[1] == bxy[1]) {
+ u = false;
+ break;
+ }
+ }
+ if (u) {
+ b.push(xy);
+ }
+ }
+ if (b.length < 3) {
+ return true;
+ }
+ const p = b[0][0];
+ const q = b[1][0] - b[0][0];
+ const r = b[0][1];
+ const s = b[1][1] - b[0][1];
+ for (let tp = 2; tp < b.length; b++) {
+ const tpair = b[tp];
+ if (q == 0 && tpair[0] != b[0][0]) {
+ return false;
+ }
+ if (s == 0 && tpair[1] != b[0][1]) {
+ return false;
+ }
+ if (q != 0 && s != 0) {
+ const n1 = (tpair[0] - p ) / q;
+ const n2 = (tpair[1] - r ) / s;
+ if (n1 != n2) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+if (straightline([[2, 1], [2, 3], [2, 5]])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (straightline([[1, 4], [3, 4], [10, 4]])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (!straightline([[0, 0], [1, 1], [2, 3]])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (straightline([[1, 1], [1, 1], [1, 1]])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write("\n");
diff --git a/challenge-333/roger-bell-west/javascript/ch-2.js b/challenge-333/roger-bell-west/javascript/ch-2.js
new file mode 100755
index 0000000000..899fd0576b
--- /dev/null
+++ b/challenge-333/roger-bell-west/javascript/ch-2.js
@@ -0,0 +1,78 @@
+#! /usr/bin/node
+
+"use strict"
+
+function duplicatezeros(a) {
+ let b = [];
+ for (let n of a) {
+ b.push(n)
+ if (a.length == b.length) {
+ break;
+ }
+ if (n == 0) {
+ b.push(0);
+ if (a.length == b.length) {
+ break;
+ }
+ }
+ }
+ return b
+}
+
+// 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(duplicatezeros([1, 0, 2, 3, 0, 4, 5, 0]), [1, 0, 0, 2, 3, 0, 0, 4])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (deepEqual(duplicatezeros([1, 2, 3]), [1, 2, 3])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (deepEqual(duplicatezeros([1, 2, 3, 0]), [1, 2, 3, 0])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (deepEqual(duplicatezeros([0, 0, 1, 2]), [0, 0, 0, 0])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (deepEqual(duplicatezeros([1, 2, 0, 3, 4]), [1, 2, 0, 0, 3])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write("\n");
diff --git a/challenge-333/roger-bell-west/kotlin/ch-1.kt b/challenge-333/roger-bell-west/kotlin/ch-1.kt
new file mode 100644
index 0000000000..fe02b12588
--- /dev/null
+++ b/challenge-333/roger-bell-west/kotlin/ch-1.kt
@@ -0,0 +1,55 @@
+fun straightline(a: List<List<Double>>): Boolean {
+ val b = a.distinct()
+ if (b.size < 3) {
+ return true
+ }
+ val p = b[0][0]
+ val q = b[1][0] - b[0][0]
+ val r = b[0][1]
+ val s = b[1][1] - b[0][1]
+ for (tpair in b.drop(2)) {
+ if (q == 0.0 && tpair[0] != b[0][0]) {
+ return false
+ }
+ if (s == 0.0 && tpair[1] != b[0][1]) {
+ return false
+ }
+ if (q != 0.0 && s != 0.0) {
+ val n1 = (tpair[0] - p ) / q
+ val n2 = (tpair[1] - r ) / s
+ if (n1 != n2) {
+ return false
+ }
+ }
+ }
+ return true
+}
+
+fun main() {
+
+ if (straightline(listOf(listOf(2.0, 1.0), listOf(2.0, 3.0), listOf(2.0, 5.0)))) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (straightline(listOf(listOf(1.0, 4.0), listOf(3.0, 4.0), listOf(10.0, 4.0)))) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (!straightline(listOf(listOf(0.0, 0.0), listOf(1.0, 1.0), listOf(2.0, 3.0)))) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (straightline(listOf(listOf(1.0, 1.0), listOf(1.0, 1.0), listOf(1.0, 1.0)))) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ println("")
+
+}
diff --git a/challenge-333/roger-bell-west/kotlin/ch-2.kt b/challenge-333/roger-bell-west/kotlin/ch-2.kt
new file mode 100644
index 0000000000..fa0b92a96c
--- /dev/null
+++ b/challenge-333/roger-bell-west/kotlin/ch-2.kt
@@ -0,0 +1,51 @@
+fun duplicatezeros(a: List<Int>): List<Int> {
+ var b = ArrayList<Int>()
+ for (n in a) {
+ b.add(n)
+ if (a.size == b.size) {
+ break
+ }
+ if (n == 0) {
+ b.add(0)
+ if (a.size == b.size) {
+ break
+ }
+ }
+ }
+ return b.toList()
+}
+
+fun main() {
+
+ if (duplicatezeros(listOf(1, 0, 2, 3, 0, 4, 5, 0)) == listOf(1, 0, 0, 2, 3, 0, 0, 4)) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (duplicatezeros(listOf(1, 2, 3)) == listOf(1, 2, 3)) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (duplicatezeros(listOf(1, 2, 3, 0)) == listOf(1, 2, 3, 0)) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (duplicatezeros(listOf(0, 0, 1, 2)) == listOf(0, 0, 0, 0)) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (duplicatezeros(listOf(1, 2, 0, 3, 4)) == listOf(1, 2, 0, 0, 3)) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ println("")
+
+}
diff --git a/challenge-333/roger-bell-west/lua/ch-1.lua b/challenge-333/roger-bell-west/lua/ch-1.lua
new file mode 100755
index 0000000000..7a5ff61942
--- /dev/null
+++ b/challenge-333/roger-bell-west/lua/ch-1.lua
@@ -0,0 +1,70 @@
+#! /usr/bin/lua
+
+function straightline(a)
+ local b = {}
+ for _, xy in ipairs(a) do
+ local u = true
+ for __, bxy in ipairs(b) do
+ if xy[1] == bxy[1] and xy[2] == bxy[2] then
+ u = false
+ break
+ end
+ end
+ if u then
+ table.insert(b, xy)
+ end
+ end
+ if #b < 3 then
+ return true
+ end
+ local p = b[1][1]
+ local q = b[2][1] - b[1][1]
+ local r = b[1][2]
+ local s = b[2][2] - b[1][2]
+ for tp = 2, #b do
+ local tpair = b[tp]
+ if q == 0 and tpair[1] ~= b[1][1] then
+ return false
+ end
+ if s == 0 and tpair[2] ~= b[1][2] then
+ return false
+ end
+ if q ~= 0 and s ~= 0 then
+ local n1 = (tpair[1] - p) / q
+ local n2 = (tpair[2] - r) / s
+ if n1 ~= n2 then
+ return false
+ end
+ end
+ end
+ return true
+end
+
+if straightline({{2, 1}, {2, 3}, {2, 5}}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if straightline({{1, 4}, {3, 4}, {10, 4}}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if not straightline({{0, 0}, {1, 1}, {2, 3}}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if straightline({{1, 1}, {1, 1}, {1, 1}}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+print("")
+
diff --git a/challenge-333/roger-bell-west/lua/ch-2.lua b/challenge-333/roger-bell-west/lua/ch-2.lua
new file mode 100755
index 0000000000..0496f2566a
--- /dev/null
+++ b/challenge-333/roger-bell-west/lua/ch-2.lua
@@ -0,0 +1,83 @@
+#! /usr/bin/lua
+
+-- 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
+
+function duplicatezeros(a)
+ local b = {}
+ for _, n in ipairs(a) do
+ table.insert(b, n)
+ if #a == #b then
+ break
+ end
+ if n == 0 then
+ table.insert(b, 0)
+ if #a == #b then
+ break
+ end
+ end
+ end
+ return b
+end
+
+if recursive_compare(duplicatezeros({1, 0, 2, 3, 0, 4, 5, 0}), {1, 0, 0, 2, 3, 0, 0, 4}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if recursive_compare(duplicatezeros({1, 2, 3}), {1, 2, 3}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if recursive_compare(duplicatezeros({1, 2, 3, 0}), {1, 2, 3, 0}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if recursive_compare(duplicatezeros({0, 0, 1, 2}), {0, 0, 0, 0}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if recursive_compare(duplicatezeros({1, 2, 0, 3, 4}), {1, 2, 0, 0, 3}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+print("")
+
diff --git a/challenge-333/roger-bell-west/perl/ch-1.pl b/challenge-333/roger-bell-west/perl/ch-1.pl
new file mode 100755
index 0000000000..fab3bf7dbe
--- /dev/null
+++ b/challenge-333/roger-bell-west/perl/ch-1.pl
@@ -0,0 +1,52 @@
+#! /usr/bin/perl
+
+use strict;
+use warnings;
+use experimental 'signatures';
+
+use Test::More tests => 4;
+
+is(straightline([[2, 1], [2, 3], [2, 5]]), 1, 'example 1');
+is(straightline([[1, 4], [3, 4], [10, 4]]), 1, 'example 2');
+is(straightline([[0, 0], [1, 1], [2, 3]]), 0, 'example 3');
+is(straightline([[1, 1], [1, 1], [1, 1]]), 1, 'example 4');
+
+sub straightline($a) {
+ my @b;
+ foreach my $xy (@{$a}) {
+ my $u = 1;
+ foreach my $bxy (@b) {
+ if ($xy->[0] == $bxy->[0] && $xy->[1] == $bxy->[1]) {
+ $u = 0;
+ last;
+ }
+ }
+ if ($u) {
+ push @b, $xy;
+ }
+ }
+ if (scalar @b < 3) {
+ return 1;
+ }
+ my $p = $b[0][0];
+ my $q = $b[1][0] - $b[0][0];
+ my $r = $b[0][1];
+ my $s = $b[1][1] - $b[0][1];
+ foreach my $tp (2 .. $#b) {
+ my $tpair = $b[$tp];
+ if ($q == 0 && $tpair->[0] != $b[0][0]) {
+ return 0;
+ }
+ if ($s == 0 && $tpair->[1] != $b[0][1]) {
+ return 0;
+ }
+ if ($q != 0 && $s != 0) {
+ my $n1 = ($tpair->[0] - $p ) / $q;
+ my $n2 = ($tpair->[1] - $r ) / $s;
+ if ($n1 != $n2) {
+ return 0;
+ }
+ }
+ }
+ 1;
+}
diff --git a/challenge-333/roger-bell-west/perl/ch-2.pl b/challenge-333/roger-bell-west/perl/ch-2.pl
new file mode 100755
index 0000000000..0be84b2fdd
--- /dev/null
+++ b/challenge-333/roger-bell-west/perl/ch-2.pl
@@ -0,0 +1,30 @@
+#! /usr/bin/perl
+
+use strict;
+use warnings;
+use experimental 'signatures';
+
+use Test::More tests => 5;
+
+is_deeply(duplicatezeros([1, 0, 2, 3, 0, 4, 5, 0]), [1, 0, 0, 2, 3, 0, 0, 4], 'example 1');
+is_deeply(duplicatezeros([1, 2, 3]), [1, 2, 3], 'example 2');
+is_deeply(duplicatezeros([1, 2, 3, 0]), [1, 2, 3, 0], 'example 3');
+is_deeply(duplicatezeros([0, 0, 1, 2]), [0, 0, 0, 0], 'example 4');
+is_deeply(duplicatezeros([1, 2, 0, 3, 4]), [1, 2, 0, 0, 3], 'example 5');
+
+sub duplicatezeros($a) {
+ my @b;
+ foreach my $n (@{$a}) {
+ push @b, $n;
+ if ($#{$a} ==$#b) {
+ last;
+ }
+ if ($n == 0) {
+ push @b, 0;
+ if ($#{$a} ==$#b) {
+ last;
+ }
+ }
+ }
+ \@b;
+}
diff --git a/challenge-333/roger-bell-west/postscript/ch-1.ps b/challenge-333/roger-bell-west/postscript/ch-1.ps
new file mode 100644
index 0000000000..86e75eca38
--- /dev/null
+++ b/challenge-333/roger-bell-west/postscript/ch-1.ps
@@ -0,0 +1,98 @@
+%!PS
+
+% begin included library code
+% see https://codeberg.org/Firedrake/postscript-libraries/
+/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
+
+/apush.right { % [a b] c -> [a b c]
+ exch
+ [ exch aload length 2 add -1 roll ]
+} bind def
+
+
+% end included library code
+
+/straightline {
+ 0 dict begin
+ /a exch def
+ /b 0 array def
+ a {
+ /xy exch def
+ /u true def
+ b {
+ /bxy exch def
+ xy 0 get bxy 0 get eq xy 1 get bxy 1 get eq and {
+ /u false def
+ exit
+ } if
+ } forall
+ u {
+ /b b xy apush.right def
+ } if
+ } forall
+ b length 3 lt {
+ true
+ } {
+ true
+ /p b 0 get 0 get def
+ /q b 1 get 0 get b 0 get 0 get sub def
+ /r b 0 get 1 get def
+ /s b 1 get 1 get b 0 get 1 get sub def
+ 2 1 b length 1 sub {
+ /tpair exch b exch get def
+ q 0 eq tpair 0 get b 0 get 0 get ne and {
+ pop false
+ exit
+ } if
+ s 0 eq tpair 1 get b 0 get 1 get ne and {
+ pop false
+ exit
+ } if
+ q 0 ne s 0 ne and {
+ tpair 0 get p sub q div
+ tpair 1 get r sub s div
+ ne {
+ pop false
+ exit
+ } if
+ } if
+ } for
+ } ifelse
+ end
+} bind def
+
+(straightline) test.start
+[[2 1] [2 3] [2 5]] straightline test
+[[1 4] [3 4] [10 4]] straightline test
+[[0 0] [1 1] [2 3]] straightline not test
+[[1 1] [1 1] [1 1]] straightline test
+test.end
diff --git a/challenge-333/roger-bell-west/postscript/ch-2.ps b/challenge-333/roger-bell-west/postscript/ch-2.ps
new file mode 100644
index 0000000000..f3737eeb59
--- /dev/null
+++ b/challenge-333/roger-bell-west/postscript/ch-2.ps
@@ -0,0 +1,115 @@
+%!PS
+
+% begin included library code
+% see https://codeberg.org/Firedrake/postscript-libraries/
+/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
+
+/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.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
+
+/duplicatezeros {
+ dup length exch
+ [ exch
+ {
+ dup 0 eq {
+ 0
+ } if
+ } forall
+ ]
+ exch 0 exch getinterval
+} bind def
+
+(duplicatezeros) test.start
+[1 0 2 3 0 4 5 0] duplicatezeros [1 0 0 2 3 0 0 4] deepeq test
+[1 2 3] duplicatezeros [1 2 3] deepeq test
+[1 2 3 0] duplicatezeros [1 2 3 0] deepeq test
+[0 0 1 2] duplicatezeros [0 0 0 0] deepeq test
+[1 2 0 3 4] duplicatezeros [1 2 0 0 3] deepeq test
+test.end
diff --git a/challenge-333/roger-bell-west/python/ch-1.py b/challenge-333/roger-bell-west/python/ch-1.py
new file mode 100755
index 0000000000..4887160e44
--- /dev/null
+++ b/challenge-333/roger-bell-west/python/ch-1.py
@@ -0,0 +1,48 @@
+#! /usr/bin/python3
+
+def straightline(a):
+ b = []
+ for xy in a:
+ u = True
+ for bxy in b:
+ if xy[0] == bxy[0] and xy[1] == bxy[1]:
+ u = False
+ break
+ if u:
+ b.append(xy)
+ if len(b) < 3:
+ return True
+ p = b[0][0]
+ q = b[1][0] - b[0][0]
+ r = b[0][1]
+ s = b[1][1] - b[0][1]
+ for tp in range(2, len(b)):
+ tpair = b[tp]
+ if q == 0. and tpair[0] != b[0][0]:
+ return False
+ if s == 0. and tpair[1] != b[0][1]:
+ return False
+ if q != 0 and s != 0:
+ n1 = (tpair[0] - p) / q
+ n2 = (tpair[1] - r) / s
+ if n1 != n2:
+ return False
+ return True
+
+import unittest
+
+class TestStraightline(unittest.TestCase):
+
+ def test_ex1(self):
+ self.assertEqual(straightline([[2, 1], [2, 3], [2, 5]]), True, 'example 1')
+
+ def test_ex2(self):
+ self.assertEqual(straightline([[1, 4], [3, 4], [10, 4]]), True, 'example 2')
+
+ def test_ex3(self):
+ self.assertEqual(straightline([[0, 0], [1, 1], [2, 3]]), False, 'example 3')
+
+ def test_ex4(self):
+ self.assertEqual(straightline([[1, 1], [1, 1], [1, 1]]), True, 'example 4')
+
+unittest.main()
diff --git a/challenge-333/roger-bell-west/python/ch-2.py b/challenge-333/roger-bell-west/python/ch-2.py
new file mode 100755
index 0000000000..6d94cdcea9
--- /dev/null
+++ b/challenge-333/roger-bell-west/python/ch-2.py
@@ -0,0 +1,34 @@
+#! /usr/bin/python3
+
+def duplicatezeros(a):
+ b = []
+ for n in a:
+ b.append(n)
+ if len(a) == len(b):
+ break
+ if n == 0:
+ b.append(0)
+ if len(a) == len(b):
+ break
+ return b
+
+import unittest
+
+class TestDuplicatezeros(unittest.TestCase):
+
+ def test_ex1(self):
+ self.assertEqual(duplicatezeros([1, 0, 2, 3, 0, 4, 5, 0]), [1, 0, 0, 2, 3, 0, 0, 4], 'example 1')
+
+ def test_ex2(self):
+ self.assertEqual(duplicatezeros([1, 2, 3]), [1, 2, 3], 'example 2')
+
+ def test_ex3(self):
+ self.assertEqual(duplicatezeros([1, 2, 3, 0]), [1, 2, 3, 0], 'example 3')
+
+ def test_ex4(self):
+ self.assertEqual(duplicatezeros([0, 0, 1, 2]), [0, 0, 0, 0], 'example 4')
+
+ def test_ex5(self):
+ self.assertEqual(duplicatezeros([1, 2, 0, 3, 4]), [1, 2, 0, 0, 3], 'example 5')
+
+unittest.main()
diff --git a/challenge-333/roger-bell-west/raku/ch-1.p6 b/challenge-333/roger-bell-west/raku/ch-1.p6
new file mode 100755
index 0000000000..869dae695c
--- /dev/null
+++ b/challenge-333/roger-bell-west/raku/ch-1.p6
@@ -0,0 +1,50 @@
+#! /usr/bin/raku
+
+use Test;
+
+plan 4;
+
+is(straightline([[2, 1], [2, 3], [2, 5]]), True, 'example 1');
+is(straightline([[1, 4], [3, 4], [10, 4]]), True, 'example 2');
+is(straightline([[0, 0], [1, 1], [2, 3]]), False, 'example 3');
+is(straightline([[1, 1], [1, 1], [1, 1]]), True, 'example 4');
+
+sub straightline(@a) {
+ my @b;
+ for @a -> @xy {
+ my $u = True;
+ for @b -> @bxy