diff options
| author | Mohammad Sajid Anwar <Mohammad.Anwar@yahoo.com> | 2024-06-18 20:12:05 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-06-18 20:12:05 +0100 |
| commit | ddbcbfcba49f227dc537c59c6a8f172f8a1e4390 (patch) | |
| tree | c71878136f517dac0e22f1568b02a34721a1580f | |
| parent | 2c8b134f83b8c30b9d30655942a6e5b81c2489f8 (diff) | |
| parent | 1c6cd189ee4f8416961ec458aebe5449accc7aaf (diff) | |
| download | perlweeklychallenge-club-ddbcbfcba49f227dc537c59c6a8f172f8a1e4390.tar.gz perlweeklychallenge-club-ddbcbfcba49f227dc537c59c6a8f172f8a1e4390.tar.bz2 perlweeklychallenge-club-ddbcbfcba49f227dc537c59c6a8f172f8a1e4390.zip | |
Merge pull request #10284 from Firedrake/rogerbw-challenge-274
RogerBW solutions for challenge no. 274
23 files changed, 1506 insertions, 0 deletions
diff --git a/challenge-274/roger-bell-west/crystal/ch-1.cr b/challenge-274/roger-bell-west/crystal/ch-1.cr new file mode 100755 index 0000000000..ae0cc9b8e5 --- /dev/null +++ b/challenge-274/roger-bell-west/crystal/ch-1.cr @@ -0,0 +1,32 @@ +#! /usr/bin/crystal + +def goatlatin(a) + out = [] of String + a.split(" ").each_with_index do |word, ix| + c = word.split("") + if c[0] !~ /[aeiou]/i + co = c.shift; + c.push(co) + end + nw = c.join("") + nw += "ma" + 0.upto(ix) do + nw += "a" + end + out.push(nw) + end + out.join(" ") +end + +require "spec" +describe "goatlatin" do + it "test_ex1" do + goatlatin("I love Perl").should eq "Imaa ovelmaaa erlPmaaaa" + end + it "test_ex2" do + goatlatin("Perl and Raku are friends").should eq "erlPmaa andmaaa akuRmaaaa aremaaaaa riendsfmaaaaaa" + end + it "test_ex3" do + goatlatin("The Weekly Challenge").should eq "heTmaa eeklyWmaaa hallengeCmaaaa" + end +end diff --git a/challenge-274/roger-bell-west/crystal/ch-2.cr b/challenge-274/roger-bell-west/crystal/ch-2.cr new file mode 100755 index 0000000000..36f4fa8789 --- /dev/null +++ b/challenge-274/roger-bell-west/crystal/ch-2.cr @@ -0,0 +1,57 @@ +#! /usr/bin/crystal + +def busroute(a) + route = [] of Hash(Int32, Int32) + a.each do |rt| + ri = Hash(Int32, Int32).new + interval, offset, duration = rt + start = offset + while true + if start > 60 + offset + break + end + ri[start] = start + duration + start += interval + end + route.push(ri) + end + out = [] of Int32 + 0.upto(59) do |t| + best = Set(Int32).new + at = -1 + nxt = Set(Int32).new + ndt = -1 + route.each_with_index do |r, i| + nb = r.keys.select { |n| n >= t }.min + nt = r[nb] + if at == -1 || nt < at + best.clear + at = nt + end + if nt <= at + best.add(i) + end + if ndt == -1 || nb < ndt + nxt.clear + ndt = nb + end + if nb <= ndt + nxt.add(i) + end + end + if (best & nxt) .size == 0 + out.push(t) + end + end + out +end + +require "spec" +describe "busroute" do + it "test_ex1" do + busroute([[12, 11, 41], [15, 5, 35]]).should eq [36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47] + end + it "test_ex2" do + busroute([[12, 3, 41], [15, 9, 35], [30, 5, 25]]).should eq [0, 1, 2, 3, 25, 26, 27, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 55, 56, 57, 58, 59] + end +end diff --git a/challenge-274/roger-bell-west/javascript/ch-1.js b/challenge-274/roger-bell-west/javascript/ch-1.js new file mode 100755 index 0000000000..b300b4d51f --- /dev/null +++ b/challenge-274/roger-bell-west/javascript/ch-1.js @@ -0,0 +1,40 @@ +#! /usr/bin/node + +"use strict" + +function goatlatin(a) { + let out = []; + a.split(" ").forEach((word, ix) => { + let c = word.split(""); + if (!c[0].match(/[aeiou]/i)) { + let co = c.shift(); + c.push(co); + } + let nw = c.join(""); + nw += "ma"; + for (let i = 0; i <= ix; i++) { + nw += "a"; + } + out.push(nw) + }); + return out.join(" "); +} + +if (goatlatin('I love Perl') == 'Imaa ovelmaaa erlPmaaaa') { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (goatlatin('Perl and Raku are friends') == 'erlPmaa andmaaa akuRmaaaa aremaaaaa riendsfmaaaaaa') { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (goatlatin('The Weekly Challenge') == 'heTmaa eeklyWmaaa hallengeCmaaaa') { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write("\n"); diff --git a/challenge-274/roger-bell-west/javascript/ch-2.js b/challenge-274/roger-bell-west/javascript/ch-2.js new file mode 100755 index 0000000000..a067c154bb --- /dev/null +++ b/challenge-274/roger-bell-west/javascript/ch-2.js @@ -0,0 +1,93 @@ +#! /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 busroute(a) { + let route = []; + for (let rt of a) { + let ri = new Map; + const interval = rt[0]; + const offset = rt[1]; + const duration = rt[2]; + let start = offset; + while (true) { + if (start > 60 + offset) { + break; + } + ri.set(start, start + duration); + start += interval; + } + route.push(ri); + } + let out = []; + for (let t = 0; t < 60; t++) { + let best = new Set; + let at = -1; + let nxt = new Set; + let ndt = -1; + route.forEach((r, i) => { + const nb = Math.min(...([...r.keys()].filter(n => n >= t))); + const nt = r.get(nb); + if (at == -1 || nt < at) { + best = new Set; + at = nt; + } + if (nt <= at) { + best.add(i); + } + if (ndt == -1 || nb < ndt) { + nxt = new Set; + ndt = nb; + } + if (nb <= ndt) { + nxt.add(i); + } + }); + const intersect = new Set([...best].filter(i => nxt.has(i))); + if (intersect.size == 0) { + out.push(t); + } + } + return out; +} + + +if (deepEqual(busroute([[12, 11, 41], [15, 5, 35]]), [36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (deepEqual(busroute([[12, 3, 41], [15, 9, 35], [30, 5, 25]]), [0, 1, 2, 3, 25, 26, 27, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 55, 56, 57, 58, 59])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write("\n"); diff --git a/challenge-274/roger-bell-west/kotlin/ch-1.kt b/challenge-274/roger-bell-west/kotlin/ch-1.kt new file mode 100644 index 0000000000..5e2e3bbb4c --- /dev/null +++ b/challenge-274/roger-bell-west/kotlin/ch-1.kt @@ -0,0 +1,48 @@ +fun is_vowel(c: Char): Boolean { + return when (c.lowercaseChar()) { + 'a', 'e', 'i', 'o', 'u' -> true + else -> false + } +} + +fun goatlatin(a: String): String { + var out = ArrayList<String>() + a.split(" ").forEachIndexed {i, word -> + var c = word.toList() + var nw = StringBuilder(word); + if (!is_vowel(c[0])) { + var co = ArrayList(c.drop(1)) + co.add(c[0]) + nw = StringBuilder(co.joinToString("")) + } + nw.append("ma") + for (ix in 0..i) { + nw.append("a") + } + out.add(nw.toString()) + } + return out.joinToString(" ") +} + +fun main() { + + if (goatlatin("I love Perl") == "Imaa ovelmaaa erlPmaaaa") { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (goatlatin("Perl and Raku are friends") == "erlPmaa andmaaa akuRmaaaa aremaaaaa riendsfmaaaaaa") { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (goatlatin("The Weekly Challenge") == "heTmaa eeklyWmaaa hallengeCmaaaa") { + print("Pass") + } else { + print("Fail") + } + println("") + +} diff --git a/challenge-274/roger-bell-west/kotlin/ch-2.kt b/challenge-274/roger-bell-west/kotlin/ch-2.kt new file mode 100644 index 0000000000..a09d3869a4 --- /dev/null +++ b/challenge-274/roger-bell-west/kotlin/ch-2.kt @@ -0,0 +1,61 @@ +fun busroute(a: List<List<Int>>): List<Int> { + var route = ArrayList<Map<Int, Int>>() + for (rt in a) { + var ri = mutableMapOf<Int, Int>() + val interval = rt[0] + val offset = rt[1] + val duration = rt[2] + var start = offset + while (start <= 60 + offset) { + ri.put(start, start + duration) + start += interval + } + route.add(ri) + } + var out = ArrayList<Int>() + for (t in 0 .. 59) { + var best = mutableSetOf<Int>() + var at = -1 + var nxt = mutableSetOf<Int>() + var ndt = -1 + route.forEachIndexed {i, r -> + val nb = r.keys.filter{it >= t}.minOrNull()!! + val nt = r.getValue(nb) + if (at == -1 || nt < at) { + best = mutableSetOf<Int>() + at = nt + } + if (nt <= at) { + best.add(i) + } + if (ndt == -1 || nb < ndt) { + nxt = mutableSetOf<Int>() + ndt = nb + } + if (nb <= ndt) { + nxt.add(i) + } + } + if (best.intersect(nxt).isEmpty()) { + out.add(t) + } + } + return out.toList() +} + +fun main() { + + if (busroute(listOf(listOf(12, 11, 41), listOf(15, 5, 35))) == listOf(36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47)) { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (busroute(listOf(listOf(12, 3, 41), listOf(15, 9, 35), listOf(30, 5, 25))) == listOf(0, 1, 2, 3, 25, 26, 27, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 55, 56, 57, 58, 59)) { + print("Pass") + } else { + print("Fail") + } + println("") + +} diff --git a/challenge-274/roger-bell-west/lua/ch-1.lua b/challenge-274/roger-bell-west/lua/ch-1.lua new file mode 100755 index 0000000000..1127f03cb4 --- /dev/null +++ b/challenge-274/roger-bell-west/lua/ch-1.lua @@ -0,0 +1,86 @@ +#! /usr/bin/lua + +-- bart at https://stackoverflow.com/questions/1426954/split-string-in-lua +function splits(inputstr, sep) + sep=sep or '%s' + local t={} + for field,s in string.gmatch(inputstr, "([^"..sep.."]*)("..sep.."?)") do + table.insert(t,field) + if s=="" then + return t + end + end +end + +function split(t) + local cl = {} + string.gsub(t, + "(.)", + function(c) + table.insert(cl, c) + end + ) + return cl +end + +function join(t) + local out="" + for i, v in ipairs(t) do + out = out .. v + end + return out +end + +function joins(t,pad) + local out="" + local later = false + for k,v in pairs(t) do + if later then + out = out .. pad + end + out = out .. v + later = true + end + return out +end + +function goatlatin(a) + local out = {} + for ix, word in ipairs(splits(a, " ")) do + local nw = word + local c = split(word) + if string.match(c[1], "[^aeiouAEIOU]") then + table.insert(c, c[1]) + table.remove(c, 1) + nw = join(c) + end + nw = nw .. "ma" + for i = 1, ix do + nw = nw .. "a" + end + table.insert(out, nw) + end + return joins(out, " ") +end + +if goatlatin("I love Perl") == "Imaa ovelmaaa erlPmaaaa" then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if goatlatin("Perl and Raku are friends") == "erlPmaa andmaaa akuRmaaaa aremaaaaa riendsfmaaaaaa" then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if goatlatin("The Weekly Challenge") == "heTmaa eeklyWmaaa hallengeCmaaaa" then + io.write("Pass") +else + io.write("FAIL") +end +print("") + diff --git a/challenge-274/roger-bell-west/lua/ch-2.lua b/challenge-274/roger-bell-west/lua/ch-2.lua new file mode 100755 index 0000000000..2f50581f13 --- /dev/null +++ b/challenge-274/roger-bell-west/lua/ch-2.lua @@ -0,0 +1,104 @@ +#! /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 busroute(a) + local routes = {} + for _, rt in ipairs(a) do + local ri = {} + local interval = rt[1] + local offset = rt[2] + local duration = rt[3] + local start = offset + while start <= 60 + offset do + ri[start] = start + duration + start = start + interval + end + table.insert(routes, rt) + end + local out = {} + for t = 0, 59 do + local best = {} + local at = -1 + local nxt = {} + local ndt = -1 + for i, r in ipairs(routes) do + local nb = 999 + local nt = 0 + for n, l in ipairs(r) do + if n >= t then + if l < nb then + nb = n + nt = l + end + end + end + if at == -1 or nt < at then + best = {} + at = nt + end + if nt <= at then + best[i] = true + end + if ndt == -1 or nb < ndt then + nxt = {} + ndt = nb + end + if nb <= ndt then + nxt[i] = true + end + end + local intersect = {} + for k, v in pairs(best) do + if nxt[k] ~= nil then + table.insert(intersect, k) + end + end + if #intersect == 0 then + table.insert(out, t) + end + end + return out +end + +if recursive_compare(busroute({{12, 11, 41}, {15, 5, 35}}), {36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47}) then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if recursive_compare(busroute({{12, 3, 41}, {15, 9, 35}, {30, 5, 25}}), {0, 1, 2, 3, 25, 26, 27, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 55, 56, 57, 58, 59}) then + io.write("Pass") +else + io.write("FAIL") +end +print("") + diff --git a/challenge-274/roger-bell-west/perl/ch-1.pl b/challenge-274/roger-bell-west/perl/ch-1.pl new file mode 100755 index 0000000000..6cb6190b8c --- /dev/null +++ b/challenge-274/roger-bell-west/perl/ch-1.pl @@ -0,0 +1,28 @@ +#! /usr/bin/perl + +use strict; +use warnings; +use experimental 'signatures'; + +use Test::More tests => 3; + +is(goatlatin('I love Perl'), 'Imaa ovelmaaa erlPmaaaa', 'example 1'); +is(goatlatin('Perl and Raku are friends'), 'erlPmaa andmaaa akuRmaaaa aremaaaaa riendsfmaaaaaa', 'example 2'); +is(goatlatin('The Weekly Challenge'), 'heTmaa eeklyWmaaa hallengeCmaaaa', 'example 3'); + +sub goatlatin($a) { + my @out; + my @w = split ' ', $a; + while (my ($ix, $word) = each @w) { + my @c = split '',$word; + my $nw = $word; + if ($c[0] !~ /[aeiou]/i) { + push @c,shift @c; + $nw = join('', @c); + } + $nw .= 'ma'; + $nw .= 'a' x ($ix + 1); + push @out, $nw; + } + return join(' ', @out); +} diff --git a/challenge-274/roger-bell-west/perl/ch-2.pl b/challenge-274/roger-bell-west/perl/ch-2.pl new file mode 100755 index 0000000000..5a3ee1c7ae --- /dev/null +++ b/challenge-274/roger-bell-west/perl/ch-2.pl @@ -0,0 +1,57 @@ +#! /usr/bin/perl + +use strict; +use warnings; +use experimental 'signatures'; + +use Test::More tests => 2; + +is_deeply(busroute([[12, 11, 41], [15, 5, 35]]), [36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47], 'example 1'); +is_deeply(busroute([[12, 3, 41], [15, 9, 35], [30, 5, 25]]), [0, 1, 2, 3, 25, 26, 27, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 55, 56, 57, 58, 59], 'example 2'); + +use List::Util qw(min); + +sub busroute($a) { + my @routes; + foreach my $rt (@{$a}) { + my %ri; + my ($interval, $offset, $duration) = @{$rt}; + my $start = $offset; + while ($start <= 60 + $offset) { + $ri{$start} = $start + $duration; + $start += $interval; + } + push @routes, \%ri; + } + my @out; + foreach my $t (0 .. 59) { + my %best; + my $at = -1; + my %nxt; + my $ndt = -1; + values @routes; + while (my ($i, $r) = each @routes) { + my $nb = min grep {$_ >= $t} keys(%{$r}); + my $nt = $r->{$nb}; + if ($at == -1 || $nt < $at) { + %best = (); + $at = $nt; + } + if ($nt <= $at) { + $best{$i} = 1; + } + if ($ndt == -1 || $nb < $ndt) { + %nxt = (); + $ndt = $nb; + } + if ($nb <= $ndt) { + $nxt{$i} = 1; + } + } + my @intersect = grep {exists $nxt{$_}} keys %best; + if (scalar @intersect == 0) { + push @out, $t; + } + } + return \@out; +} diff --git a/challenge-274/roger-bell-west/postscript/ch-1.ps b/challenge-274/roger-bell-west/postscript/ch-1.ps new file mode 100644 index 0000000000..09be170853 --- /dev/null +++ b/challenge-274/roger-bell-west/postscript/ch-1.ps @@ -0,0 +1,158 @@ +%!PS + +% begin included library code +% see https://codeberg.org/Firedrake/postscript-libraries/ +/strconcat % (a) (b) -> (ab) +{ + [ + 3 -1 roll + s2a aload length + 2 add -1 roll + s2a aload pop + ] a2s +} bind def + +/a2s { + 2 dict begin + /i exch def + i length dup string /o exch def + 1 sub 0 exch 1 exch { + dup i 3 -1 roll get o 3 1 roll put + } for + o + 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 + +/toset { % array -> dict of (value, true) + << exch + { + true + } forall + >> +} bind def + +/test.start { + print (:) print + /test.pass 0 def + /test.count 0 def +} 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 + +/enumerate.array { + 1 dict begin + /a exch def + [ + 0 1 a length 1 sub { + [ exch dup a exch get ] + } for + ] + end +} bind def + +/strsplit % (ajbjc) (j) -> [ (a) (b) (c) ] +{ + 1 dict begin + /sep exch def + [ exch + { + dup length 0 eq { + pop + exit + } { + sep search { + exch pop + dup length 0 eq { + pop + } { + exch + } ifelse + } { + () + } ifelse + } ifelse + } loop + ] + end +} bind def + +/s2a { + [ exch { } forall ] +} bind def + +/strjoin % [(a) (b) (c)] (j) -> (ajbjc) +{ + 3 dict begin + /j exch def + dup 0 get /out exch def + /first true def + { + first { + pop + /first false def + } { + out j strconcat + exch strconcat + /out exch def + } ifelse + } forall + out + end +} bind def + + +% end included library code + +/goatlatin { + 0 dict begin + /vowels (aeiouAEIOU) s2a toset def + [ exch + ( ) strsplit enumerate.array { + aload pop + /c exch s2a def + /i exch def + [ + c aload pop + vowels c 0 get known not { + c length -1 roll + } if + 109 + 97 + i 1 add { + 97 + } repeat + ] a2s + } forall + ] ( ) strjoin + end +} bind def + +(goatlatin) test.start +(I love Perl) goatlatin (Imaa ovelmaaa erlPmaaaa) eq test +(Perl and Raku are friends) goatlatin (erlPmaa andmaaa akuRmaaaa aremaaaaa riendsfmaaaaaa) eq test +(The Weekly Challenge) goatlatin (heTmaa eeklyWmaaa hallengeCmaaaa) eq test +test.end diff --git a/challenge-274/roger-bell-west/postscript/ch-2.ps b/challenge-274/roger-bell-west/postscript/ch-2.ps new file mode 100644 index 0000000000..f34399caf4 --- /dev/null +++ b/challenge-274/roger-bell-west/postscript/ch-2.ps @@ -0,0 +1,221 @@ +%!PS + +% begin included library code +% see https://codeberg.org/Firedrake/postscript-libraries/ +/test.start { + print (:) print + /test.pass 0 def + /test.count 0 def +} bind def + +/set.intersection { + 4 dict begin + /s 0 dict def + /b exch def + /a exch def + a keys { + /k exch def + b k known { + s k true put + } if + } forall + s + 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 + +/keys { % dict -> array of dict keys + [ exch + { + pop + } forall + ] +} 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 + +/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 + +/listmin { + { min } reduce +} 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 + +/enumerate.array { + 1 dict begin + /a exch def + [ + 0 1 a length 1 sub { + [ exch dup a exch get ] + } for + ] + end +} bind def + +/filter { % array proc(bool) -> array + 1 dict begin + /p exch def + [ exch + { + dup p not + { + pop |
