aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad Sajid Anwar <Mohammad.Anwar@yahoo.com>2023-12-26 20:00:39 +0000
committerGitHub <noreply@github.com>2023-12-26 20:00:39 +0000
commitdaa81203fd6467dff10f82712fe8a71280929f25 (patch)
treef5d08ad13d6111da9aef76f6dcc48522ddb4f79c
parent2c61da4908dec6febe1ecaa44ff2e72def79df58 (diff)
parent858a5a78afbe2f51d389af1d6f4dd5d4e28d9710 (diff)
downloadperlweeklychallenge-club-daa81203fd6467dff10f82712fe8a71280929f25.tar.gz
perlweeklychallenge-club-daa81203fd6467dff10f82712fe8a71280929f25.tar.bz2
perlweeklychallenge-club-daa81203fd6467dff10f82712fe8a71280929f25.zip
Merge pull request #9299 from Firedrake/rogerbw-challenge-249
RogerBW solutions for challenge no. 249
-rwxr-xr-xchallenge-249/roger-bell-west/javascript/ch-1.js59
-rwxr-xr-xchallenge-249/roger-bell-west/javascript/ch-2.js71
-rw-r--r--challenge-249/roger-bell-west/kotlin/ch-1.kt32
-rw-r--r--challenge-249/roger-bell-west/kotlin/ch-2.kt45
-rwxr-xr-xchallenge-249/roger-bell-west/lua/ch-1.lua61
-rwxr-xr-xchallenge-249/roger-bell-west/lua/ch-2.lua79
-rwxr-xr-xchallenge-249/roger-bell-west/perl/ch-1.pl25
-rwxr-xr-xchallenge-249/roger-bell-west/perl/ch-2.pl29
-rw-r--r--challenge-249/roger-bell-west/postscript/ch-1.ps215
-rw-r--r--challenge-249/roger-bell-west/postscript/ch-2.ps276
-rwxr-xr-xchallenge-249/roger-bell-west/python/ch-1.py25
-rwxr-xr-xchallenge-249/roger-bell-west/python/ch-2.py35
-rwxr-xr-xchallenge-249/roger-bell-west/raku/ch-1.p623
-rwxr-xr-xchallenge-249/roger-bell-west/raku/ch-2.p627
-rwxr-xr-xchallenge-249/roger-bell-west/ruby/ch-1.rb30
-rwxr-xr-xchallenge-249/roger-bell-west/ruby/ch-2.rb39
-rwxr-xr-xchallenge-249/roger-bell-west/rust/ch-1.rs31
-rwxr-xr-xchallenge-249/roger-bell-west/rust/ch-2.rs39
-rw-r--r--challenge-249/roger-bell-west/scala/ch-1.scala33
-rw-r--r--challenge-249/roger-bell-west/scala/ch-2.scala46
-rw-r--r--challenge-249/roger-bell-west/tests.yaml44
21 files changed, 1264 insertions, 0 deletions
diff --git a/challenge-249/roger-bell-west/javascript/ch-1.js b/challenge-249/roger-bell-west/javascript/ch-1.js
new file mode 100755
index 0000000000..6b39470cdd
--- /dev/null
+++ b/challenge-249/roger-bell-west/javascript/ch-1.js
@@ -0,0 +1,59 @@
+#! /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 shortestdistance(a0) {
+ if (a0.length % 2 != 0) {
+ return [];
+ }
+ let a = a0;
+ a.sort();
+ let out = [];
+ for (let i = 0; i < a.length; i += 2) {
+ if (a[i] != a[i + 1]) {
+ return [];
+ }
+ out.push([a[i], a[i]]);
+ }
+ return out;
+}
+
+if (deepEqual(shortestdistance([3, 2, 3, 2, 2, 2]), [[2, 2], [2, 2], [3, 3]])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (deepEqual(shortestdistance([1, 2, 3, 4]), [])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write("\n");
diff --git a/challenge-249/roger-bell-west/javascript/ch-2.js b/challenge-249/roger-bell-west/javascript/ch-2.js
new file mode 100755
index 0000000000..4dd1690970
--- /dev/null
+++ b/challenge-249/roger-bell-west/javascript/ch-2.js
@@ -0,0 +1,71 @@
+#! /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 distringmatch(a) {
+ let v = 1 << (a.length - 1);
+ let wv = v << 1;
+ let out = [wv];
+ for (const c of a) {
+ if (c == 'I') {
+ wv += v;
+ } else {
+ wv -= v;
+ }
+ v >>= 1;
+ out.push(wv);
+ }
+ let q = [...out];
+ q.sort(function(a,b) {
+ return a-b;
+ });
+ let c = new Map;
+ q.forEach((v, i) => {c.set(v, i)});
+ return out.map(x => c.get(x));
+}
+
+if (deepEqual(distringmatch('IDID'), [0, 4, 1, 3, 2])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (deepEqual(distringmatch('III'), [0, 1, 2, 3])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (deepEqual(distringmatch('DDI'), [3, 2, 0, 1])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write("\n");
diff --git a/challenge-249/roger-bell-west/kotlin/ch-1.kt b/challenge-249/roger-bell-west/kotlin/ch-1.kt
new file mode 100644
index 0000000000..c0bae85bf8
--- /dev/null
+++ b/challenge-249/roger-bell-west/kotlin/ch-1.kt
@@ -0,0 +1,32 @@
+fun shortestdistance(a0: List<Int>): List<List<Int>> {
+ if (a0.size % 2 != 0) {
+ return emptyList<List<Int>>()
+ }
+ var a = ArrayList(a0)
+ a.sort()
+ var out = ArrayList<List<Int>>()
+ for (t in a.chunked(2)) {
+ if (t[0] != t[1]) {
+ return emptyList<List<Int>>()
+ }
+ out.add(listOf(t[0], t[0]))
+ }
+ return out.toList()
+}
+
+fun main() {
+
+ if (shortestdistance(listOf(3, 2, 3, 2, 2, 2)) == listOf(listOf(2, 2), listOf(2, 2), listOf(3, 3))) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (shortestdistance(listOf(1, 2, 3, 4)) == emptyList<Int>()) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ println("")
+
+}
diff --git a/challenge-249/roger-bell-west/kotlin/ch-2.kt b/challenge-249/roger-bell-west/kotlin/ch-2.kt
new file mode 100644
index 0000000000..8338b31034
--- /dev/null
+++ b/challenge-249/roger-bell-west/kotlin/ch-2.kt
@@ -0,0 +1,45 @@
+fun distringmatch(a: String): List<Int> {
+ var v = 1 shl (a.length - 1)
+ var wv = v shl 1
+ var out = ArrayList<Int>()
+ var q = ArrayList<Int>()
+ out.add(wv)
+ q.add(wv)
+ for (c in a) {
+ if (c == 'I') {
+ wv += v
+ } else {
+ wv -= v
+ }
+ v = v shr 1
+ out.add(wv)
+ q.add(wv)
+ }
+ q.sort()
+ var c = mutableMapOf<Int, Int>()
+ q.forEachIndexed {i, n -> c.put(n, i)}
+ return out.map{c.getValue(it)}.toList()
+}
+
+fun main() {
+
+ if (distringmatch("IDID") == listOf(0, 4, 1, 3, 2)) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (distringmatch("III") == listOf(0, 1, 2, 3)) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (distringmatch("DDI") == listOf(3, 2, 0, 1)) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ println("")
+
+}
diff --git a/challenge-249/roger-bell-west/lua/ch-1.lua b/challenge-249/roger-bell-west/lua/ch-1.lua
new file mode 100755
index 0000000000..111457de6f
--- /dev/null
+++ b/challenge-249/roger-bell-west/lua/ch-1.lua
@@ -0,0 +1,61 @@
+#! /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 shortestdistance(a0)
+ if #a0 % 2 ~= 0 then
+ return {}
+ end
+ local a = a0
+ table.sort(a)
+ local out = {}
+ for i = 1, #a, 2 do
+ if a[i] ~= a[i+1] then
+ return {}
+ end
+ table.insert(out, {a[i], a[i]})
+ end
+ return out
+end
+
+if recursive_compare(shortestdistance({3, 2, 3, 2, 2, 2}), {{2, 2}, {2, 2}, {3, 3}}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if recursive_compare(shortestdistance({1, 2, 3, 4}), {}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+print("")
+
diff --git a/challenge-249/roger-bell-west/lua/ch-2.lua b/challenge-249/roger-bell-west/lua/ch-2.lua
new file mode 100755
index 0000000000..4ce75b8aff
--- /dev/null
+++ b/challenge-249/roger-bell-west/lua/ch-2.lua
@@ -0,0 +1,79 @@
+#! /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 distringmatch(a)
+ local v = 1 << (#a - 1)
+ local wv = v << 1
+ local out = {wv}
+ local r = {wv}
+ for c in string.gmatch(a, ".") do
+ if c == "I" then
+ wv = wv + v
+ else
+ wv = wv - v
+ end
+ v = v >> 1
+ table.insert(out, wv)
+ table.insert(r, wv)
+ end
+ table.sort(r)
+ local c = {}
+ for i = 1, #r do
+ c[r[i]] = i
+ end
+ local o = {}
+ for _, n in ipairs(out) do
+ table.insert(o, c[n])
+ end
+ return o
+end
+
+if recursive_compare(distringmatch("IDID"), {0, 4, 1, 3, 2}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if recursive_compare(distringmatch("III"), {0, 1, 2, 3}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if recursive_compare(distringmatch("DDI"), {3, 2, 0, 1}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+print("")
+
diff --git a/challenge-249/roger-bell-west/perl/ch-1.pl b/challenge-249/roger-bell-west/perl/ch-1.pl
new file mode 100755
index 0000000000..ca7bc936a5
--- /dev/null
+++ b/challenge-249/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 => 2;
+
+is_deeply(shortestdistance([3, 2, 3, 2, 2, 2]), [[2, 2], [2, 2], [3, 3]], 'example 1');
+is_deeply(shortestdistance([1, 2, 3, 4]), [], 'example 2');
+
+sub shortestdistance($a0) {
+ if (scalar @{$a0} % 2 != 0) {
+ return [];
+ }
+ my @a = sort {$a <=> $b} @{$a0};
+ my @out;
+ for (my $i = 0; $i < scalar @a; $i+=2) {
+ if ($a[$i] != $a[$i+1]) {
+ return [];
+ }
+ push @out,[$a[$i], $a[$i]];
+ }
+ return \@out;
+}
diff --git a/challenge-249/roger-bell-west/perl/ch-2.pl b/challenge-249/roger-bell-west/perl/ch-2.pl
new file mode 100755
index 0000000000..92aba07749
--- /dev/null
+++ b/challenge-249/roger-bell-west/perl/ch-2.pl
@@ -0,0 +1,29 @@
+#! /usr/bin/perl
+
+use strict;
+use warnings;
+use experimental 'signatures';
+
+use Test::More tests => 3;
+
+is_deeply(distringmatch('IDID'), [0, 4, 1, 3, 2], 'example 1');
+is_deeply(distringmatch('III'), [0, 1, 2, 3], 'example 2');
+is_deeply(distringmatch('DDI'), [3, 2, 0, 1], 'example 3');
+
+sub distringmatch($a) {
+ my $v = 1 << (length($a) - 1);
+ my $wv = $v << 1;
+ my @out = ($wv);
+ foreach my $c (split '', $a) {
+ if ($c eq 'I') {
+ $wv += $v
+ } else {
+ $wv -= $v;
+ }
+ $v >>= 1;
+ push @out, $wv;
+ }
+ my @r = sort{$::a <=> $::b} @out;
+ my %c = map {$r[$_] => $_} (0..$#r);
+ return [map{$c{$_}} @out];
+}
diff --git a/challenge-249/roger-bell-west/postscript/ch-1.ps b/challenge-249/roger-bell-west/postscript/ch-1.ps
new file mode 100644
index 0000000000..e6ffb359ec
--- /dev/null
+++ b/challenge-249/roger-bell-west/postscript/ch-1.ps
@@ -0,0 +1,215 @@
+%!PS
+
+% begin included library code
+% see https://codeberg.org/Firedrake/postscript-libraries/
+/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
+
+/test.start {
+ print (:) print
+ /test.pass 0 def
+ /test.count 0 def
+} bind def
+
+/quicksort {
+ { quicksort.cmp } quicksort.with_comparator
+} 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
+
+/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
+
+/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
+
+/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
+
+
+% end included library code
+
+/shortestdistance {
+ 0 dict begin
+ /a exch def
+ 1 {
+ a length 2 mod 0 ne {
+ [] exit
+ } if
+ /fail false def
+ /a a quicksort def
+ [
+ 0 2 a length 2 sub {
+ /i exch def
+ a i get a i 1 add get ne {
+ fail true def
+ exit
+ } if
+ [ a i get dup ]
+ } for
+ ]
+ fail {
+ pop
+ []
+ } if
+ } repeat
+ end
+} bind def
+
+(shortestdistance) test.start
+[3 2 3 2 2 2] shortestdistance [[2 2] [2 2] [3 3]] deepeq test
+[1 2 3 4] shortestdistance [] deepeq test
+test.end
diff --git a/challenge-249/roger-bell-west/postscript/ch-2.ps b/challenge-249/roger-bell-west/postscript/ch-2.ps
new file mode 100644
index 0000000000..4b834a76b9
--- /dev/null
+++ b/challenge-249/roger-bell-west/postscript/ch-2.ps
@@ -0,0 +1,276 @@
+%!PS
+
+% begin included library code
+% see https://codeberg.org/Firedrake/postscript-libraries/
+/quicksort {
+ { quicksort.cmp } quicksort.with_comparator
+} 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
+
+/test.start {
+ print (:) print
+ /test.pass 0 def
+ /test.count 0 def
+} 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
+
+/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
+
+/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
+
+/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
+
+/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.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
+
+/map { % array proc -> array
+ 2 dict begin
+ /p exch def
+ [ exch
+ {
+ p
+ } forall
+ ]
+ end
+} 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
+
+/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
+
+/distringmatch {
+ 0 dict begin
+ /a exch def
+ /v 1 a length 1 sub bitshift def
+ /wv v 1 bitshift def
+ /out [
+ wv
+ a {
+ 73 eq {
+ /wv wv v add def
+ } {
+ /wv wv v sub def
+ } ifelse
+ /v v -1 bitshift def
+ wv
+ } forall
+ ] def
+ /c <<
+ out deepcopy
+ quicksort
+ enumerate.array
+ { aload pop exch } map
+ aload pop
+ >> def
+ out { c exch get } map
+ end
+} bind def
+
+(distringmatch) test.start
+(IDID) distringmatch [0 4 1 3 2] deepeq test
+(III) distringmatch [0 1 2 3] deepeq test
+(DDI) distringmatch [3 2 0 1] deepeq test
+test.end
diff --git a/challenge-249/roger-bell-west/python/ch-1.py b/challenge-249/roger-bell-west/python/ch-1.py
new file mode 100755
index 0000000000..e086773409
--- /dev/null
+++ b/challenge-249/roger-bell-west/python/ch-1.py
@@ -0,0 +1,25 @@
+#! /usr/bin/python3
+
+def shortestdistance(a0):
+ if len(a0) % 2 != 0:
+ return []
+ a = a0
+ a.sort()
+ out = []
+ for i in range(0, len(a), 2):
+ if a[i] != a[i+1]:
+ return []
+ out.append([a[i], a[i]])
+ return out
+
+import unittest
+
+class TestShortestdistance(unittest.TestCase):
+
+ def test_ex1(self):
+ self.assertEqual(shortestdistance([3, 2, 3, 2, 2, 2]), [[2, 2], [2, 2], [3, 3]], 'example 1')
+
+ def test_ex2(self):
+ self.assertEqual(shortestdistance([1, 2, 3, 4]), [], 'example 2')
+
+unittest.main()
diff --git a/challenge-249/roger-bell-west/python/ch-2.py b/challenge-249/roger-bell-west/python/ch-2.py
new file mode 100755
index 0000000000..a242036ab7
--- /dev/null
+++ b/challenge-249/roger-bell-west/python/ch-2.py
@@ -0,0 +1,35 @@
+#! /usr/bin/python3
+
+def distringmatch(a):
+ v = 1 << (len(a) - 1)
+ wv = v << 1
+ out = [wv]
+ for c in a:
+ if c == "I":
+ wv += v
+ else:
+ wv -= v
+ v >>= 1
+ out.append(wv)
+ c = dict()
+ q = out.copy()
+ q.sort()
+ for i, v in enumerate(q):
+ c[v] = i
+ return [c[v] for v in out]
+
+
+import unittest
+
+class TestDistringmatch(unittest.TestCase):
+
+ def test_ex1(self):
+ self.assertEqual(distringmatch("IDID"), [0, 4, 1, 3, 2], 'example 1')
+
+ def test_ex2(self):
+ self.assertEqual(distringmatch("III"), [0, 1, 2, 3], 'example 2')
+
+ def test_ex3(self):
+ self.assertEqual(distringmatch("DDI"), [3, 2, 0, 1], 'example 3')
+
+unittest.main()
diff --git a/challenge-249/roger-bell-west/raku/ch-1.p6 b/challenge-249/roger-bell-west/raku/ch-1.p6
new file mode 100755
index 0000000000..9f5bdbf702
--- /dev/null
+++ b/challenge-249/roger-bell-west/raku/ch-1.p6
@@ -0,0 +1,23 @@
+#! /usr/bin/raku
+
+use Test;
+
+plan 2;
+
+is-deeply(shortestdistance([3, 2, 3, 2, 2, 2]), [[2, 2], [2, 2], [3, 3]], 'example 1');
+is-deeply(shortestdistance([1, 2, 3, 4]), [], 'example 2');
+
+sub shortestdistance(@a0) {
+ if (@a0.elems % 2 != 0) {
+ return [];
+ }
+ my @a = @a0.sort({$^a <=> $^b});
+ my @out;
+ for @a -> $i, $j {
+ if ($i != $j) {
+ return [];