aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-210/roger-bell-west/blog.txt1
-rwxr-xr-xchallenge-213/roger-bell-west/javascript/ch-1.js65
-rwxr-xr-xchallenge-213/roger-bell-west/javascript/ch-2.js94
-rw-r--r--challenge-213/roger-bell-west/kotlin/ch-1.kt38
-rw-r--r--challenge-213/roger-bell-west/kotlin/ch-2.kt60
-rwxr-xr-xchallenge-213/roger-bell-west/lua/ch-1.lua60
-rwxr-xr-xchallenge-213/roger-bell-west/lua/ch-2.lua86
-rwxr-xr-xchallenge-213/roger-bell-west/perl/ch-1.pl25
-rwxr-xr-xchallenge-213/roger-bell-west/perl/ch-2.pl39
-rw-r--r--challenge-213/roger-bell-west/postscript/ch-1.ps192
-rw-r--r--challenge-213/roger-bell-west/postscript/ch-2.ps176
-rwxr-xr-xchallenge-213/roger-bell-west/python/ch-1.py29
-rwxr-xr-xchallenge-213/roger-bell-west/python/ch-2.py54
-rwxr-xr-xchallenge-213/roger-bell-west/raku/ch-1.p620
-rwxr-xr-xchallenge-213/roger-bell-west/raku/ch-2.p641
-rwxr-xr-xchallenge-213/roger-bell-west/ruby/ch-1.rb34
-rwxr-xr-xchallenge-213/roger-bell-west/ruby/ch-2.rb54
-rwxr-xr-xchallenge-213/roger-bell-west/rust/ch-1.rs33
-rwxr-xr-xchallenge-213/roger-bell-west/rust/ch-2.rs69
-rw-r--r--challenge-213/roger-bell-west/tests.yaml76
20 files changed, 1246 insertions, 0 deletions
diff --git a/challenge-210/roger-bell-west/blog.txt b/challenge-210/roger-bell-west/blog.txt
new file mode 100644
index 0000000000..f82900468e
--- /dev/null
+++ b/challenge-210/roger-bell-west/blog.txt
@@ -0,0 +1 @@
+https://blog.firedrake.org/archive/2023/04/The_Weekly_Challenge_210__Collisions_Kill.html
diff --git a/challenge-213/roger-bell-west/javascript/ch-1.js b/challenge-213/roger-bell-west/javascript/ch-1.js
new file mode 100755
index 0000000000..1e4e8e01a4
--- /dev/null
+++ b/challenge-213/roger-bell-west/javascript/ch-1.js
@@ -0,0 +1,65 @@
+#! /usr/bin/node
+
+"use strict"
+
+// 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;
+ }
+}
+
+function funsort(l0) {
+ let l = l0;
+ l.sort();
+ let a = [];
+ let b = [];
+ for (let k of l) {
+ if (k % 2 == 0) {
+ a.push(k);
+ } else {
+ b.push(k);
+ }
+ }
+ a.push(...b);
+ return a;
+}
+
+if (deepEqual(funsort([1, 2, 3, 4, 5, 6]), [2, 4, 6, 1, 3, 5])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (deepEqual(funsort([1, 2]), [2, 1])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (deepEqual(funsort([1]), [1])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write("\n");
diff --git a/challenge-213/roger-bell-west/javascript/ch-2.js b/challenge-213/roger-bell-west/javascript/ch-2.js
new file mode 100755
index 0000000000..7f4fb83572
--- /dev/null
+++ b/challenge-213/roger-bell-west/javascript/ch-2.js
@@ -0,0 +1,94 @@
+#! /usr/bin/node
+
+"use strict"
+
+// 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;
+ }
+}
+
+// by VLAZ
+// https://stackoverflow.com/a/59322890
+function toWindows(inputArray, size) {
+ return Array.from(
+ {length: inputArray.length - (size - 1)}, //get the appropriate length
+ (_, index) => inputArray.slice(index, index+size) //create the windows
+ )
+}
+
+function shortestroute(r0, origin, destination) {
+ let r = new Map();
+ for (let rt of r0) {
+ for (let rp of toWindows(rt, 2)) {
+ if (!r.has(rp[0])) {
+ r.set(rp[0], new Map());
+ }
+ r.set(rp[0], r.get(rp[0]).set(rp[1]));
+ if (!r.has(rp[1])) {
+ r.set(rp[1], new Map());
+ }
+ r.set(rp[1], r.get(rp[1]).set(rp[0]));
+ }
+ }
+ let out = [];
+ let stack = [ [ origin ] ];
+ while (stack.length > 0) {
+ const s = stack.shift();
+ const l = s[s.length-1];
+ if (l == destination) {
+ out = s;
+ break;
+ } else {
+ const s1 = new Set(s);
+ for (let pd of r.get(l).keys()) {
+ if (!s1.has(pd)) {
+ let q = [...s];
+ q.push(pd);
+ stack.push(q);
+ }
+ }
+ }
+ }
+ return out;
+}
+
+if (deepEqual(shortestroute([[1, 2, 6], [5, 6, 7]], 1, 7), [1, 2, 6, 7])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (deepEqual(shortestroute([[1, 2, 3], [4, 5, 6]], 2, 5), [])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (deepEqual(shortestroute([[1, 2, 3], [4, 5, 6], [3, 8, 9], [7, 8]], 1, 7), [1, 2, 3, 8, 7])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write("\n");
diff --git a/challenge-213/roger-bell-west/kotlin/ch-1.kt b/challenge-213/roger-bell-west/kotlin/ch-1.kt
new file mode 100644
index 0000000000..095f8b94b0
--- /dev/null
+++ b/challenge-213/roger-bell-west/kotlin/ch-1.kt
@@ -0,0 +1,38 @@
+fun funsort(l0: List<Int>): List<Int> {
+ var l = ArrayList(l0)
+ l.sort()
+ var a = ArrayList<Int>()
+ var b = ArrayList<Int>()
+ for (k in l) {
+ if (k % 2 == 0) {
+ a.add(k)
+ } else {
+ b.add(k)
+ }
+ }
+ a.addAll(b)
+ return a.toList()
+}
+
+fun main() {
+
+ if (funsort(listOf(1, 2, 3, 4, 5, 6)) == listOf(2, 4, 6, 1, 3, 5)) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (funsort(listOf(1, 2)) == listOf(2, 1)) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (funsort(listOf(1)) == listOf(1)) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ println("")
+
+}
diff --git a/challenge-213/roger-bell-west/kotlin/ch-2.kt b/challenge-213/roger-bell-west/kotlin/ch-2.kt
new file mode 100644
index 0000000000..502778f7bb
--- /dev/null
+++ b/challenge-213/roger-bell-west/kotlin/ch-2.kt
@@ -0,0 +1,60 @@
+fun shortestroute(r0: List<List<Int>>, origin: Int, destination: Int): List<Int> {
+ var r = mutableMapOf<Int, MutableSet<Int>>()
+ for (rt in r0) {
+ for (rp in rt.windowed(size = 2)) {
+ if (!r.contains(rp[0])) {
+ r.put(rp[0], mutableSetOf<Int>())
+ }
+ r.get(rp[0])!!.add(rp[1])
+ if (!r.contains(rp[1])) {
+ r.put(rp[1], mutableSetOf<Int>())
+ }
+ r.get(rp[1])!!.add(rp[0])
+ }
+ }
+ var out = ArrayList<Int>()
+ var stack = ArrayDeque<ArrayList<Int>>()
+ stack.add(arrayListOf(origin))
+ while (stack.size > 0) {
+ val s = stack.removeFirst()
+ val l = s.last()
+ if (l == destination) {
+ out = s
+ break
+ } else {
+ val s1 = s.toSet()
+ for (pd in r.get(l)!!) {
+ if (!s1.contains(pd)) {
+ var q = ArrayList(s)
+ q.add(pd)
+ stack.add(q)
+ }
+ }
+ }
+ }
+ return out.toList()
+}
+
+
+fun main() {
+
+ if (shortestroute(listOf(listOf(1, 2, 6), listOf(5, 6, 7)), 1, 7) == listOf(1, 2, 6, 7)) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (shortestroute(listOf(listOf(1, 2, 3), listOf(4, 5, 6)), 2, 5) == emptyList<List<Int>>()) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (shortestroute(listOf(listOf(1, 2, 3), listOf(4, 5, 6), listOf(3, 8, 9), listOf(7, 8)), 1, 7) == listOf(1, 2, 3, 8, 7)) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ println("")
+
+}
diff --git a/challenge-213/roger-bell-west/lua/ch-1.lua b/challenge-213/roger-bell-west/lua/ch-1.lua
new file mode 100755
index 0000000000..6896076810
--- /dev/null
+++ b/challenge-213/roger-bell-west/lua/ch-1.lua
@@ -0,0 +1,60 @@
+#! /usr/bin/lua
+
+-- by Michael Anderson at
+-- https://stackoverflow.com/questions/8722620/comparing-two-index-tables-by-index-value-in-lua
+function recursive_compare(t1,t2)
+ if t1==t2 then return true end
+ if (type(t1)~="table") then return false end
+ local mt1 = getmetatable(t1)
+ local mt2 = getmetatable(t2)
+ if( not recursive_compare(mt1,mt2) ) then return false end
+ for k1,v1 in pairs(t1) do
+ local v2 = t2[k1]
+ if( not recursive_compare(v1,v2) ) then return false end
+ end
+ for k2,v2 in pairs(t2) do
+ local v1 = t1[k2]
+ if( not recursive_compare(v1,v2) ) then return false end
+ end
+ return true
+end
+
+function funsort(l0)
+ local l = l0
+ table.sort(l)
+ local a = {}
+ local b = {}
+ for i, k in ipairs(l) do
+ if k % 2 == 0 then
+ table.insert(a, k)
+ else
+ table.insert(b, k)
+ end
+ end
+ for i, k in ipairs(b) do
+ table.insert(a, k)
+ end
+ return a
+end
+
+if recursive_compare(funsort({1, 2, 3, 4, 5, 6}), {2, 4, 6, 1, 3, 5}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if recursive_compare(funsort({1, 2}), {2, 1}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if recursive_compare(funsort({1}), {1}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+print("")
+
diff --git a/challenge-213/roger-bell-west/lua/ch-2.lua b/challenge-213/roger-bell-west/lua/ch-2.lua
new file mode 100755
index 0000000000..a2d353c669
--- /dev/null
+++ b/challenge-213/roger-bell-west/lua/ch-2.lua
@@ -0,0 +1,86 @@
+#! /usr/bin/lua
+
+-- by Michael Anderson at
+-- https://stackoverflow.com/questions/8722620/comparing-two-index-tables-by-index-value-in-lua
+function recursive_compare(t1,t2)
+ if t1==t2 then return true end
+ if (type(t1)~="table") then return false end
+ local mt1 = getmetatable(t1)
+ local mt2 = getmetatable(t2)
+ if( not recursive_compare(mt1,mt2) ) then return false end
+ for k1,v1 in pairs(t1) do
+ local v2 = t2[k1]
+ if( not recursive_compare(v1,v2) ) then return false end
+ end
+ for k2,v2 in pairs(t2) do
+ local v1 = t1[k2]
+ if( not recursive_compare(v1,v2) ) then return false end
+ end
+ return true
+end
+
+function shortestroute(r0, origin, destination)
+ local r = {}
+ for _dummy, rt in ipairs(r0) do
+ for i = 1, #rt-1 do
+ local ri = rt[i]
+ local rj = rt[i + 1]
+ if r[ri] == nil then
+ r[ri] = {}
+ end
+ r[ri][rj] = true
+ if r[rj] == nil then
+ r[rj] = {}
+ end
+ r[rj][ri] = true
+ end
+ end
+ local out = {}
+ local stack = { { origin } }
+ while #stack > 0 do
+ local s = table.remove(stack, 1)
+ local l = s[#s]
+ if l == destination then
+ out = s
+ break
+ else
+ local s1 = {}
+ for _dummy, v in ipairs(s) do
+ s1[v] = true
+ end
+ for pd, _dummy in pairs(r[l]) do
+ if s1[pd] == nil then
+ local q = {}
+ for _dummy, v in ipairs(s) do
+ table.insert(q, v)
+ end
+ table.insert(q, pd)
+ table.insert(stack, q)
+ end
+ end
+ end
+ end
+ return out
+end
+
+if recursive_compare(shortestroute({{1, 2, 6}, {5, 6, 7}}, 1, 7), {1, 2, 6, 7}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if recursive_compare(shortestroute({{1, 2, 3}, {4, 5, 6}}, 2, 5), {}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if recursive_compare(shortestroute({{1, 2, 3}, {4, 5, 6}, {3, 8, 9}, {7, 8}}, 1, 7), {1, 2, 3, 8, 7}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+print("")
+
diff --git a/challenge-213/roger-bell-west/perl/ch-1.pl b/challenge-213/roger-bell-west/perl/ch-1.pl
new file mode 100755
index 0000000000..4d5de082f3
--- /dev/null
+++ b/challenge-213/roger-bell-west/perl/ch-1.pl
@@ -0,0 +1,25 @@
+#! /usr/bin/perl
+
+use strict;
+use warnings;
+use experimental 'signatures';
+
+use Test::More tests => 3;
+
+is_deeply(funsort([1, 2, 3, 4, 5, 6]), [2, 4, 6, 1, 3, 5], 'example 1');
+is_deeply(funsort([1, 2]), [2, 1], 'example 2');
+is_deeply(funsort([1]), [1], 'example 3');
+
+sub funsort($l0) {
+ my @l = sort @{$l0};
+ my (@a, @b);
+ foreach my $k (@l) {
+ if ($k % 2 == 0) {
+ push @a, $k;
+ } else {
+ push @b, $k;
+ }
+ }
+ push @a, @b;
+ return \@a;
+}
diff --git a/challenge-213/roger-bell-west/perl/ch-2.pl b/challenge-213/roger-bell-west/perl/ch-2.pl
new file mode 100755
index 0000000000..2ecbd62e94
--- /dev/null
+++ b/challenge-213/roger-bell-west/perl/ch-2.pl
@@ -0,0 +1,39 @@
+#! /usr/bin/perl
+
+use strict;
+use warnings;
+use experimental 'signatures';
+
+use Test::More tests => 3;
+
+is_deeply(shortestroute([[1, 2, 6], [5, 6, 7]], 1, 7), [1, 2, 6, 7], 'example 1');
+is_deeply(shortestroute([[1, 2, 3], [4, 5, 6]], 2, 5), [], 'example 2');
+is_deeply(shortestroute([[1, 2, 3], [4, 5, 6], [3, 8, 9], [7, 8]], 1, 7), [1, 2, 3, 8, 7], 'example 3');
+
+sub shortestroute($r0, $origin, $destination) {
+ my %r;
+ foreach my $rt (@{$r0}) {
+ foreach my $i (0..$#{$rt}-1) {
+ my $ri = $rt->[$i];
+ my $rj = $rt->[$i + 1];
+ $r{$ri}{$rj} = 1;
+ $r{$rj}{$ri} = 1;
+ }
+ }
+ my $out = [];
+ my @stack = ([$origin]);
+ while (scalar @stack > 0) {
+ my $s = shift @stack;
+ my $l = $s->[-1];
+ if ($l == $destination) {
+ $out = $s;
+ last;
+ } else {
+ my %s1 = map {$_ => 1} @{$s};
+ foreach my $pd (grep {!exists $s1{$_}} keys %{$r{$l}}) {
+ push @stack,[@{$s}, $pd];
+ }
+ }
+ }
+ return $out;
+}
diff --git a/challenge-213/roger-bell-west/postscript/ch-1.ps b/challenge-213/roger-bell-west/postscript/ch-1.ps
new file mode 100644
index 0000000000..8397b96231
--- /dev/null
+++ b/challenge-213/roger-bell-west/postscript/ch-1.ps
@@ -0,0 +1,192 @@
+%!PS
+
+% begin included library code
+% see https://codeberg.org/Firedrake/postscript-libraries/
+/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
+
+/test.start {
+ print (:) print
+ /test.pass 0 def
+ /test.count 0 def
+} 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 { % [ a c b ] -> [ a b c ]
+ 1 dict begin
+ /arr exch def
+ arr length 0 gt {
+ 0 arr length 1 sub quicksort.main
+ } if
+ arr
+ 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 ge {
+ exit
+ } if
+ } loop
+ {
+ /j j 1 sub def
+ arr j get pivot le {
+ exit
+ } if
+ } loop
+ i j ge {
+ j
+ exit
+ } if
+ i j quicksort.swap
+ } loop
+ 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 {
+ /test.count test.count 1 add def
+ {
+ /test.pass test.pass 1 add def
+ } {
+ ( ) print
+ test.count (....) cvs print
+ (-fail) print
+ } ifelse
+} bind def
+
+/apush.right { % [a b] c -> [a b c]
+ exch
+ [ exch aload length 2 add -1 roll ]
+} bind def
+
+
+% end included library code
+
+/funsort {
+ 3 dict begin
+ /a 0 array def
+ /b 0 array def
+ quicksort {
+ /k exch def
+ k 2 mod 0 eq {
+ /a a k apush.right def
+ } {
+ /b b k apush.right def
+ } ifelse
+ } forall
+ [ a aload pop b aload pop ]
+ end
+} bind def
+
+(funsort) test.start
+[1 2 3 4 5 6] funsort [2 4 6 1 3 5] deepeq test
+[1 2] funsort [2 1] deepeq test
+[1] funsort [1] deepeq test
+test.end
diff --git a/challenge-213/roger-bell-west/postscript/ch-2.ps b/challenge-213/roger-bell-west/postscript/ch-2.ps
new file mode 100644
index 0000000000..c9d86fdd8c
--- /dev/null
+++ b/challenge-213/roger-bell-west/postscript/ch-2.ps
@@ -0,0 +1,176 @@
+%!PS
+
+% begin included library code
+% see https://codeberg.org/Firedrake/postscript-libraries/
+/toset { % array -> dict of (value, true)
+ << exch
+ {
+ true
+ } forall
+ >>
+} 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
+
+/apop.left { % [a b c] -> [b c] a
+ dup 0 get exch
+ [ exch aload length -1 roll pop ] exch
+} 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
+
+/apush.right { % [a b] c -> [a b c]
+ exch
+ [ exch aload length 2 add -1 roll ]
+} 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
+
+/keys { % dict -> array of dict keys
+ [ exch
+ {
+ pop
+ } forall
+ ]
+} bind def
+
+
+% end included library code
+
+/shortestroute {
+ 14 dict begin
+ /destination exch def
+ /origin exch def
+ /r 0 dict def
+ {
+ /rt exch def
+ 0 1 rt length 2 sub {
+ /i exch def
+ /ri rt i get def
+ /j i 1 add def
+ /rj rt j get def
+ r ri known not {
+ r ri 1 dict put
+ } if
+ r ri get rj true put
+ r rj known not {
+ r rj 1 dict put
+ } if
+ r rj get ri true put
+ } for
+ } forall
+ /out 0 array def
+ /stack [ [ origin ] ] def
+ {
+ stack length 0 eq {
+ exit
+ } if
+ /stack stack apop.left /s exch def def
+ /l s s length 1 sub get def
+ l destination eq {
+ /out s def
+ exit
+ } {
+ /s1 s toset def
+ r l get keys {
+ /pd exch def
+ s1 pd known not {
+ /q s aload length array astore def
+ /q q pd apush.right def
+ /stack stack q apush.right def
+ } if
+ } forall
+ } ifelse
+ } loop
+ out
+ end
+} bind def
+
+(shortestroute) test.start
+[[1 2 6] [5 6 7]] 1 7 shortestroute [1 2 6 7] deepeq test
+[[1 2 3] [4 5 6]] 2 5 shortestroute [] deepeq test
+[[1 2 3] [4 5 6] [3 8 9] [7 8]] 1 7 shortestroute [1 2 3 8 7] deepeq test
+test.end
diff --git a/challenge-213/roger-bell-west/python/ch-1.py b/challenge-213/roger-bell-west/python/ch-1.py
new file mode 100755
index 0000000000..130fcfff62
--- /dev/null
+++ b/challenge-213/roger-bell-west/python/ch-1.py
@@ -0,0 +1,29 @@
+#! /usr/bin/python3
+
+import unittest
+
+def funsort(l0):
+ l = l0
+ l.sort()
+ a = []
+ b = []
+ for k in l:
+ if k % 2 == 0:
+ a.append(k)
+ else:
+ b.append(k)
+ a.extend(b)
+ return a
+
+class TestFunsort(unittest.TestCase):
+
+ def test_ex1(self):
+ self.assertEqual(funsort([1, 2, 3, 4, 5, 6]), [2, 4, 6, 1, 3, 5], 'example 1')
+
+ def test_ex2(self):
+ self.assertEqual(funsort([1, 2]), [2, 1], 'example 2')
+
+ def test_ex3(self):
+ self.assertEqual(funsort([1]), [1], 'example 3')
+
+unittest.main()
diff --git a/challenge-213/roger-bell-west/python/ch-2.py b/challenge-213/roger-bell-west/python/ch-2.py
new file mode 100755
index 0000000000..14b9bc35a9
--- /dev/null
+++ b/challenge-213/roger-bell-west/python/ch-2.py
@@ -0,0 +1,54 @@
+#! /usr/bin/python3
+
+from itertools import islice
+from collections import deque,defaultdict
+
+# https://docs.python.org/3/library/itertools.html
+def sliding_window(iterable, n):
+ # sliding_window('ABCDEFG', 4) --> ABCD BCDE CDEF DEFG
+ it = iter(iterable)
+ window = deque(islice(it, n), maxlen=n)
+ if len(window) == n:
+ yield tuple(window)
+ for x in it:
+ window.append(x)
+ yield tuple(window)
+
+def shortestroute(r0, origin, destination):
+ r = defaultdict(set)
+ for rt in r0:
+ for rp in sliding_window(rt, 2):
+ r[rp[0]].add(rp[1])
+ r[rp[1]].add(rp[0])
+ out = []
+ stack = deque()
+ stack.append([[origin], set([origin])])
+ while len(stack) > 0:
+ s = stack.popleft()
+ l = s[0][-1]
+ if l == destination:
+ out = s[0]
+ break
+ else:
+ for pd in r[l] - s[1]:
+ q = [s[0].copy(), s[1].copy()]
+ q[0].append(pd)
+ q[1].discard(pd)
+ stack.append(q)
+ return out
+
+
+import unittest
+
+class TestShortestroute(unittest.TestCase):
+
+ def test_ex1(self):
+ self.assertEqual(shortestroute([[1, 2, 6], [5, 6, 7]], 1, 7), [1, 2, 6, 7], 'example 1')
+
+ def test_ex2(self):
+ self.assertEqual(shortestroute([[1, 2, 3], [4, 5, 6]], 2, 5), [], 'example 2')
+
+ def test_ex3(self):
+ self.assertEqual(shortestroute([[1, 2, 3], [4, 5, 6], [3, 8, 9], [7, 8]], 1, 7), [1, 2, 3, 8, 7], 'example 3')
+
+unittest.main()
diff --git a/challenge-213/roger-bell-west/raku/ch-1.p6 b/challenge-213/roger-bell-west/raku/ch-1.p6
new file mode 100755
index 0000000000..b8bf2edec6
--- /dev/null
+++ b/challenge-213/roger-bell-west/raku/ch-1.p6
@@ -0,0 +1,20 @@
+#! /usr/bin/raku
+
+use Test;
+
+plan 3;
+
+is-deeply(funsort([1, 2, 3, 4, 5, 6]), [2, 4, 6, 1, 3, 5], 'example 1');
+is-deeply(funsort([1, 2]), [2, 1], 'example 2');
+is-deeply(funsort([1]), [1], 'example 3');
+
+sub funsort(@l0) {
+ my %h = classify { $_ %% 2 ?? 'even' !! 'odd' }, @l0.sort();
+ my @a;
+ for ("even", "odd") -> $mode {
+ if (%h{$mode}) {
+ @a.append(%h{$mode}.List);
+ }
+ }
+ return @a;
+}
diff --git a/challenge-213/roger-bell-west/raku/ch-2.p6 b/challenge-213/roger-bell-west/raku/ch-2.p6
new file mode 100755
index 0000000000..5f5747e271
--- /dev/null
+++ b/challenge-213/roger-bell-west/raku/ch-2.p6
@@ -0,0 +1,41 @@
+#! /usr/bin/raku
+
+use Test;
+
+plan 3;
+
+is-deeply(shortestroute([[1, 2, 6], [5, 6, 7]], 1, 7), [1, 2, 6, 7], 'example 1');
+is-deeply(shortestroute([[1, 2, 3], [4, 5, 6]], 2, 5), [], 'example 2');
+is-deeply(shortestroute([[1, 2, 3], [4, 5, 6], [3, 8, 9], [7, 8]], 1, 7), [1, 2, 3, 8, 7], 'example 3');
+
+sub shortestroute(@r0, $origin, $destination) {
+ my %r;
+ for @r0 -> @rt {
+ for @rt.rotor(2 => -1) -> @rp {
+ %r{@rp[0]} ||= SetHash.new;
+ %r{@rp[0]}{@rp[1]}++;
+ %r{@rp[1]} ||= SetHash.new;
+ %r{@rp[1]}{@rp[0]}++;
+ }
+ }
+ my @out;
+ my @stack = ([$origin,],);
+ while (@stack.elems > 0) {
+ my @s = @stack.shift.flat;
+ my $l = @s[*-1];
+ if ($l == $destination) {
+ @out = @s;
+ last;
+ } else {
+ my %s1 = Set.new(@s);
+