diff options
| author | Roger Bell_West <roger@firedrake.org> | 2022-07-04 12:37:24 +0100 |
|---|---|---|
| committer | Roger Bell_West <roger@firedrake.org> | 2022-07-04 12:37:24 +0100 |
| commit | da3811c616d6337013f2b721352dd24815ed478a (patch) | |
| tree | 7e036b9471edbdb6ef479ac717e744322fd6ac79 | |
| parent | 42bd07d080a38d552fb4562de9eba28ccfbecb18 (diff) | |
| download | perlweeklychallenge-club-da3811c616d6337013f2b721352dd24815ed478a.tar.gz perlweeklychallenge-club-da3811c616d6337013f2b721352dd24815ed478a.tar.bz2 perlweeklychallenge-club-da3811c616d6337013f2b721352dd24815ed478a.zip | |
Solutions for challenge #172
18 files changed, 1295 insertions, 0 deletions
diff --git a/challenge-172/roger-bell-west/javascript/ch-1.js b/challenge-172/roger-bell-west/javascript/ch-1.js new file mode 100755 index 0000000000..17db559d95 --- /dev/null +++ b/challenge-172/roger-bell-west/javascript/ch-1.js @@ -0,0 +1,97 @@ +#! /usr/bin/node + +"use strict" + +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 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 primepartition (n, divs) { + let pl = genprimes(n); + let p = [[]]; + while (p.length > 0) { + let pa = p.pop(); + if (pa.length == divs) { + if (pa.reduce((x,y) => x+y, 0) == n) { + return pa; + } + } else { + let px = new Set(pa); + for (let pq of pl) { + if (!px.has(pq)) { + let pb = [...pa]; + pb.push(pq); + p.push(pb); + } + } + } + } + return [n]; +} + +if (deepEqual(primepartition(18, 2),[13, 5])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); + +if (deepEqual(primepartition(19, 3),[11, 5, 3])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write("\n"); diff --git a/challenge-172/roger-bell-west/javascript/ch-2.js b/challenge-172/roger-bell-west/javascript/ch-2.js new file mode 100755 index 0000000000..2f0420ad38 --- /dev/null +++ b/challenge-172/roger-bell-west/javascript/ch-2.js @@ -0,0 +1,54 @@ +#! /usr/bin/node + +"use strict" + +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 fivenumber(n0) { + let n = [...n0]; + n.sort(); + let nl = n.length - 1; + let o = [ n[0] ]; + for (let quartile = 1; quartile <= 3; quartile++) { + let bx = quartile * nl; + let base = Math.floor(bx / 4); + let v = n[base]; + if (bx % 4 != 0) { + v = (n[base] + n[base+1]) / 2; + } + o.push(v); + } + o.push(n[n.length - 1]); + return o; +} + +if (deepEqual(fivenumber([0, 0, 1, 2, 63, 61, 27, 13]), + [0, 0.5, 7.5, 44, 63])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write("\n"); diff --git a/challenge-172/roger-bell-west/kotlin/ch-1.kt b/challenge-172/roger-bell-west/kotlin/ch-1.kt new file mode 100644 index 0000000000..fb13b6be60 --- /dev/null +++ b/challenge-172/roger-bell-west/kotlin/ch-1.kt @@ -0,0 +1,73 @@ +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 primepartition(n: Int, divs: Int): ArrayList<Int> { + val pl = genprimes(n) + var p = ArrayList<ArrayList<Int>>() + p.add(ArrayList<Int>()) + while (p.size > 0) { + val pa = p.removeLast() + if (pa.size == divs) { + if (pa.sum() == n) { + return pa + } + } else { + val px = pa.toSet() + for (pq in pl) { + if (!px.contains(pq)) { + var pb = ArrayList(pa) + pb.add(pq) + p.add(pb) + } + } + } + } + return arrayListOf(n) +} + +fun main() { + if (primepartition(18, 2) == listOf(13, 5)) { + print("Pass") + } else { + print("FAIL") + } + print(" ") + + if (primepartition(19, 3) == listOf(11, 5, 3)) { + print("Pass") + } else { + print("FAIL") + } + println("") +} diff --git a/challenge-172/roger-bell-west/kotlin/ch-2.kt b/challenge-172/roger-bell-west/kotlin/ch-2.kt new file mode 100644 index 0000000000..992604f7e3 --- /dev/null +++ b/challenge-172/roger-bell-west/kotlin/ch-2.kt @@ -0,0 +1,27 @@ +fun fivenumber(n0: List<Double>): ArrayList<Double> { + var n = ArrayList(n0) + n.sort() + val nl = n.size - 1 + var o = arrayListOf(n[0]) + for (quartile in 1..3) { + val bx = quartile * nl + val base = bx / 4 + var v = n[base] + if (bx % 4 != 0) { + v = (n[base] + n[base+1]) / 2.0 + } + o.add(v) + } + o.add(n[n.size - 1]) + return o +} + +fun main() { + if (fivenumber(listOf(0.0, 0.0, 1.0, 2.0, 63.0, 61.0, 27.0, 13.0)) == + listOf(0.0, 0.5, 7.5, 44.0, 63.0)) { + print("Pass") + } else { + print("FAIL") + } + println("") +} diff --git a/challenge-172/roger-bell-west/lua/ch-1.lua b/challenge-172/roger-bell-west/lua/ch-1.lua new file mode 100755 index 0000000000..82e7553e65 --- /dev/null +++ b/challenge-172/roger-bell-west/lua/ch-1.lua @@ -0,0 +1,111 @@ +#! /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) + -- 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 + + -- Check each key-value pair + -- We have to do this both ways in case we miss some. + -- TODO: Could probably be smarter and not check those we've + -- already checked though! + 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 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 primepartition(n, divs) + local pl = genprimes(n) + local p = {{}} + while #p > 0 do + local pa = table.remove(p) + if #pa == divs then + local sum = 0 + for i,v in ipairs(pa) do + sum = sum + v + end + if sum == n then + return pa + end + else + local px = {} + for i,v in ipairs(pa) do + px[v] = true + end + for i,pq in ipairs(pl) do + if px[pq] == nil then + local pb = {} + for j,pk in ipairs(pa) do + table.insert(pb,pk) + end + table.insert(pb,pq) + table.insert(p,pb) + end + end + end + end + return {n} +end + +if recursive_compare(primepartition(18,2), {13, 5}) then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if recursive_compare(primepartition(19,3), {11, 5, 3}) then + io.write("Pass") +else + io.write("FAIL") +end +print("") diff --git a/challenge-172/roger-bell-west/lua/ch-2.lua b/challenge-172/roger-bell-west/lua/ch-2.lua new file mode 100755 index 0000000000..0477026669 --- /dev/null +++ b/challenge-172/roger-bell-west/lua/ch-2.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) + -- 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 + + -- Check each key-value pair + -- We have to do this both ways in case we miss some. + -- TODO: Could probably be smarter and not check those we've + -- already checked though! + 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 fivenumber(n0) + local n = {} + for i,v in ipairs(n0) do + table.insert(n,v) + end + table.sort(n) + local nl = #n - 1 + local o = {n[1]} + for quartile = 1,3 do + local bx = quartile * nl + local base = math.floor(bx / 4) + local v = n[base+1] + if bx % 4 ~= 0 then + v = (n[base+1] + n[base+2]) / 2 + end + table.insert(o,v) + end + table.insert(o,n[#n]) + return o +end + +if recursive_compare( + fivenumber({0., 0., 1., 2., 63., 61., 27., 13.}), + {0., 0.5, 7.5, 44., 63.} +) then + io.write("Pass") +else + io.write("FAIL") +end +print("") diff --git a/challenge-172/roger-bell-west/perl/ch-1.pl b/challenge-172/roger-bell-west/perl/ch-1.pl new file mode 100755 index 0000000000..0de4ff4f1d --- /dev/null +++ b/challenge-172/roger-bell-west/perl/ch-1.pl @@ -0,0 +1,38 @@ +#! /usr/bin/perl + +use strict; +use warnings; +use experimental 'signatures'; + +use Test::More tests => 2; +use Math::Prime::Util qw(primes); +use List::Util qw(sum); + +is_deeply(primepartition(18, 2), + [13, 5], + 'example 1'); + +is_deeply(primepartition(19, 3), + [11, 5, 3], + 'example 2'); + +sub primepartition($n, $divs) { + my @pl = @{primes($n)}; + my @p = ([]); + while (scalar @p > 0) { + my $pa = pop @p; + if (scalar @{$pa} == $divs) { + if (sum(@{$pa}) == $n) { + return $pa; + } + } else { + my %px = map {$_ => 1} @{$pa}; + foreach my $pq (@pl) { + unless (exists $px{$pq}) { + push @p,[@{$pa},$pq]; + } + } + } + } + return [$n]; +} diff --git a/challenge-172/roger-bell-west/perl/ch-2.pl b/challenge-172/roger-bell-west/perl/ch-2.pl new file mode 100755 index 0000000000..ed01eaff50 --- /dev/null +++ b/challenge-172/roger-bell-west/perl/ch-2.pl @@ -0,0 +1,28 @@ +#! /usr/bin/perl + +use strict; +use warnings; +use experimental 'signatures'; + +use Test::More tests => 1; + +is_deeply(fivenumber((0.0, 0.0, 1.0, 2.0, 63.0, 61.0, 27.0, 13.0)), + [0.0, 0.5, 7.5, 44.0, 63.0], + 'example 1'); + +sub fivenumber(@n0) { + my @n = sort(@n0); + my $nl = scalar @n - 1; + my @o = ($n[0]); + foreach my $quartile (1..3) { + my $bx = $quartile * $nl; + my $base = int($bx / 4); + my $v = $n[$base]; + if ($bx % 4 != 0) { + $v = ($n[$base] + $n[$base+1]) / 2 + } + push @o,$v; + } + push @o,$n[-1]; + return \@o; +} diff --git a/challenge-172/roger-bell-west/postscript/ch-1.ps b/challenge-172/roger-bell-west/postscript/ch-1.ps new file mode 100644 index 0000000000..77c4b30ff1 --- /dev/null +++ b/challenge-172/roger-bell-west/postscript/ch-1.ps @@ -0,0 +1,278 @@ +%!PS + +% begin included library code +% see https://github.com/Firedrake/postscript-libraries/ +/genprimes { + 6 dict begin + /mx exch def + /primesh mx dict def + 2 1 3 { + primesh exch true put + } 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 sqrt cvi 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 + +/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 + +/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 + +/toset { % array -> dict of (value, true) + << exch + { + true + } forall + >> +} 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 + 0 arr length 1 sub quicksort.main + arr + end +} bind def + +/keys { % dict -> array of dict keys + [ exch + { + pop + } forall + ] +} 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.start { + print (:) print + /test.pass 0 def + /test.count 0 def +} 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 + +/apop.right { % [a b c] -> [a b] c + [ exch aload length 1 add 1 roll ] exch +} bind def + +/apush.right { % [a b] c -> [a b c] + exch + [ exch aload length 2 add -1 roll ] +} bind def + + +/apush { apush.right } bind def + + +% end included library code + +/primepartition { + 6 dict begin + /divs exch def + /n exch def + /p [ 0 array ] def + /pl n genprimes quicksort def + [ n ] + { + p length 0 eq { + exit + } if + p apop.right /pa exch def /p exch def + pa length divs eq { + pa { add } reduce n eq { + pop pa + exit + } if + } { + /px pa toset def + pl { + /pq exch def + px pq known not { + /p p [ pa aload pop pq ] apush.right def + } if + } forall + } ifelse + } loop + end +} bind def + +(primepartition) test.start +18 2 primepartition [ 13 5 ] deepeq test +19 3 primepartition [ 11 5 3 ] deepeq test +test.end diff --git a/challenge-172/roger-bell-west/postscript/ch-2.ps b/challenge-172/roger-bell-west/postscript/ch-2.ps new file mode 100644 index 0000000000..6d4f0b6aa2 --- /dev/null +++ b/challenge-172/roger-bell-west/postscript/ch-2.ps @@ -0,0 +1,186 @@ +%!PS + +% begin included library code +% see https://github.com/Firedrake/postscript-libraries/ +/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 + +/quicksort { % [ a c b ] -> [ a b c ] + 1 dict begin + /arr exch def + 0 arr length 1 sub quicksort.main + arr + 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 + +/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.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.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 { + /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 + +/fivenumber { + 4 dict begin + /n exch quicksort def + /nl n length 1 sub def + [ + n 0 get + 1 1 3 { + nl mul /bx exch def + /base bx 4 idiv def + n base get + bx 4 mod 0 ne { + n base 1 add get add 2.0 div + } if + } for + n nl get + ] + end +} bind def + +(fivenumber) test.start +[0.0 0.0 1.0 2.0 63.0 61.0 27.0 13.0] fivenumber [ 0.0 0.5 7.5 44.0 63.0 ] deepeq test +test.end diff --git a/challenge-172/roger-bell-west/python/ch-1.py b/challenge-172/roger-bell-west/python/ch-1.py new file mode 100755 index 0000000000..1db86de4d6 --- /dev/null +++ b/challenge-172/roger-bell-west/python/ch-1.py @@ -0,0 +1,56 @@ +#! /usr/bin/python3 + +import unittest + +from math import sqrt,floor,log +from collections import deque + +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=floor(sqrt(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 primepartition(n, divs): + pl = genprimes(n) + p = [[]] + while len(p) > 0: + pa = p.pop() + if len(pa) == divs: + if sum(pa) == n: + return pa + else: + px = set(pa) + for pq in pl: + if pq not in px: + pb = pa.copy() + pb.append(pq) + p.append(pb) + return [n] + +class TestPrimepartition(unittest.TestCase): + + def test_ex1(self): + self.assertEqual(primepartition(18, 2), + [13, 5],'example 1') + + def test_ex2(self): + self.assertEqual(primepartition(19, 3), + [11, 5, 3],'example 1') + +unittest.main() diff --git a/challenge-172/roger-bell-west/python/ch-2.py b/challenge-172/roger-bell-west/python/ch-2.py new file mode 100755 index 0000000000..54ab98438e --- /dev/null +++ b/challenge-172/roger-be |
