diff options
| author | Mohammad Sajid Anwar <Mohammad.Anwar@yahoo.com> | 2023-12-26 20:00:39 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-12-26 20:00:39 +0000 |
| commit | daa81203fd6467dff10f82712fe8a71280929f25 (patch) | |
| tree | f5d08ad13d6111da9aef76f6dcc48522ddb4f79c | |
| parent | 2c61da4908dec6febe1ecaa44ff2e72def79df58 (diff) | |
| parent | 858a5a78afbe2f51d389af1d6f4dd5d4e28d9710 (diff) | |
| download | perlweeklychallenge-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
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 []; |
