diff options
| author | Roger Bell_West <roger@firedrake.org> | 2024-02-20 11:37:46 +0000 |
|---|---|---|
| committer | Roger Bell_West <roger@firedrake.org> | 2024-02-20 11:37:46 +0000 |
| commit | 4de649256f3bad9f0331d183c7efcc7ce83b4fb0 (patch) | |
| tree | 8607bd91eda90a9921465d1a340225eee559bf20 | |
| parent | d56f5846adcf3864f7b9dd2426d85ae68579729e (diff) | |
| download | perlweeklychallenge-club-4de649256f3bad9f0331d183c7efcc7ce83b4fb0.tar.gz perlweeklychallenge-club-4de649256f3bad9f0331d183c7efcc7ce83b4fb0.tar.bz2 perlweeklychallenge-club-4de649256f3bad9f0331d183c7efcc7ce83b4fb0.zip | |
RogerBW solutions for challenge no. 257
21 files changed, 1877 insertions, 0 deletions
diff --git a/challenge-257/roger-bell-west/javascript/ch-1.js b/challenge-257/roger-bell-west/javascript/ch-1.js new file mode 100755 index 0000000000..f7d2801884 --- /dev/null +++ b/challenge-257/roger-bell-west/javascript/ch-1.js @@ -0,0 +1,69 @@ +#! /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 smallerthancurrent(a) { + let s = [...a]; + s.sort(function(a,b) { + return a-b; + }); + let l = new Map; + s.forEach((n, i) => { + if (!l.has(n)) { + l.set(n, i); + } + }); + return a.map(n => l.get(n)); +} + +if (deepEqual(smallerthancurrent([5, 2, 1, 6]), [2, 1, 0, 3])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (deepEqual(smallerthancurrent([1, 2, 0, 3]), [1, 2, 0, 3])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (deepEqual(smallerthancurrent([0, 1]), [0, 1])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (deepEqual(smallerthancurrent([9, 4, 9, 2]), [2, 1, 2, 0])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write("\n"); diff --git a/challenge-257/roger-bell-west/javascript/ch-2.js b/challenge-257/roger-bell-west/javascript/ch-2.js new file mode 100755 index 0000000000..30d85505c0 --- /dev/null +++ b/challenge-257/roger-bell-west/javascript/ch-2.js @@ -0,0 +1,125 @@ +#! /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 reducedrowechelon(a) { + let leadingone = []; + let valid = true; + for (let row of a) { + let lp = -1; + row.forEach((cell, cn) => { + if (lp == -1) { + if (cell == 1) { + lp = cn; + } else if (cell != 0) { + valid = false; + } + } + }); + leadingone.push(lp); + } + if (!valid) { + return false; + } + while (leadingone[leadingone.length-1] == -1) { + leadingone.pop(); + } + let c = [...leadingone]; + c.sort(function(a,b) { + return a-b; + }); + if (c[0] == -1) { + return false; + } + if (!deepEqual(c, leadingone)) { + return false; + } + for (let i of c) { + let col = a.map(r => r[i]); + col.sort(function(a,b) { + return a-b; + }); + if (col[col.length-1] != 1 || + col[col.length-2] != 0 || + col[0] != 0) { + return false; + } + } + return true; +} + +if (!reducedrowechelon([[1, 1, 0], [0, 1, 0], [0, 0, 0]])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (reducedrowechelon([[0, 1, -2, 0, 1], [0, 0, 0, 1, 3], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (reducedrowechelon([[1, 0, 0, 4], [0, 1, 0, 7], [0, 0, 1, -1]])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (!reducedrowechelon([[0, 1, -2, 0, 1], [0, 0, 0, 0, 0], [0, 0, 0, 1, 3], [0, 0, 0, 0, 0]])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (!reducedrowechelon([[0, 1, 0], [0, 1, 0], [0, 0, 0]])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (!reducedrowechelon([[4, 0, 0, 0], [0, 1, 0, 7], [0, 0, 1, -1]])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (!reducedrowechelon([[1, 0, 0, 4], [1, 0, 0, 7], [0, 0, 1, -1]])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (!reducedrowechelon([[1, -2, 0, 4], [0, 1, 0, 7], [0, 0, 1, -1]])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write("\n"); diff --git a/challenge-257/roger-bell-west/kotlin/ch-1.kt b/challenge-257/roger-bell-west/kotlin/ch-1.kt new file mode 100644 index 0000000000..09a1b389ba --- /dev/null +++ b/challenge-257/roger-bell-west/kotlin/ch-1.kt @@ -0,0 +1,40 @@ +fun smallerthancurrent(a: List<Int>): List<Int> { + var s = ArrayList(a) + s.sort() + var l = mutableMapOf<Int, Int>() + s.forEachIndexed {i, n -> + if (!l.contains(n)) { + l.put(n, i) + } + } + return a.map { l.getValue(it) }.toList() +} + +fun main() { + + if (smallerthancurrent(listOf(5, 2, 1, 6)) == listOf(2, 1, 0, 3)) { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (smallerthancurrent(listOf(1, 2, 0, 3)) == listOf(1, 2, 0, 3)) { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (smallerthancurrent(listOf(0, 1)) == listOf(0, 1)) { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (smallerthancurrent(listOf(9, 4, 9, 2)) == listOf(2, 1, 2, 0)) { + print("Pass") + } else { + print("Fail") + } + println("") + +} diff --git a/challenge-257/roger-bell-west/kotlin/ch-2.kt b/challenge-257/roger-bell-west/kotlin/ch-2.kt new file mode 100644 index 0000000000..f5d3abccda --- /dev/null +++ b/challenge-257/roger-bell-west/kotlin/ch-2.kt @@ -0,0 +1,95 @@ + +fun reducedrowechelon(a: List<List<Int>>): Boolean { + var leadingone = ArrayList<Int>() + var valid = true + for (row in a) { + var lp = -1 + row.forEachIndexed{cn, cell -> + if (lp == -1) { + if (cell == 1) { + lp = cn + } else if (cell != 0) { + valid = false + } + } + } + leadingone.add(lp) + if (!valid) { + return false + } + } + while (leadingone[leadingone.size-1] == -1) { + leadingone.removeLast() + } + var c = ArrayList(leadingone) + c.sort() + if (c[0] == -1) { + return false + } + if (c != leadingone) { + return false + } + for (i in c) { + var col = ArrayList(a.map { it[i] }) + col.sort() + if (col[col.size-1] != 1 || + col[col.size-2] != 0 || + col[0] != 0) { + return false + } + } + return true +} + +fun main() { + + if (!reducedrowechelon(listOf(listOf(1, 1, 0), listOf(0, 1, 0), listOf(0, 0, 0)))) { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (reducedrowechelon(listOf(listOf(0, 1, -2, 0, 1), listOf(0, 0, 0, 1, 3), listOf(0, 0, 0, 0, 0), listOf(0, 0, 0, 0, 0)))) { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (reducedrowechelon(listOf(listOf(1, 0, 0, 4), listOf(0, 1, 0, 7), listOf(0, 0, 1, -1)))) { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (!reducedrowechelon(listOf(listOf(0, 1, -2, 0, 1), listOf(0, 0, 0, 0, 0), listOf(0, 0, 0, 1, 3), listOf(0, 0, 0, 0, 0)))) { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (!reducedrowechelon(listOf(listOf(0, 1, 0), listOf(0, 1, 0), listOf(0, 0, 0)))) { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (!reducedrowechelon(listOf(listOf(4, 0, 0, 0), listOf(0, 1, 0, 7), listOf(0, 0, 1, -1)))) { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (!reducedrowechelon(listOf(listOf(1, 0, 0, 4), listOf(1, 0, 0, 7), listOf(0, 0, 1, -1)))) { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (!reducedrowechelon(listOf(listOf(1, -2, 0, 4), listOf(0, 1, 0, 7), listOf(0, 0, 1, -1)))) { + print("Pass") + } else { + print("Fail") + } + println("") + +} diff --git a/challenge-257/roger-bell-west/lua/ch-1.lua b/challenge-257/roger-bell-west/lua/ch-1.lua new file mode 100755 index 0000000000..fbd0bc40b4 --- /dev/null +++ b/challenge-257/roger-bell-west/lua/ch-1.lua @@ -0,0 +1,75 @@ +#! /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 smallerthancurrent(a) + local s = a + table.sort(s, function (i, j) return i < j end) + local l = {} + for i, n in ipairs(s) do + if l[n] == nil then + l[n] = i + end + end + local out = {} + for _, n in ipairs(a) do + table.insert(out, l[n]) + end + return out +end + +if recursive_compare(smallerthancurrent({5, 2, 1, 6}), {2, 1, 0, 3}) then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if recursive_compare(smallerthancurrent({1, 2, 0, 3}), {1, 2, 0, 3}) then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if recursive_compare(smallerthancurrent({0, 1}), {0, 1}) then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if recursive_compare(smallerthancurrent({9, 4, 9, 2}), {2, 1, 2, 0}) then + io.write("Pass") +else + io.write("FAIL") +end +print("") + diff --git a/challenge-257/roger-bell-west/lua/ch-2.lua b/challenge-257/roger-bell-west/lua/ch-2.lua new file mode 100755 index 0000000000..436dc433e3 --- /dev/null +++ b/challenge-257/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 reducedrowechelon(a) + local leadingone = {} + for _, row in ipairs(a) do + local lp = -1 + for cn, cell in ipairs(row) do + if cell == 1 then + lp = cn - 1 + break + elseif cell ~= 0 then + return false + end + end + table.insert(leadingone, lp) + end + while leadingone[#leadingone] == -1 do + table.remove(leadingone) + end + local c = leadingone + table.sort(c, function (i, j) return i < j end) + if c[1] == -1 then + return false + end + if not recursive_compare(c, leadingone) then + return false + end + for _, i in ipairs(c) do + local col = {} + for _b, row in ipairs(a) do + table.insert(col, row[i + 1]) + end + table.sort(col, function (i, j) return i < j end) + if col[#col] ~= 1 or col[#col - 1] ~= 0 or col[1] ~= 0 then + return false + end + end + return true +end + +if not reducedrowechelon({{1, 1, 0}, {0, 1, 0}, {0, 0, 0}}) then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if reducedrowechelon({{0, 1, -2, 0, 1}, {0, 0, 0, 1, 3}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}}) then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if reducedrowechelon({{1, 0, 0, 4}, {0, 1, 0, 7}, {0, 0, 1, -1}}) then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if not reducedrowechelon({{0, 1, -2, 0, 1}, {0, 0, 0, 0, 0}, {0, 0, 0, 1, 3}, {0, 0, 0, 0, 0}}) then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if not reducedrowechelon({{0, 1, 0}, {0, 1, 0}, {0, 0, 0}}) then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if not reducedrowechelon({{4, 0, 0, 0}, {0, 1, 0, 7}, {0, 0, 1, -1}}) then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if not reducedrowechelon({{1, 0, 0, 4}, {1, 0, 0, 7}, {0, 0, 1, -1}}) then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if not reducedrowechelon({{1, -2, 0, 4}, {0, 1, 0, 7}, {0, 0, 1, -1}}) then + io.write("Pass") +else + io.write("FAIL") +end +print("") + diff --git a/challenge-257/roger-bell-west/perl/ch-1.pl b/challenge-257/roger-bell-west/perl/ch-1.pl new file mode 100755 index 0000000000..3ebebbc636 --- /dev/null +++ b/challenge-257/roger-bell-west/perl/ch-1.pl @@ -0,0 +1,24 @@ +#! /usr/bin/perl + +use strict; +use warnings; +use experimental 'signatures'; + +use Test::More tests => 4; + +is_deeply(smallerthancurrent([5, 2, 1, 6]), [2, 1, 0, 3], 'example 1'); +is_deeply(smallerthancurrent([1, 2, 0, 3]), [1, 2, 0, 3], 'example 2'); +is_deeply(smallerthancurrent([0, 1]), [0, 1], 'example 3'); +is_deeply(smallerthancurrent([9, 4, 9, 2]), [2, 1, 2, 0], 'example 4'); + +sub smallerthancurrent($a) { + my %l; + my @s = sort {$::a <=> $::b} @{$a}; + foreach my $i (0..$#s) { + my $n = $s[$i]; + unless (exists $l{$n}) { + $l{$n} = $i; + } + } + return [map {$l{$_}} @{$a}]; +} diff --git a/challenge-257/roger-bell-west/perl/ch-2.pl b/challenge-257/roger-bell-west/perl/ch-2.pl new file mode 100755 index 0000000000..43a4621110 --- /dev/null +++ b/challenge-257/roger-bell-west/perl/ch-2.pl @@ -0,0 +1,53 @@ +#! /usr/bin/perl + +use strict; +use warnings; +use experimental 'signatures'; + +use Test::More tests => 8; +use Test::Deep::NoTest; + +is(reducedrowechelon([[1, 1, 0], [0, 1, 0], [0, 0, 0]]), 0, 'example 1'); +is(reducedrowechelon([[0, 1, -2, 0, 1], [0, 0, 0, 1, 3], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]), 1, 'example 2'); +is(reducedrowechelon([[1, 0, 0, 4], [0, 1, 0, 7], [0, 0, 1, -1]]), 1, 'example 3'); +is(reducedrowechelon([[0, 1, -2, 0, 1], [0, 0, 0, 0, 0], [0, 0, 0, 1, 3], [0, 0, 0, 0, 0]]), 0, 'example 4'); +is(reducedrowechelon([[0, 1, 0], [0, 1, 0], [0, 0, 0]]), 0, 'example 5'); +is(reducedrowechelon([[4, 0, 0, 0], [0, 1, 0, 7], [0, 0, 1, -1]]), 0, 'example 6'); +is(reducedrowechelon([[1, 0, 0, 4], [1, 0, 0, 7], [0, 0, 1, -1]]), 0, 'example 7'); +is(reducedrowechelon([[1, -2, 0, 4], [0, 1, 0, 7], [0, 0, 1, -1]]), 0, 'example 8'); + +sub reducedrowechelon($a) { + my @leadingone; + foreach my $row (@{$a}) { + my $lp = -1; + foreach my $cn (0 .. $#{$row}) { + my $cell = $row->[$cn]; + if ($cell == 1) { + $lp = $cn; + last; + } elsif ($cell != 0) { + return 0; + } + } + push @leadingone, $lp; + } + while ($leadingone[-1] == -1) { + pop @leadingone; + } + my @c = sort {$::a <=> $::b} @leadingone; + if ($c[0] == -1) { + return 0; + } + if (!eq_deeply(\@c, \@leadingone)) { + return 0; + } + foreach my $i (@c) { + my @col = sort {$::a <=> $::b} map {$_->[$i]} @{$a}; + if ($col[-1] != 1 || + $col[-2] != 0 || + $col[0] != 0) { + return 0; + } + } + return 1; +} diff --git a/challenge-257/roger-bell-west/postscript/ch-1.ps b/challenge-257/roger-bell-west/postscript/ch-1.ps new file mode 100644 index 0000000000..edaebf28b0 --- /dev/null +++ b/challenge-257/roger-bell-west/postscript/ch-1.ps @@ -0,0 +1,228 @@ +%!PS + +% begin included library code +% see https://codeberg.org/Firedrake/postscript-libraries/ +/quicksort.cmp { + 2 copy + lt { + pop pop -1 + } { + gt { + 1 + } { + 0 + } ifelse + } ifelse +} 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 + +/enumerate.array { + 1 dict begin + /a exch def + [ + 0 1 a length 1 sub { + [ exch dup a exch get ] + } 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 + +/quicksort { + { quicksort.cmp } quicksort.with_comparator +} 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.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.start { + print (:) print + /test.pass 0 def + /test.count 0 def +} 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 + +/map { % array proc -> array + 2 dict begin + /p exch def + [ exch + { + p + } forall + ] + 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 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 + +/smallerthancurrent { + 0 dict begin + dup + /l 0 dict def + [ exch aload pop ] quicksort enumerate.array { + aload pop + /n exch def + /i exch def + l n known not { + l n i put + } if + } forall + { l exch get } map + end +} bind def + +(smallerthancurrent) test.start +[5 2 1 6] smallerthancurrent [2 1 0 3] deepeq test +[1 2 0 3] smallerthancurrent [1 2 0 3] deepeq test +[0 1] smallerthancurrent [0 1] deepeq test +[9 4 9 2] smallerthancurrent [2 1 2 0] deepeq test +test.end diff --git a/challenge-257/roger-bell-west/postscript/ch-2.ps b/challenge-257/roger-bell-west/postscript/ch-2.ps new file mode 100644 index 0000000000..ea6ed2bf63 --- /dev/null +++ b/challenge-257/roger-bell-west/postscript/ch-2.ps @@ -0,0 +1,313 @@ +%!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 + +/map { % array proc -> array + 2 dict begin + /p exch def + [ exch + { + p + } forall + ] + 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 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 + +/test.start { + print (:) print + /test.pass 0 def + /test.count 0 def +} bind def + +/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 + +/apop.right { % [a b c] -> [a b] c + [ exch aload length 1 add 1 roll ] exch +} 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 + +/keys { % dict -> array of dict keys + [ exch + { + pop + } 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 + +/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.main { % lo hi -> (null) + 3 dict begin + /hi exch def + /lo exch def + / |
