aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xchallenge-241/roger-bell-west/javascript/ch-1.js21
-rwxr-xr-xchallenge-241/roger-bell-west/javascript/ch-2.js114
-rw-r--r--challenge-241/roger-bell-west/kotlin/ch-1.kt21
-rw-r--r--challenge-241/roger-bell-west/kotlin/ch-2.kt85
-rwxr-xr-xchallenge-241/roger-bell-west/lua/ch-1.lua30
-rwxr-xr-xchallenge-241/roger-bell-west/lua/ch-2.lua125
-rwxr-xr-xchallenge-241/roger-bell-west/perl/ch-1.pl15
-rwxr-xr-xchallenge-241/roger-bell-west/perl/ch-2.pl67
-rw-r--r--challenge-241/roger-bell-west/postscript/ch-1.ps75
-rw-r--r--challenge-241/roger-bell-west/postscript/ch-2.ps410
-rwxr-xr-xchallenge-241/roger-bell-west/python/ch-1.py17
-rwxr-xr-xchallenge-241/roger-bell-west/python/ch-2.py74
-rwxr-xr-xchallenge-241/roger-bell-west/raku/ch-1.p613
-rwxr-xr-xchallenge-241/roger-bell-west/raku/ch-2.p667
-rwxr-xr-xchallenge-241/roger-bell-west/ruby/ch-1.rb22
-rwxr-xr-xchallenge-241/roger-bell-west/ruby/ch-2.rb32
-rwxr-xr-xchallenge-241/roger-bell-west/rust/ch-1.rs21
-rwxr-xr-xchallenge-241/roger-bell-west/rust/ch-2.rs84
-rw-r--r--challenge-241/roger-bell-west/scala/ch-1.scala22
-rw-r--r--challenge-241/roger-bell-west/scala/ch-2.scala90
-rw-r--r--challenge-241/roger-bell-west/tests.yaml35
21 files changed, 1440 insertions, 0 deletions
diff --git a/challenge-241/roger-bell-west/javascript/ch-1.js b/challenge-241/roger-bell-west/javascript/ch-1.js
new file mode 100755
index 0000000000..0e73ee8dec
--- /dev/null
+++ b/challenge-241/roger-bell-west/javascript/ch-1.js
@@ -0,0 +1,21 @@
+#! /usr/bin/node
+
+"use strict"
+
+function arithmetictriplets(a, diff) {
+ const vs = new Set(a);
+ return a.filter(n => vs.has(n + diff) && vs.has(n + diff * 2)).length;
+}
+
+if (arithmetictriplets([0, 1, 4, 6, 7, 10], 3) == 2) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (arithmetictriplets([4, 5, 6, 7, 8, 9], 2) == 2) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write("\n");
diff --git a/challenge-241/roger-bell-west/javascript/ch-2.js b/challenge-241/roger-bell-west/javascript/ch-2.js
new file mode 100755
index 0000000000..760d249f40
--- /dev/null
+++ b/challenge-241/roger-bell-west/javascript/ch-2.js
@@ -0,0 +1,114 @@
+#! /usr/bin/node
+
+"use strict"
+
+function genprimes(mx) {
+ let primesh=new Set([2,3])
+ for (let i = 6; i <= mx; i += 6) {
+ for (let j = i-1; j <= i+1; j += 2) {
+ if (j <= mx) {
+ primesh.add(j);
+ }
+ }
+ }
+ let q=[2,3,5,7];
+ let p=q.shift();
+ let mr=Math.floor(Math.sqrt(mx));
+ while (p <= mr) {
+ if (primesh.has(p)) {
+ let i=p*p
+ for (let i=p*p; i <= mx; i += p) {
+ primesh.delete(i);
+ }
+ }
+ if (q.length < 2) {
+ q.push(q[q.length-1]+4);
+ q.push(q[q.length-1]+2);
+ }
+ p=q.shift();
+ }
+ let primes=[...primesh];
+ primes.sort(function(a,b) {
+ return a-b;
+ });
+ return primes;
+}
+
+function primefactor(n) {
+ let f=new Map();
+ let m=n;
+ for (let p of genprimes(1+Math.floor(Math.sqrt(n)))) {
+ while (m % p == 0) {
+ m=Math.floor(m/p);
+ if (f.has(p)) {
+ f.set(p,f.get(p)+1);
+ } else {
+ f.set(p,1);
+ }
+ if (m == 1) {
+ break;
+ }
+ }
+ }
+ if (m > 1) {
+ if (f.has(m)) {
+ f.set(m,f.get(m)+1);
+ } else {
+ f.set(m,1);
+ }
+ }
+ return f;
+}
+
+function primefactorcount(n) {
+ return Array.of(...primefactor(n).values()).reduce((x, y) => x + y, 0);
+}
+
+function primeorder(ints) {
+ let b = ints;
+ let c = new Map;
+ for (let n of ints) {
+ c.set(n, primefactorcount(n));
+ }
+ b.sort(function(aa, bb) { if (c.get(aa) == c.get(bb)) {
+ return aa - bb;
+ } else {
+ return c.get(aa) - c.get(bb);
+ }
+ });
+ 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(primeorder([11, 8, 27, 4]), [11, 4, 8, 27])) {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write("\n");
diff --git a/challenge-241/roger-bell-west/kotlin/ch-1.kt b/challenge-241/roger-bell-west/kotlin/ch-1.kt
new file mode 100644
index 0000000000..8f68d4ad25
--- /dev/null
+++ b/challenge-241/roger-bell-west/kotlin/ch-1.kt
@@ -0,0 +1,21 @@
+fun arithmetictriplets(ints: List<Int>, diff: Int): Int {
+ val vs = ints.toSet()
+ return ints.filter { n -> vs.contains(n + diff) && vs.contains(n + diff * 2)}.size
+}
+
+fun main() {
+
+ if (arithmetictriplets(listOf(0, 1, 4, 6, 7, 10), 3) == 2) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (arithmetictriplets(listOf(4, 5, 6, 7, 8, 9), 2) == 2) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ println("")
+
+}
diff --git a/challenge-241/roger-bell-west/kotlin/ch-2.kt b/challenge-241/roger-bell-west/kotlin/ch-2.kt
new file mode 100644
index 0000000000..a252969050
--- /dev/null
+++ b/challenge-241/roger-bell-west/kotlin/ch-2.kt
@@ -0,0 +1,85 @@
+import kotlin.math.*
+
+fun genprimes(mx: Int): ArrayList<Int> {
+ var primesh=mutableSetOf<Int>()
+ for (i in 2..3) {
+ primesh.add(i)
+ }
+ for (i in 6..mx+1 step 6) {
+ for (j in i-1..i+1 step 2) {
+ if (j <= mx) {
+ primesh.add(j)
+ }
+ }
+ }
+ var q=ArrayDeque(listOf(2,3,5,7))
+ var p=q.removeFirst()
+ val mr=sqrt(mx.toDouble()).toInt()
+ while (p <= mr) {
+ if (primesh.contains(p)) {
+ for (i in p*p..mx step p) {
+ primesh.remove(i)
+ }
+ }
+ if (q.size < 2) {
+ q.add(q.last()+4)
+ q.add(q.last()+2)
+ }
+ p=q.removeFirst()
+ }
+ var primes=ArrayList(primesh.distinct())
+ primes.sort()
+ return primes
+}
+
+fun primefactor(n: Int): Map<Int,Int> {
+ var f=mutableMapOf<Int,Int>()
+ var m=n
+ for (p in genprimes(sqrt(m.toDouble()).toInt())) {
+ while (m % p == 0) {
+ m /= p
+ if (f.containsKey(p)) {
+ f[p] = f[p]!!+1
+ } else {
+ f[p]=1
+ }
+ }
+ if (m == 1) {
+ break
+ }
+ }
+ if (m > 1) {
+ if (f.containsKey(m)) {
+ f[m] = f[m]!!+1
+ } else {
+ f[m]=1
+ }
+ }
+ return f
+}
+
+fun primefactorcount(n: Int): Int {
+ return primefactor(n).values.sum();
+}
+
+fun primeorder(a: List<Int>): List<Int> {
+ var b = ArrayList(a)
+ var c = mutableMapOf<Int, Int>()
+ for (v in a.toSet()) {
+ c[v] = primefactorcount(v)
+ }
+ b.sort()
+ b.sortBy { c[it] }
+ return b.toList()
+}
+
+fun main() {
+
+ if (primeorder(listOf(11, 8, 27, 4)) == listOf(11, 4, 8, 27)) {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ println("")
+
+}
diff --git a/challenge-241/roger-bell-west/lua/ch-1.lua b/challenge-241/roger-bell-west/lua/ch-1.lua
new file mode 100755
index 0000000000..8426cad692
--- /dev/null
+++ b/challenge-241/roger-bell-west/lua/ch-1.lua
@@ -0,0 +1,30 @@
+#! /usr/bin/lua
+
+function arithmetictriplets(ints, diff)
+ local vs = {}
+ for _i, c in ipairs(ints) do
+ vs[c] = true
+ end
+ local n = 0
+ for _ai, s in ipairs(ints) do
+ if vs[s + diff] ~= nil and vs[s + diff * 2] ~= nil then
+ n = n + 1
+ end
+ end
+ return n
+end
+
+if arithmetictriplets({0, 1, 4, 6, 7, 10}, 3) == 2 then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+io.write(" ")
+
+if arithmetictriplets({4, 5, 6, 7, 8, 9}, 2) == 2 then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+print("")
+
diff --git a/challenge-241/roger-bell-west/lua/ch-2.lua b/challenge-241/roger-bell-west/lua/ch-2.lua
new file mode 100755
index 0000000000..3cbb2563ea
--- /dev/null
+++ b/challenge-241/roger-bell-west/lua/ch-2.lua
@@ -0,0 +1,125 @@
+#! /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 genprimes(mx)
+ local primesh = {}
+ for i = 2, 3 do
+ primesh[i] = true
+ end
+ for i = 6, mx, 6 do
+ for j = i-1, i+1, 2 do
+ if j <= mx then
+ primesh[j]=true
+ end
+ end
+ end
+ local q={2,3,5,7}
+ local p=table.remove(q,1)
+ local mr=math.floor(math.sqrt(mx))
+ while p <= mr do
+ if primesh[p] ~= nil then
+ for i = p*p,mx,p do
+ primesh[i] = nil
+ end
+ end
+ if #q < 2 then
+ table.insert(q,q[#q]+4)
+ table.insert(q,q[#q]+2)
+ end
+ p=table.remove(q,1)
+ end
+ local primes = {}
+ for k,v in pairs(primesh) do
+ table.insert(primes,k)
+ end
+ table.sort(primes)
+ return primes
+end
+
+function primefactor(n)
+ local f={}
+ local m=n
+ for k,p in pairs(genprimes(1+math.floor(math.sqrt(m)))) do
+ while m % p == 0 do
+ m=math.floor(m/p)
+ if f[p] == nil then
+ f[p]=1
+ else
+ f[p] = f[p] + 1
+ end
+ if m==1 then
+ break
+ end
+ end
+ end
+ if m>1 then
+ if f[m] == nil then
+ f[m]=1
+ else
+ f[m] = f[m] + 1
+ end
+ end
+ return f
+end
+
+function primefactorcount(n)
+ local r = 0
+ for k, v in pairs(primefactor(n)) do
+ r = r + v
+ end
+ return r
+end
+
+function primeorder(a)
+ local b = a
+ local c = {}
+ for _, v in ipairs(b) do
+ if c[v] == nil then
+ c[v] = primefactorcount(v)
+ end
+ end
+ table.sort(b, function(a, b)
+ if c[a] == c[b] then
+ return a < b
+ else
+ return c[a] < c[b]
+ end
+ end)
+ return b
+end
+
+if recursive_compare(primeorder({11, 8, 27, 4}), {11, 4, 8, 27}) then
+ io.write("Pass")
+else
+ io.write("FAIL")
+end
+print("")
+
diff --git a/challenge-241/roger-bell-west/perl/ch-1.pl b/challenge-241/roger-bell-west/perl/ch-1.pl
new file mode 100755
index 0000000000..342574f36e
--- /dev/null
+++ b/challenge-241/roger-bell-west/perl/ch-1.pl
@@ -0,0 +1,15 @@
+#! /usr/bin/perl
+
+use strict;
+use warnings;
+use experimental 'signatures';
+
+use Test::More tests => 2;
+
+is(arithmetictriplets([0, 1, 4, 6, 7, 10], 3), 2, 'example 1');
+is(arithmetictriplets([4, 5, 6, 7, 8, 9], 2), 2, 'example 2');
+
+sub arithmetictriplets($a, $diff) {
+ my %vs = map {$_ => 1} @{$a};
+ return grep {(exists $vs{$_+$diff}) && (exists $vs{$_+$diff*2})} @{$a};
+}
diff --git a/challenge-241/roger-bell-west/perl/ch-2.pl b/challenge-241/roger-bell-west/perl/ch-2.pl
new file mode 100755
index 0000000000..48f588c9b0
--- /dev/null
+++ b/challenge-241/roger-bell-west/perl/ch-2.pl
@@ -0,0 +1,67 @@
+#! /usr/bin/perl
+
+use strict;
+use warnings;
+use experimental 'signatures';
+
+use Test::More tests => 1;
+
+is_deeply(primeorder([11, 8, 27, 4]), [11, 4, 8, 27], 'example 1');
+
+use List::Util qw(sum);
+
+sub genprimes($mx) {
+ my %primesh=map {$_ => 1} (2,3);
+ for (my $i=6;$i <= $mx+1; $i += 6) {
+ foreach my $j ($i-1,$i+1) {
+ if ($j <= $mx) {
+ $primesh{$j}=1;
+ }
+ }
+ }
+ my @q=(2,3,5,7);
+ my $p=shift @q;
+ my $mr=int(sqrt($mx));
+ while ($p <= $mr) {
+ if ($primesh{$p}) {
+ my $i=$p*$p;
+ while ($i <= $mx) {
+ delete $primesh{$i};
+ $i += $p;
+ }
+ }
+ if (scalar @q < 2) {
+ push @q,$q[-1]+4;
+ push @q,$q[-1]+2;
+ }
+ $p=shift @q;
+ }
+ return [sort {$a <=> $b} keys %primesh];
+}
+
+sub primefactor($n) {
+ my %f;
+ my $m=$n;
+ foreach my $p (@{genprimes(int(sqrt($n)))}) {
+ while ($m % $p == 0) {
+ $f{$p}++;
+ $m=int($m/$p);
+ if ($m == 1) {
+ last;
+ }
+ }
+ }
+ if ($m > 1) {
+ $f{$m}++;
+ }
+ return \%f;
+}
+
+sub primefactorcount($n) {
+ return sum(values %{primefactor($n)});
+}
+
+sub primeorder($a) {
+ my %c = map {$_ => primefactorcount($_)} @{$a};
+ return [sort {$c{$::a} <=> $c{$::b} || $::a <=> $::b} @{$a}];
+}
diff --git a/challenge-241/roger-bell-west/postscript/ch-1.ps b/challenge-241/roger-bell-west/postscript/ch-1.ps
new file mode 100644
index 0000000000..4260b47d07
--- /dev/null
+++ b/challenge-241/roger-bell-west/postscript/ch-1.ps
@@ -0,0 +1,75 @@
+%!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
+
+/filter { % array proc(bool) -> array
+ 1 dict begin
+ /p exch def
+ [ exch
+ {
+ dup p not
+ {
+ pop
+ } if
+ } forall
+ ]
+ end
+} bind def
+
+/toset { % array -> dict of (value, true)
+ << exch
+ {
+ true
+ } 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
+
+/test.start {
+ print (:) print
+ /test.pass 0 def
+ /test.count 0 def
+} bind def
+
+
+% end included library code
+
+/arithmetictriplets {
+ 0 dict begin
+ /diff exch def
+ /nums exch def
+ /ns nums toset def
+ nums { diff add dup ns exch known
+ exch diff add ns exch known
+ and } filter length
+ end
+} bind def
+
+(arithmetictriplets) test.start
+[0 1 4 6 7 10] 3 arithmetictriplets 2 eq test
+[4 5 6 7 8 9] 2 arithmetictriplets 2 eq test
+test.end
diff --git a/challenge-241/roger-bell-west/postscript/ch-2.ps b/challenge-241/roger-bell-west/postscript/ch-2.ps
new file mode 100644
index 0000000000..ebf2930d46
--- /dev/null
+++ b/challenge-241/roger-bell-west/postscript/ch-2.ps
@@ -0,0 +1,410 @@
+%!PS
+
+% begin included library code
+% see https://codeberg.org/Firedrake/postscript-libraries/
+/values { % dict -> array of dict values
+ [ exch
+ {
+ exch pop
+ } forall
+ ]
+} bind def
+
+/mergesort.with_keygen { % [ a c b ] { keygen } -> [ a b c ]
+ 3 dict begin
+ /kg exch def
+ /arr exch def
+ /kl << arr {
+ dup kg
+ } forall >> def
+ arr {
+ exch kl exch get exch kl exch get mergesort.cmp
+ } mergesort.with_comparator
+} bind def
+
+/quicksort.cmp {
+ 2 copy
+ lt {
+ pop pop -1
+ } {
+ gt {
+ 1
+ } {
+ 0
+ } ifelse
+ } ifelse
+} bind def
+
+/keys { % dict -> array of dict keys
+ [ exch
+ {
+ pop
+ } forall
+ ]
+} bind def
+
+/mergesort.cmp {
+ 2 copy
+ lt {
+ pop pop -1
+ } {
+ gt {
+ 1
+ } {
+ 0
+ } ifelse
+ } 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
+
+/mergesort.with_comparator { % [ a c b ] { comparator } -> [ a b c ]
+ 5 dict begin
+ /cmp where {
+ pop
+ } {
+ /cmp exch def
+ } ifelse
+ /m exch def
+ m length 1 le {
+ m
+ } {
+ /l2 m length 2 idiv def
+ /left m 0 l2 getinterval mergesort.with_comparator def
+ /right m l2 m length l2 sub getinterval mergesort.with_comparator def
+ left right mergesort.merge
+ } ifelse
+ end
+} bind def
+
+
+/test.start {
+ print (:) print
+ /test.pass 0 def
+ /test.count 0 def
+} bind def
+
+/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
+
+/isqrt {
+ 0 dict begin
+ /s exch def
+ s 1 le {
+ s
+ } {
+ /x0 s 2 idiv def
+ /x1 x0 s x0 idiv add 2 idiv def
+ {
+ x1 x0 ge {
+ exit
+ } if
+ /x0 x1 def
+ /x1 x0 s x0 idiv add 2 idiv def
+ } loop
+ x0
+ } 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
+
+/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 {
+ /test.count test.count 1 add def
+ {
+ /test.pass test.pass 1 add def
+ } {
+ ( ) print
+ test.count (....) cvs print
+ (-fail) print
+ } ifelse
+} bind def
+
+/primefactor {
+ 4 dict begin
+ /n exch def
+ /f 1 dict def
+ /m n def
+ n isqrt genprimes quicksort {
+ /p exch def
+ {
+ m p mod 0 eq {
+ f p known {
+ f p f p get 1 add put
+ } {
+ f p 1 put
+ } ifelse
+ /m m p idiv def
+ } {
+ exit
+ } ifelse
+ } loop
+ m 1 eq {
+ exit
+ } if
+ } forall
+ m 1 gt {
+ f m known {
+ f m f m get 1 add put
+ } {
+ f m 1 put
+ } ifelse
+ } if
+ f
+ 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
+
+/genprimes {
+ 6 dict begin
+ /mx exch def
+ /primesh mx dict def
+ 2 1 3 {
+ dup mx le {
+ primesh exch true put
+ } {
+ pop
+ } ifelse
+ } for
+ 6 6 mx 1 add {
+ dup 1 sub exch 1 add 2 exch {
+ dup mx le {
+ primesh exch true put
+ } {
+ pop
+ } ifelse
+ } for
+ } for
+ /q [ 3 5 7 ] def
+ /qi 0 def
+ /p 2 def
+ /mr mx isqrt def
+ {
+ p mr le not {
+ exit
+ } if
+ primesh p known {
+ p dup mul p mx {
+ primesh exch undef
+ } for
+ } if
+ q length qi sub 2 le {
+ /q q q q length 1 sub get 4 add apush def
+ /q q q q length 1 sub get 2 add apush def
+ } if
+ /p q qi get def
+ /qi qi 1 add def
+ } loop
+ primesh keys
+ end
+} bind def
+
+/mergesort.merge {
+ 4 dict begin
+ /right exch def
+ /left exch def
+ /li 0 def
+ /ri 0 def
+ [
+ {
+ li left length ge ri right length ge or {
+ exit
+ } if
+ left li get right ri get cmp 0 le {
+ left li get
+ /li li 1 add def
+ } {
+ right ri get
+ /ri ri 1 add def
+ } ifelse
+ } loop
+ li left length lt {
+ left li left length li sub getinterval aload pop
+ } if
+ ri right length lt {
+ right ri right length ri sub getinterval aload pop
+ } if
+ ]
+ end
+} bind def
+
+
+/quicksort {
+ { quicksort.cmp } quicksort.with_comparator
+} bind def
+
+/apush { apush.right } 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
+
+/mergesort {
+ { mergesort.cmp } mergesort.with_comparator
+} 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
+
+/apush.right { % [a b] c -> [a b c]
+ exch
+ [ exch aload length 2 add -1 roll ]
+} bind def
+
+
+% end included library code
+
+/primefactorcount {
+ primefactor values { add } reduce
+} bind def
+
+/primeorder {
+ mergesort
+ { primefactorcount }
+ mergesort.with_keygen
+} bind def
+
+(primeorder) test.start
+[11 8 27 4] primeorder [11 4 8 27] deepeq test
+test.end
diff --git a/challenge-241/roger-bell-west/python/ch-1.py b/challenge-241/roger-bell-west/python/ch-1.py
new file mode 100755
index 0000000000..915a56bfeb
--- /dev/null
+++ b/challenge-241/roger-bell-west/python/ch-1.py
@@ -0,0 +1,17 @@
+#! /usr/bin/python3
+
+def arithmetictriplets(nums, diff):
+ ns = set(nums)
+ return len([n for n in nums if (n + diff) in ns and (n + diff * 2) in ns])
+
+import unittest
+
+class TestArithmetictriplets(unittest.TestCase):
+
+ def test_ex1(self):
+ self.assertEqual(arithmetictriplets([0, 1, 4, 6, 7, 10], 3), 2, 'example 1')
+
+ def test_ex2(self):
+ self.assertEqual(arithmetictriplets([4, 5, 6, 7, 8, 9], 2), 2, 'example 2')
+
+unittest.main()
diff --git a/challenge-241/roger-bell-west/python/ch-2.py b/challenge-241/roger-bell-west/python/ch-2.py
new file mode 100755
index 0000000000..973d9eee6b
--- /dev/null
+++ b/challenge-241/roger-bell-west/python/ch-2.py
@@ -0,0 +1,74 @@
+#! /usr/bin/python3
+
+from collections import deque
+from functools import reduce
+
+def isqrt(s:int):
+ if s <= 1:
+ return s
+ x0 = s // 2
+ x1 = (x0 + s // x0) // 2
+ while x1 < x0:
+ x0 = x1
+ x1 = (x0 + s // x0) // 2
+ return x0
+
+def genprimes(mx):
+ primesh=set(range(2,4))
+ for i in range(6,mx+2,6):
+ for j in range(i-1,i+2,2):
+ if j <= mx:
+ primesh.add(j)
+ q=deque([2,3,5,7])
+ p=q.popleft()
+ mr=isqrt(mx)
+ while p <= mr:
+ if p in primesh:
+ for i in range(p*p,mx+1,p):
+ primesh.discard(i)
+ if len(q) < 2:
+ q.append(q[-1]+4)
+ q.append(q[-1]+2)
+ p=q.popleft()
+ primes=list(primesh)
+ primes.sort()
+ return primes
+
+def primefactor(n):
+ f=dict()
+ m=n
+ for p in genprimes(isqrt(n)):
+ while (m % p == 0):
+ m //= p
+ if p in f:
+ f[p] += 1
+ else:
+ f[p] = 1
+ if m==1:
+ break
+ if m > 1:
+ if m in f:
+ f[m] += 1
+ else:
+ f[m] = 1
+ return f
+
+def primefactorcount(n):
+ return reduce(lambda a, b: a + b, primefactor(n).values())
+
+
+def primeorder(ints):
+ c = dict((x, primefactorcount(x)) for x in ints)
+ b = ints
+ b.sort()
+ b.sort(key = lambda i: c[i])
+ return b
+
+import unittest
+
+class TestPrimeorder(unittest.TestCase):
+
+ def test_ex1(self):
+ self.assertEqual(primeorder([11, 8, 27, 4]), [11, 4, 8, 27], 'example 1')