From b3d35809f9e728cd1e057ccc7980e0d77f6970f4 Mon Sep 17 00:00:00 2001 From: Roger Bell_West Date: Tue, 19 Aug 2025 12:16:29 +0100 Subject: RogerBW solutions for challenge no. 335 --- challenge-335/roger-bell-west/crystal/ch-1.cr | 55 +++++ challenge-335/roger-bell-west/crystal/ch-2.cr | 63 ++++++ challenge-335/roger-bell-west/javascript/ch-1.js | 101 +++++++++ challenge-335/roger-bell-west/javascript/ch-2.js | 73 +++++++ challenge-335/roger-bell-west/kotlin/ch-1.kt | 70 ++++++ challenge-335/roger-bell-west/kotlin/ch-2.kt | 76 +++++++ challenge-335/roger-bell-west/lua/ch-1.lua | 123 +++++++++++ challenge-335/roger-bell-west/lua/ch-2.lua | 85 ++++++++ challenge-335/roger-bell-west/perl/ch-1.pl | 43 ++++ challenge-335/roger-bell-west/perl/ch-2.pl | 56 +++++ challenge-335/roger-bell-west/postscript/ch-1.ps | 261 +++++++++++++++++++++++ challenge-335/roger-bell-west/postscript/ch-2.ps | 167 +++++++++++++++ challenge-335/roger-bell-west/python/ch-1.py | 52 +++++ challenge-335/roger-bell-west/python/ch-2.py | 53 +++++ challenge-335/roger-bell-west/raku/ch-1.p6 | 39 ++++ challenge-335/roger-bell-west/raku/ch-2.p6 | 54 +++++ challenge-335/roger-bell-west/ruby/ch-1.rb | 63 ++++++ challenge-335/roger-bell-west/ruby/ch-2.rb | 72 +++++++ challenge-335/roger-bell-west/rust/ch-1.rs | 58 +++++ challenge-335/roger-bell-west/rust/ch-2.rs | 111 ++++++++++ challenge-335/roger-bell-west/scala/ch-1.scala | 74 +++++++ challenge-335/roger-bell-west/scala/ch-2.scala | 86 ++++++++ challenge-335/roger-bell-west/tests.json | 76 +++++++ challenge-335/roger-bell-west/typst/ch-1.typ | 58 +++++ challenge-335/roger-bell-west/typst/ch-2.typ | 72 +++++++ 25 files changed, 2041 insertions(+) create mode 100755 challenge-335/roger-bell-west/crystal/ch-1.cr create mode 100755 challenge-335/roger-bell-west/crystal/ch-2.cr create mode 100755 challenge-335/roger-bell-west/javascript/ch-1.js create mode 100755 challenge-335/roger-bell-west/javascript/ch-2.js create mode 100644 challenge-335/roger-bell-west/kotlin/ch-1.kt create mode 100644 challenge-335/roger-bell-west/kotlin/ch-2.kt create mode 100755 challenge-335/roger-bell-west/lua/ch-1.lua create mode 100755 challenge-335/roger-bell-west/lua/ch-2.lua create mode 100755 challenge-335/roger-bell-west/perl/ch-1.pl create mode 100755 challenge-335/roger-bell-west/perl/ch-2.pl create mode 100644 challenge-335/roger-bell-west/postscript/ch-1.ps create mode 100644 challenge-335/roger-bell-west/postscript/ch-2.ps create mode 100755 challenge-335/roger-bell-west/python/ch-1.py create mode 100755 challenge-335/roger-bell-west/python/ch-2.py create mode 100755 challenge-335/roger-bell-west/raku/ch-1.p6 create mode 100755 challenge-335/roger-bell-west/raku/ch-2.p6 create mode 100755 challenge-335/roger-bell-west/ruby/ch-1.rb create mode 100755 challenge-335/roger-bell-west/ruby/ch-2.rb create mode 100755 challenge-335/roger-bell-west/rust/ch-1.rs create mode 100755 challenge-335/roger-bell-west/rust/ch-2.rs create mode 100644 challenge-335/roger-bell-west/scala/ch-1.scala create mode 100644 challenge-335/roger-bell-west/scala/ch-2.scala create mode 100644 challenge-335/roger-bell-west/tests.json create mode 100644 challenge-335/roger-bell-west/typst/ch-1.typ create mode 100644 challenge-335/roger-bell-west/typst/ch-2.typ diff --git a/challenge-335/roger-bell-west/crystal/ch-1.cr b/challenge-335/roger-bell-west/crystal/ch-1.cr new file mode 100755 index 0000000000..d16cb98692 --- /dev/null +++ b/challenge-335/roger-bell-west/crystal/ch-1.cr @@ -0,0 +1,55 @@ +#! /usr/bin/crystal + +def counterify(a) + cc = Hash(Char, Int32).new(default_value: 0) + a.each do |x| + cc[x] += 1 + end + return cc +end + +def commoncharacters(a) + mc = Hash(Char, Int32).new + first = true + a.each do |s| + mk = counterify(s.chars) + if first + mc = mk + first = false + else + mc.keys.each do |k| + if mk.has_key?(k) + mc[k] = [mc[k], mk[k]].min + else + mc.delete(k) + end + end + end + end + out = Array(String).new + mc.keys.sort.each do |c| + 1.upto(mc[c]) do + out.push(c.to_s) + end + end + out +end + +require "spec" +describe "commoncharacters" do + it "test_ex1" do + commoncharacters(["bella", "label", "roller"]).should eq ["e", "l", "l"] + end + it "test_ex2" do + commoncharacters(["cool", "lock", "cook"]).should eq ["c", "o"] + end + it "test_ex3" do + commoncharacters(["hello", "world", "pole"]).should eq ["l", "o"] + end + it "test_ex4" do + commoncharacters(["abc", "def", "ghi"]).should eq Array(String).new + end + it "test_ex5" do + commoncharacters(["aab", "aac", "aaa"]).should eq ["a", "a"] + end +end diff --git a/challenge-335/roger-bell-west/crystal/ch-2.cr b/challenge-335/roger-bell-west/crystal/ch-2.cr new file mode 100755 index 0000000000..29405bd9d8 --- /dev/null +++ b/challenge-335/roger-bell-west/crystal/ch-2.cr @@ -0,0 +1,63 @@ +#! /usr/bin/crystal + +def findwinner(a) + board = [ + [ 0, 0, 0 ], + [ 0, 0, 0 ], + [ 0, 0, 0 ] + ] + player = 1 + a.each do |play| + board[play[0]][play[1]] = player + player = 3 - player + end + [ + [0, 0, 1, 0], + [0, 1, 1, 0], + [0, 2, 1, 0], + [0, 0, 0, 1], + [1, 0, 0, 1], + [2, 0, 0, 1], + [0, 0, 1, 1], + [0, 2, 1, -1], + ].each do |pattern| + cellvals = Set(Int32).new + 0.upto(2) do |i| + x = pattern[0] + i * pattern[2] + y = pattern[1] + i * pattern[3] + cellvals.add(board[y][x]) + end + if cellvals.size == 1 + winner = cellvals.to_a[0] + if winner == 1 + return "A" + elsif winner == 2 + return "B" + end + end + end + if a.size == 9 + return "Draw" + else + return "Pending" + end +end + +require "spec" +describe "findwinner" do + it "test_ex1" do + findwinner([[0, 0], [2, 0], [1, 1], [2, 1], [2, 2]]).should eq "A" + end + it "test_ex2" do + findwinner([[0, 0], [1, 1], [0, 1], [0, 2], [1, 0], [2, 0]]).should eq "B" + end + it "test_ex3" do + findwinner([[0, 0], [1, 1], [2, 0], [1, 0], [1, 2], [2, 1], [0, 1], [0, 2], [2, 2]]).should eq "Draw" + end + it "test_ex4" do + findwinner([[0, 0], [1, 1]]).should eq "Pending" + end + it "test_ex5" do + findwinner([[1, 1], [0, 0], [2, 2], [0, 1], [1, 0], [0, 2]]).should eq "B" + end +end diff --git a/challenge-335/roger-bell-west/javascript/ch-1.js b/challenge-335/roger-bell-west/javascript/ch-1.js new file mode 100755 index 0000000000..7c002de222 --- /dev/null +++ b/challenge-335/roger-bell-west/javascript/ch-1.js @@ -0,0 +1,101 @@ +#! /usr/bin/node + +"use strict" + +function commoncharacters(a) { + let mc = new Map; + let first = true; + for (let s of a) { + const mk = counterify(s.split("")); + if (first) { + mc = mk; + first = false; + } else { + for (let k of mc.keys()) { + if (mk.has(k)) { + mc.set(k, Math.min(mc.get(k), mk.get(k))); + } else { + mc.delete(k); + } + } + } + } + let out = []; + let kl = [...mc.keys()]; + kl.sort(); + for (let c of kl) { + for (let n = 1; n <= mc.get(c); n++) { + out.push(c); + } + } + return out; +} + +function counterify(a) { + let cc = new Map; + for (let x of a) { + if (!cc.has(x)) { + cc.set(x, 0); + } + cc.set(x, cc.get(x) + 1); + } + return cc; +} + +// 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(commoncharacters(['bella', 'label', 'roller']), ['e', 'l', 'l'])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (deepEqual(commoncharacters(['cool', 'lock', 'cook']), ['c', 'o'])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (deepEqual(commoncharacters(['hello', 'world', 'pole']), ['l', 'o'])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (deepEqual(commoncharacters(['abc', 'def', 'ghi']), [])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (deepEqual(commoncharacters(['aab', 'aac', 'aaa']), ['a', 'a'])) { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write("\n"); diff --git a/challenge-335/roger-bell-west/javascript/ch-2.js b/challenge-335/roger-bell-west/javascript/ch-2.js new file mode 100755 index 0000000000..a3eda21565 --- /dev/null +++ b/challenge-335/roger-bell-west/javascript/ch-2.js @@ -0,0 +1,73 @@ +#! /usr/bin/node + +"use strict" + +function findwinner(a) { + let board = [ [0, 0, 0], [0, 0, 0], [0, 0, 0] ]; + let player = 1; + for (let play of a) { + board[play[0]][play[1]] = player; + player = 3 - player; + } + for (let pattern of [ + [0, 0, 1, 0], + [0, 1, 1, 0], + [0, 2, 1, 0], + [0, 0, 0, 1], + [1, 0, 0, 1], + [2, 0, 0, 1], + [0, 0, 1, 1], + [0, 2, 1, -1] + ]) { + let cellvals = new Set; + for (let i = 0; i <= 2; i++) { + const x = pattern[0] + i * pattern[2]; + const y = pattern[1] + i * pattern[3]; + cellvals.add(board[y][x]); + } + if (cellvals.size == 1) { + let winner = [...cellvals][0]; + if (winner == 1) { + return "A"; + } else if (winner == 2) { + return "B"; + } + } + } + if (a.length == 9) { + return "Draw"; + } else { + return "Pending"; + } +} + +if (findwinner([[0, 0], [2, 0], [1, 1], [2, 1], [2, 2]]) == 'A') { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (findwinner([[0, 0], [1, 1], [0, 1], [0, 2], [1, 0], [2, 0]]) == 'B') { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (findwinner([[0, 0], [1, 1], [2, 0], [1, 0], [1, 2], [2, 1], [0, 1], [0, 2], [2, 2]]) == 'Draw') { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (findwinner([[0, 0], [1, 1]]) == 'Pending') { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write(" "); +if (findwinner([[1, 1], [0, 0], [2, 2], [0, 1], [1, 0], [0, 2]]) == 'B') { + process.stdout.write("Pass"); +} else { + process.stdout.write("FAIL"); +} +process.stdout.write("\n"); diff --git a/challenge-335/roger-bell-west/kotlin/ch-1.kt b/challenge-335/roger-bell-west/kotlin/ch-1.kt new file mode 100644 index 0000000000..b63b668434 --- /dev/null +++ b/challenge-335/roger-bell-west/kotlin/ch-1.kt @@ -0,0 +1,70 @@ +fun counterify(a: List): Map { + var cc = mutableMapOf().withDefault({0}) + for (x in a) { + cc.set(x, cc.getValue(x) + 1) + } + return cc +} + +fun commoncharacters(a: List): List { + var mc = mutableMapOf().withDefault({0}) + var first = true + for (s in a) { + val mk = counterify(s.toCharArray().toList()) + if (first) { + mc = mk.toMutableMap() + first = false + } else { + for (k in mc.keys.toList()) { + if (mk.contains(k)) { + mc.set(k, listOf(mc.getValue(k), mk.getValue(k)).minOrNull()!!) + } else { + mc.remove(k) + } + } + } + } + var out = ArrayList() + for (c in mc.keys.sorted()) { + val s = c.toString() + for (n in 1 .. mc.getValue(c)) { + out.add(s) + } + } + return out.toList() +} + +fun main() { + + if (commoncharacters(listOf("bella", "label", "roller")) == listOf("e", "l", "l")) { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (commoncharacters(listOf("cool", "lock", "cook")) == listOf("c", "o")) { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (commoncharacters(listOf("hello", "world", "pole")) == listOf("l", "o")) { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (commoncharacters(listOf("abc", "def", "ghi")) == emptyList()) { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (commoncharacters(listOf("aab", "aac", "aaa")) == listOf("a", "a")) { + print("Pass") + } else { + print("Fail") + } + println("") + +} diff --git a/challenge-335/roger-bell-west/kotlin/ch-2.kt b/challenge-335/roger-bell-west/kotlin/ch-2.kt new file mode 100644 index 0000000000..2cb9878611 --- /dev/null +++ b/challenge-335/roger-bell-west/kotlin/ch-2.kt @@ -0,0 +1,76 @@ +fun findwinner(a: List>): String { + var board = ArrayList(listOf(ArrayList(listOf(0, 0, 0)), + ArrayList(listOf(0, 0, 0)), + ArrayList(listOf(0, 0, 0)) + )) + var player = 1 + for (play in a) { + board[play[0]][play[1]] = player + player = 3 - player + } + for (pattern in listOf( + listOf(0, 0, 1, 0), + listOf(0, 1, 1, 0), + listOf(0, 2, 1, 0), + listOf(0, 0, 0, 1), + listOf(1, 0, 0, 1), + listOf(2, 0, 0, 1), + listOf(0, 0, 1, 1), + listOf(0, 2, 1, -1) + )) { + var cellvals = mutableSetOf() + for (i in 0 .. 2) { + val x = pattern[0] + i * pattern[2] + val y = pattern[1] + i * pattern[3] + cellvals.add(board[y][x]) + } + if (cellvals.size == 1) { + var winner = cellvals.toList()[0] + if (winner == 1) { + return "A" + } else if (winner == 2) { + return "B" + } + } + } + if (a.size == 9) { + return "Draw" + } else { + return "Pending" + } +} + +fun main() { + + if (findwinner(listOf(listOf(0, 0), listOf(2, 0), listOf(1, 1), listOf(2, 1), listOf(2, 2))) == "A") { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (findwinner(listOf(listOf(0, 0), listOf(1, 1), listOf(0, 1), listOf(0, 2), listOf(1, 0), listOf(2, 0))) == "B") { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (findwinner(listOf(listOf(0, 0), listOf(1, 1), listOf(2, 0), listOf(1, 0), listOf(1, 2), listOf(2, 1), listOf(0, 1), listOf(0, 2), listOf(2, 2))) == "Draw") { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (findwinner(listOf(listOf(0, 0), listOf(1, 1))) == "Pending") { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (findwinner(listOf(listOf(1, 1), listOf(0, 0), listOf(2, 2), listOf(0, 1), listOf(1, 0), listOf(0, 2))) == "B") { + print("Pass") + } else { + print("Fail") + } + println("") + +} diff --git a/challenge-335/roger-bell-west/lua/ch-1.lua b/challenge-335/roger-bell-west/lua/ch-1.lua new file mode 100755 index 0000000000..200f658fec --- /dev/null +++ b/challenge-335/roger-bell-west/lua/ch-1.lua @@ -0,0 +1,123 @@ +#! /usr/bin/lua + +function commoncharacters(a) + local mc = {} + for sn, s in ipairs(a) do + local mk = counterify(split(s)) + if sn == 1 then + mc = mk + else + for k, _v in pairs(mc) do + if mk[k] ~= nil then + mc[k] = math.min(mc[k], mk[k]) + else + mc[k] = nil + end + end + end + end + local out = {} + local kl = keys(mc) + table.sort(kl) + for _, c in ipairs(kl) do + for n = 1, mc[c] do + table.insert(out, c) + end + end + return out +end + +function keys(t) + local a = {} + for k, v in pairs(t) do + table.insert(a, k) + end + return a +end + +function counterify(a) + local cc = {} + for _, c in ipairs(a) do + if cc[c] == nil then + cc[c] = 0 + end + cc[c] = cc[c] + 1 + end + return cc +end + +function split(t) + local cl = {} + string.gsub(t, + "(.)", + function(c) + table.insert(cl, c) + end + ) + return cl +end + +-- 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 + +if recursive_compare(commoncharacters({"bella", "label", "roller"}), {"e", "l", "l"}) then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if recursive_compare(commoncharacters({"cool", "lock", "cook"}), {"c", "o"}) then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if recursive_compare(commoncharacters({"hello", "world", "pole"}), {"l", "o"}) then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if recursive_compare(commoncharacters({"abc", "def", "ghi"}), {}) then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if recursive_compare(commoncharacters({"aab", "aac", "aaa"}), {"a", "a"}) then + io.write("Pass") +else + io.write("FAIL") +end +print("") + diff --git a/challenge-335/roger-bell-west/lua/ch-2.lua b/challenge-335/roger-bell-west/lua/ch-2.lua new file mode 100755 index 0000000000..573112c886 --- /dev/null +++ b/challenge-335/roger-bell-west/lua/ch-2.lua @@ -0,0 +1,85 @@ +#! /usr/bin/lua + +function findwinner(a) + local board = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } } + local player = 1 + for _, play in ipairs(a) do + board[1 + play[1]][1 + play[2]] = player + player = 3 - player + end + for _, pattern in ipairs({ + {0, 0, 1, 0}, + {0, 1, 1, 0}, + {0, 2, 1, 0}, + {0, 0, 0, 1}, + {1, 0, 0, 1}, + {2, 0, 0, 1}, + {0, 0, 1, 1}, + {0, 2, 1, -1} + }) do + local cellvals = {} + for i = 0, 2 do + local x = 1 + pattern[1] + i * pattern[3] + local y = 1 + pattern[2] + i * pattern[4] + cellvals[board[y][x]] = true + end + local w = keys(cellvals) + if #w == 1 then + local winner = w[1] + if winner == 1 then + return "A" + elseif winner == 2 then + return "B" + end + end + end + if #a == 9 then + return "Draw" + else + return "Pending" + end +end + +function keys(t) + local a = {} + for k, v in pairs(t) do + table.insert(a, k) + end + return a +end + +if findwinner({{0, 0}, {2, 0}, {1, 1}, {2, 1}, {2, 2}}) == "A" then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if findwinner({{0, 0}, {1, 1}, {0, 1}, {0, 2}, {1, 0}, {2, 0}}) == "B" then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if findwinner({{0, 0}, {1, 1}, {2, 0}, {1, 0}, {1, 2}, {2, 1}, {0, 1}, {0, 2}, {2, 2}}) == "Draw" then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if findwinner({{0, 0}, {1, 1}}) == "Pending" then + io.write("Pass") +else + io.write("FAIL") +end +io.write(" ") + +if findwinner({{1, 1}, {0, 0}, {2, 2}, {0, 1}, {1, 0}, {0, 2}}) == "B" then + io.write("Pass") +else + io.write("FAIL") +end +print("") + diff --git a/challenge-335/roger-bell-west/perl/ch-1.pl b/challenge-335/roger-bell-west/perl/ch-1.pl new file mode 100755 index 0000000000..e8c55e6a0c --- /dev/null +++ b/challenge-335/roger-bell-west/perl/ch-1.pl @@ -0,0 +1,43 @@ +#! /usr/bin/perl + +use strict; +use warnings; +use experimental 'signatures'; + +use Test::More tests => 5; + +is_deeply(commoncharacters(['bella', 'label', 'roller']), ['e', 'l', 'l'], 'example 1'); +is_deeply(commoncharacters(['cool', 'lock', 'cook']), ['c', 'o'], 'example 2'); +is_deeply(commoncharacters(['hello', 'world', 'pole']), ['l', 'o'], 'example 3'); +is_deeply(commoncharacters(['abc', 'def', 'ghi']), [], 'example 4'); +is_deeply(commoncharacters(['aab', 'aac', 'aaa']), ['a', 'a'], 'example 5'); + +use List::Util qw(min); + +sub commoncharacters($a) { + my %mc; + my $first = 1; + foreach my $s (@{$a}) { + my %mk; + map {$mk{$_}++} split '',$s; + if ($first) { + %mc = %mk; + $first = 0; + } else { + foreach my $k (keys %mc) { + if (exists $mk{$k}) { + $mc{$k} = min($mc{$k}, $mk{$k}); + } else { + delete $mc{$k}; + } + } + } + } + my @out; + foreach my $c (sort keys %mc) { + foreach (1 .. $mc{$c}) { + push @out, $c; + } + } + \@out; +} diff --git a/challenge-335/roger-bell-west/perl/ch-2.pl b/challenge-335/roger-bell-west/perl/ch-2.pl new file mode 100755 index 0000000000..bf5f0f13cc --- /dev/null +++ b/challenge-335/roger-bell-west/perl/ch-2.pl @@ -0,0 +1,56 @@ +#! /usr/bin/perl + +use strict; +use warnings; +use experimental 'signatures'; + +use Test::More tests => 5; + +is(findwinner([[0, 0], [2, 0], [1, 1], [2, 1], [2, 2]]), 'A', 'example 1'); +is(findwinner([[0, 0], [1, 1], [0, 1], [0, 2], [1, 0], [2, 0]]), 'B', 'example 2'); +is(findwinner([[0, 0], [1, 1], [2, 0], [1, 0], [1, 2], [2, 1], [0, 1], [0, 2], [2, 2]]), 'Draw', 'example 3'); +is(findwinner([[0, 0], [1, 1]]), 'Pending', 'example 4'); +is(findwinner([[1, 1], [0, 0], [2, 2], [0, 1], [1, 0], [0, 2]]), 'B', 'example 5'); + +sub findwinner($a) { + my @board = ( + [ 0, 0, 0 ], + [ 0, 0, 0 ], + [ 0, 0, 0 ], + ); + my $player = 1; + foreach my $play (@{$a}) { + $board[$play->[0]][$play->[1]] = $player; + $player = 3 - $player; + } + foreach my $pattern ( + [0, 0, 1, 0], + [0, 1, 1, 0], + [0, 2, 1, 0], + [0, 0, 0, 1], + [1, 0, 0, 1], + [2, 0, 0, 1], + [0, 0, 1, 1], + [0, 2, 1, -1], + ) { + my %cellvals; + foreach my $i (0 .. 2) { + my $x = $pattern->[0] + $i * $pattern->[2]; + my $y = $pattern->[1] + $i * $pattern->[3]; + $cellvals{$board[$y][$x]}++; + } + if (scalar keys %cellvals == 1) { + my $winner = (keys %cellvals)[0]; + if ($winner == 1) { + return "A"; + } elsif ($winner == 2) { + return "B"; + } + } + } + if (scalar @{$a} == 9) { + return "Draw"; + } else { + return "Pending"; + } +} diff --git a/challenge-335/roger-bell-west/postscript/ch-1.ps b/challenge-335/roger-bell-west/postscript/ch-1.ps new file mode 100644 index 0000000000..b70b315685 --- /dev/null +++ b/challenge-335/roger-bell-west/postscript/ch-1.ps @@ -0,0 +1,261 @@ +%!PS + +% begin included library code +% see https://codeberg.org/Firedrake/postscript-libraries/ +/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 + +/s2a { + [ exch { } 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 + +/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 + +/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 + +/quicksort.cmp { + 2 copy + lt { + pop pop -1 + } { + gt { + 1 + } { + 0 + } ifelse + } ifelse +} 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 { + { quicksort.cmp } quicksort.with_comparator +} 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 + +/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.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 + + +% end included library code + +/counterify { + 2 dict begin + /c 0 dict def + { + /n exch def + c n known { + c n 2 copy get 1 add put + } { + c n 1 put + } ifelse + } forall + c + end +} bind def + +/commoncharacters { + 0 dict begin + /mc 0 dict def + /first true def + { + s2a counterify /mk exch def + first { + /mc mk def + /first false def + } { + mc keys { + /k exch def + mk k known { + mc k 2 copy get mk k get min put + } { + mc k undef + } ifelse + } forall + } ifelse + } forall + [ + mc keys quicksort { + /c exch def + c 1 array astore a2s /s exch def + mc c get { + s + } repeat + } forall + ] + end +} bind def + +(commoncharacters) test.start +[(bella) (label) (roller)] commoncharacters [(e) (l) (l)] deepeq test +[(cool) (lock) (cook)] commoncharacters [(c) (o)] deepeq test +[(hello) (world) (pole)] commoncharacters [(l) (o)] deepeq test +[(abc) (def) (ghi)] commoncharacters [] deepeq test +[(aab) (aac) (aaa)] commoncharacters [(a) (a)] deepeq test +test.end diff --git a/challenge-335/roger-bell-west/postscript/ch-2.ps b/challenge-335/roger-bell-west/postscript/ch-2.ps new file mode 100644 index 0000000000..c26b9c664f --- /dev/null +++ b/challenge-335/roger-bell-west/postscript/ch-2.ps @@ -0,0 +1,167 @@ +%!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 + +/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 + +/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 + + +% end included library code + +/findwinner { + 0 dict begin + /outcome (Null) def + /board [ 3 { [ 3 { 0 } repeat ] } repeat ] def + /player 1 def + /a exch def + a { + /play exch def + /r board play 0 get get def + r play 1 get player put + board play 0 get r put + /player 3 player sub def + } forall + [ + [0 0 1 0] + [0 1 1 0] + [0 2 1 0] + [0 0 0 1] + [1 0 0 1] + [2 0 0 1] + [0 0 1 1] + [0 2 1 -1] + ] { + /pattern exch def + /cellvals 0 dict def + 0 1 2 { + /i exch def + /x pattern 0 get i pattern 2 get mul add def + /y pattern 1 get i pattern 3 get mul add def + cellvals board y get x get true put + } for + cellvals length 1 eq { + /winner cellvals keys 0 get def + winner 1 eq { + /outcome (A) def + exit + } if + winner 2 eq { + /outcome (B) def + exit + } if + } if + } forall + outcome (Null) deepeq { + /outcome + a length 9 eq { + (Draw) + } { + (Pending) + } ifelse + def + } if + outcome + end +} bind def + +(findwinner) test.start +[[0 0] [2 0] [1 1] [2 1] [2 2]] findwinner (A) eq test +[[0 0] [1 1] [0 1] [0 2] [1 0] [2 0]] findwinner (B) eq test +[[0 0] [1 1] [2 0] [1 0] [1 2] [2 1] [0 1] [0 2] [2 2]] findwinner (Draw) eq test +[[0 0] [1 1]] findwinner (Pending) eq test +[[1 1] [0 0] [2 2] [0 1] [1 0] [0 2]] findwinner (B) eq test +test.end diff --git a/challenge-335/roger-bell-west/python/ch-1.py b/challenge-335/roger-bell-west/python/ch-1.py new file mode 100755 index 0000000000..1d127bb292 --- /dev/null +++ b/challenge-335/roger-bell-west/python/ch-1.py @@ -0,0 +1,52 @@ +#! /usr/bin/python3 + +from collections import defaultdict + +def commoncharacters(a): + mc = dict() + first = True + for s in a: + mk = defaultdict(lambda: 0) + for c in s: + mk[c] += 1 + if first: + mc = mk + first = False + else: + ktr = set() + for k in mc.keys(): + if k in mk: + mc[k] = min(mc[k], mk[k]) + else: + ktr.add(k) + if len(ktr) > 0: + for k in ktr: + del mc[k] + out = [] + kl = list(mc.keys()) + kl.sort() + for c in kl: + for _ in range(mc[c]): + out.append(c) + return out + +import unittest + +class TestCommoncharacters(unittest.TestCase): + + def test_ex1(self): + self.assertEqual(commoncharacters(["bella", "label", "roller"]), ["e", "l", "l"], 'example 1') + + def test_ex2(self): + self.assertEqual(commoncharacters(["cool", "lock", "cook"]), ["c", "o"], 'example 2') + + def test_ex3(self): + self.assertEqual(commoncharacters(["hello", "world", "pole"]), ["l", "o"], 'example 3') + + def test_ex4(self): + self.assertEqual(commoncharacters(["abc", "def", "ghi"]), [], 'example 4') + + def test_ex5(self): + self.assertEqual(commoncharacters(["aab", "aac", "aaa"]), ["a", "a"], 'example 5') + +unittest.main() diff --git a/challenge-335/roger-bell-west/python/ch-2.py b/challenge-335/roger-bell-west/python/ch-2.py new file mode 100755 index 0000000000..053486a683 --- /dev/null +++ b/challenge-335/roger-bell-west/python/ch-2.py @@ -0,0 +1,53 @@ +#! /usr/bin/python3 + +def findwinner(a): + board = [ [ 0, 0, 0], [ 0, 0, 0], [ 0, 0, 0] ] + player = 1 + for play in a: + board[play[0]][play[1]] = player + player = 3 - player + for pattern in [ + [0, 0, 1, 0], + [0, 1, 1, 0], + [0, 2, 1, 0], + [0, 0, 0, 1], + [1, 0, 0, 1], + [2, 0, 0, 1], + [0, 0, 1, 1], + [0, 2, 1, -1] ]: + cellvals = set() + for i in range(3): + x = pattern[0] + i * pattern[2] + y = pattern[1] + i * pattern[3] + cellvals.add(board[y][x]) + if len(cellvals) == 1: + winner = list(cellvals)[0] + if winner == 1: + return "A" + elif winner == 2: + return "B" + if len(a) == 9: + return "Draw" + else: + return "Pending" + +import unittest + +class TestFindwinner(unittest.TestCase): + + def test_ex1(self): + self.assertEqual(findwinner([[0, 0], [2, 0], [1, 1], [2, 1], [2, 2]]), "A", 'example 1') + + def test_ex2(self): + self.assertEqual(findwinner([[0, 0], [1, 1], [0, 1], [0, 2], [1, 0], [2, 0]]), "B", 'example 2') + + def test_ex3(self): + self.assertEqual(findwinner([[0, 0], [1, 1], [2, 0], [1, 0], [1, 2], [2, 1], [0, 1], [0, 2], [2, 2]]), "Draw", 'example 3') + + def test_ex4(self): + self.assertEqual(findwinner([[0, 0], [1, 1]]), "Pending", 'example 4') + + def test_ex5(self): + self.assertEqual(findwinner([[1, 1], [0, 0], [2, 2], [0, 1], [1, 0], [0, 2]]), "B", 'example 5') + +unittest.main() diff --git a/challenge-335/roger-bell-west/raku/ch-1.p6 b/challenge-335/roger-bell-west/raku/ch-1.p6 new file mode 100755 index 0000000000..2e7565d579 --- /dev/null +++ b/challenge-335/roger-bell-west/raku/ch-1.p6 @@ -0,0 +1,39 @@ +#! /usr/bin/raku + +use Test; + +plan 5; + +is-deeply(commoncharacters(['bella', 'label', 'roller']), ['e', 'l', 'l'], 'example 1'); +is-deeply(commoncharacters(['cool', 'lock', 'cook']), ['c', 'o'], 'example 2'); +is-deeply(commoncharacters(['hello', 'world', 'pole']), ['l', 'o'], 'example 3'); +is-deeply(commoncharacters(['abc', 'def', 'ghi']), [], 'example 4'); +is-deeply(commoncharacters(['aab', 'aac', 'aaa']), ['a', 'a'], 'example 5'); + +sub commoncharacters(@a) { + my %mc; + my $first = True; + for @a -> $s { + my %mk; + $s.comb("").map({%mk{$_}++}); + if ($first) { + %mc = %mk; + $first = False; + } else { + for %mc.keys -> $k { + if (%mk{$k}:exists) { + %mc{$k} = [%mc{$k}, %mk{$k}].min; + } else { + %mc{$k}:delete; + } + } + } + } + my @out; + for %mc.keys.sort -> $c { + for 1 .. %mc{$c} { + @out.push($c); + } + } + @out; +} diff --git a/challenge-335/roger-bell-west/raku/ch-2.p6 b/challenge-335/roger-bell-west/raku/ch-2.p6 new file mode 100755 index 0000000000..f03371073d --- /dev/null +++ b/challenge-335/roger-bell-west/raku/ch-2.p6 @@ -0,0 +1,54 @@ +#! /usr/bin/raku + +use Test; + +plan 5; + +is(findwinner([[0, 0], [2, 0], [1, 1], [2, 1], [2, 2]]), 'A', 'example 1'); +is(findwinner([[0, 0], [1, 1], [0, 1], [0, 2], [1, 0], [2, 0]]), 'B', 'example 2'); +is(findwinner([[0, 0], [1, 1], [2, 0], [1, 0], [1, 2], [2, 1], [0, 1], [0, 2], [2, 2]]), 'Draw', 'example 3'); +is(findwinner([[0, 0], [1, 1]]), 'Pending', 'example 4'); +is(findwinner([[1, 1], [0, 0], [2, 2], [0, 1], [1, 0], [0, 2]]), 'B', 'example 5'); + +sub findwinner(@a) { + my @board = [ + [ 0, 0, 0 ], + [ 0, 0, 0 ], + [ 0, 0, 0 ], + ]; + my $player = 1; + for @a -> @play { + @board[@play[0]][@play[1]] = $player; + $player = 3 - $player; + } + for [ + [0, 0, 1, 0], + [0, 1, 1, 0], + [0, 2, 1, 0], + [0, 0, 0, 1], + [1, 0, 0, 1], + [2, 0, 0, 1], + [0, 0, 1, 1], + [0, 2, 1, -1], + ] -> @pattern { + my %cellvals = SetHash.new; + for 0 .. 2 -> $i { + my $x = @pattern[0] + $i * @pattern[2]; + my $y = @pattern[1] + $i * @pattern[3]; + %cellvals{@board[$y][$x]}++; + } + if (%cellvals.elems == 1) { + my $winner = %cellvals.keys[0]; + if ($winner == 1) { + return "A"; + } elsif ($winner == 2) { + return "B"; + } + } + } + if (@a.elems == 9) { + return "Draw"; + } else { + return "Pending"; + } +} diff --git a/challenge-335/roger-bell-west/ruby/ch-1.rb b/challenge-335/roger-bell-west/ruby/ch-1.rb new file mode 100755 index 0000000000..a6dbac99a3 --- /dev/null +++ b/challenge-335/roger-bell-west/ruby/ch-1.rb @@ -0,0 +1,63 @@ +#! /usr/bin/ruby + +def counterify(a) + cc = Hash.new + cc.default = 0 + a.each do |x| + cc[x] += 1 + end + return cc +end + +def commoncharacters(a) + mc = Hash.new + first = true + a.each do |s| + mk = counterify(s.chars) + if first + mc = mk + first = false + else + mc.keys.each do |k| + if mk.has_key?(k) + mc[k] = [mc[k], mk[k]].min + else + mc.delete(k) + end + end + end + end + out = [] + mc.keys.sort.each do |c| + 1.upto(mc[c]) do + out.push(c) + end + end + out +end + +require 'test/unit' + +class TestCommoncharacters < Test::Unit::TestCase + + def test_ex1 + assert_equal(['e', 'l', 'l'], commoncharacters(['bella', 'label', 'roller'])) + end + + def test_ex2 + assert_equal(['c', 'o'], commoncharacters(['cool', 'lock', 'cook'])) + end + + def test_ex3 + assert_equal(['l', 'o'], commoncharacters(['hello', 'world', 'pole'])) + end + + def test_ex4 + assert_equal([], commoncharacters(['abc', 'def', 'ghi'])) + end + + def test_ex5 + assert_equal(['a', 'a'], commoncharacters(['aab', 'aac', 'aaa'])) + end + +end diff --git a/challenge-335/roger-bell-west/ruby/ch-2.rb b/challenge-335/roger-bell-west/ruby/ch-2.rb new file mode 100755 index 0000000000..ad37269ba8 --- /dev/null +++ b/challenge-335/roger-bell-west/ruby/ch-2.rb @@ -0,0 +1,72 @@ +#! /usr/bin/ruby + +require 'set' + +def findwinner(a) + board = [ + [ 0, 0, 0 ], + [ 0, 0, 0 ], + [ 0, 0, 0 ] + ] + player = 1 + a.each do |play| + board[play[0]][play[1]] = player + player = 3 - player + end + [ + [0, 0, 1, 0], + [0, 1, 1, 0], + [0, 2, 1, 0], + [0, 0, 0, 1], + [1, 0, 0, 1], + [2, 0, 0, 1], + [0, 0, 1, 1], + [0, 2, 1, -1], + ].each do |pattern| + cellvals = Set.new + 0.upto(2) do |i| + x = pattern[0] + i * pattern[2] + y = pattern[1] + i * pattern[3] + cellvals.add(board[y][x]) + end + if cellvals.size == 1 + winner = cellvals.to_a[0] + if winner == 1 + return "A" + elsif winner == 2 + return "B" + end + end + end + if a.size == 9 + return "Draw" + else + return "Pending" + end +end + +require 'test/unit' + +class TestFindwinner < Test::Unit::TestCase + + def test_ex1 + assert_equal('A', findwinner([[0, 0], [2, 0], [1, 1], [2, 1], [2, 2]])) + end + + def test_ex2 + assert_equal('B', findwinner([[0, 0], [1, 1], [0, 1], [0, 2], [1, 0], [2, 0]])) + end + + def test_ex3 + assert_equal('Draw', findwinner([[0, 0], [1, 1], [2, 0], [1, 0], [1, 2], [2, 1], [0, 1], [0, 2], [2, 2]])) + end + + def test_ex4 + assert_equal('Pending', findwinner([[0, 0], [1, 1]])) + end + + def test_ex5 + assert_equal('B', findwinner([[1, 1], [0, 0], [2, 2], [0, 1], [1, 0], [0, 2]])) + end + +end diff --git a/challenge-335/roger-bell-west/rust/ch-1.rs b/challenge-335/roger-bell-west/rust/ch-1.rs new file mode 100755 index 0000000000..683bdd17f0 --- /dev/null +++ b/challenge-335/roger-bell-west/rust/ch-1.rs @@ -0,0 +1,58 @@ +use counter::Counter; + +#[test] +fn test_ex1() { + assert_eq!( + commoncharacters(vec!["bella", "label", "roller"]), + vec!["e", "l", "l"] + ); +} + +#[test] +fn test_ex2() { + assert_eq!(commoncharacters(vec!["cool", "lock", "cook"]), vec!["c", "o"]); +} + +#[test] +fn test_ex3() { + assert_eq!( + commoncharacters(vec!["hello", "world", "pole"]), + vec!["l", "o"] + ); +} + +#[test] +fn test_ex4() { + assert_eq!( + commoncharacters(vec!["abc", "def", "ghi"]), + Vec::::new() + ); +} + +#[test] +fn test_ex5() { + assert_eq!(commoncharacters(vec!["aab", "aac", "aaa"]), vec!["a", "a"]); +} + +fn commoncharacters(a: Vec<&str>) -> Vec { + let mut mc: Counter = Counter::new(); + let mut first = true; + for s in a { + let mk = s.chars().collect::>(); + if first { + mc = mk; + first = false; + } else { + mc = mc & mk; + } + } + let mut out = Vec::new(); + let mut kl = mc.keys().collect::>(); + kl.sort(); + for c in kl { + for _ in 0..*mc.get(&c).unwrap() { + out.push(c.to_string()); + } + } + out +} diff --git a/challenge-335/roger-bell-west/rust/ch-2.rs b/challenge-335/roger-bell-west/rust/ch-2.rs new file mode 100755 index 0000000000..eeba8ad25b --- /dev/null +++ b/challenge-335/roger-bell-west/rust/ch-2.rs @@ -0,0 +1,111 @@ +#! /bin/sh +//usr/bin/env rustc --test $0 -o ${0}x && ./${0}x --nocapture; rm -f ${0}x ; exit + +use std::collections::HashSet; + +#[test] +fn test_ex1() { + assert_eq!( + findwinner(vec![ + vec![0, 0], + vec![2, 0], + vec![1, 1], + vec![2, 1], + vec![2, 2] + ]), + "A" + ); +} + +#[test] +fn test_ex2() { + assert_eq!( + findwinner(vec![ + vec![0, 0], + vec![1, 1], + vec![0, 1], + vec![0, 2], + vec![1, 0], + vec![2, 0] + ]), + "B" + ); +} + +#[test] +fn test_ex3() { + assert_eq!( + findwinner(vec![ + vec![0, 0], + vec![1, 1], + vec![2, 0], + vec![1, 0], + vec![1, 2], + vec![2, 1], + vec![0, 1], + vec![0, 2], + vec![2, 2] + ]), + "Draw" + ); +} + +#[test] +fn test_ex4() { + assert_eq!(findwinner(vec![vec![0, 0], vec![1, 1]]), "Pending"); +} + +#[test] +fn test_ex5() { + assert_eq!( + findwinner(vec![ + vec![1, 1], + vec![0, 0], + vec![2, 2], + vec![0, 1], + vec![1, 0], + vec![0, 2] + ]), + "B" + ); +} + +fn findwinner(a: Vec>) -> String { + let mut board = vec![vec![0; 3]; 3]; + let mut player: u8 = 1; + for play in &a { + board[play[0]][play[1]] = player; + player = 3 - player; + } + for pattern in [ + [0isize, 0isize, 1isize, 0isize], + [0, 1, 1, 0], + [0, 2, 1, 0], + [0, 0, 0, 1], + [1, 0, 0, 1], + [2, 0, 0, 1], + [0, 0, 1, 1], + [0, 2, 1, -1], + ] { + let mut cellvals = HashSet::new(); + for i in 0..3 { + let x = (pattern[0] + i * pattern[2]) as usize; + let y = (pattern[1] + i * pattern[3]) as usize; + cellvals.insert(board[y][x]); + } + if cellvals.len() == 1 { + // all the same cell value + let winner = *cellvals.iter().nth(0).unwrap(); + if winner == 1 { + return "A".to_string(); + } else if winner == 2 { + return "B".to_string(); + } + } + } + if a.len() == 9 { + return "Draw".to_string(); + } else { + return "Pending".to_string(); + } +} diff --git a/challenge-335/roger-bell-west/scala/ch-1.scala b/challenge-335/roger-bell-west/scala/ch-1.scala new file mode 100644 index 0000000000..b41158b519 --- /dev/null +++ b/challenge-335/roger-bell-west/scala/ch-1.scala @@ -0,0 +1,74 @@ +import scala.collection.mutable +import scala.collection.mutable.ListBuffer + +object Commoncharacters { + def counterify(a: List[Char]): Map[Char, Int] = { + var cc = mutable.Map.empty[Char, Int].withDefaultValue(0) + for (x <- a) { + cc += (x -> (cc(x) + 1)) + } + cc.toMap + } + + def commoncharacters(a: List[String]): List[String] = { + var mc = mutable.Map.empty[Char, Int].withDefaultValue(0) + var first = true + for (s <- a) { + val mk = counterify(s.toCharArray.toList) + if (first) { + mc = collection.mutable.Map() ++ mk + first = false + } else { + for (k <- mc.keys) { + if (mk.contains(k)) { + mc += ((k, List(mc(k), mk(k)).min)) + } else { + mc.remove(k) + } + } + } + } + var out = new ListBuffer[String] + for (c <- mc.keys.toList.sortWith(_ < _)) { + val s = c.toString + for (n <- 1 to mc(c)) { + out += s + } + } + out.toList + } + + def main(args: Array[String]) { + if (commoncharacters(List("bella", "label", "roller")) == List("e", "l", "l")) { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (commoncharacters(List("cool", "lock", "cook")) == List("c", "o")) { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (commoncharacters(List("hello", "world", "pole")) == List("l", "o")) { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (commoncharacters(List("abc", "def", "ghi")) == List()) { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (commoncharacters(List("aab", "aac", "aaa")) == List("a", "a")) { + print("Pass") + } else { + print("Fail") + } + println("") + + } +} diff --git a/challenge-335/roger-bell-west/scala/ch-2.scala b/challenge-335/roger-bell-west/scala/ch-2.scala new file mode 100644 index 0000000000..a6e0d8a6a0 --- /dev/null +++ b/challenge-335/roger-bell-west/scala/ch-2.scala @@ -0,0 +1,86 @@ +import scala.collection.mutable +import scala.collection.mutable.ListBuffer + +object Findwinner { + def findwinner(a: List[List[Int]]): String = { + var outcome = "Null" + var board = List(List(0, 0, 0).to[ListBuffer], + List(0, 0, 0).to[ListBuffer], + List(0, 0, 0).to[ListBuffer] + ).to[ListBuffer] + var player = 1 + for (play <- a) { + board(play(0))(play(1)) = player + player = 3 - player + } + for (pattern <- List( + List(0, 0, 1, 0), + List(0, 1, 1, 0), + List(0, 2, 1, 0), + List(0, 0, 0, 1), + List(1, 0, 0, 1), + List(2, 0, 0, 1), + List(0, 0, 1, 1), + List(0, 2, 1, -1) + )) { + if (outcome == "Null") { + var cellvals = mutable.Set.empty[Int] + for (i <- 0 to 2) { + val x = pattern(0) + i * pattern(2) + val y = pattern(1) + i * pattern(3) + cellvals += board(y)(x) + } + if (cellvals.size == 1) { + var winner = cellvals.toList(0) + if (winner == 1) { + outcome = "A" + } else if (winner == 2) { + outcome = "B" + } + } + } + } + if (outcome == "Null") { + if (a.size == 9) { + outcome = "Draw" + } else { + outcome = "Pending" + } + } + outcome + } + + def main(args: Array[String]) { + if (findwinner(List(List(0, 0), List(2, 0), List(1, 1), List(2, 1), List(2, 2))) == "A") { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (findwinner(List(List(0, 0), List(1, 1), List(0, 1), List(0, 2), List(1, 0), List(2, 0))) == "B") { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (findwinner(List(List(0, 0), List(1, 1), List(2, 0), List(1, 0), List(1, 2), List(2, 1), List(0, 1), List(0, 2), List(2, 2))) == "Draw") { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (findwinner(List(List(0, 0), List(1, 1))) == "Pending") { + print("Pass") + } else { + print("Fail") + } + print(" ") + if (findwinner(List(List(1, 1), List(0, 0), List(2, 2), List(0, 1), List(1, 0), List(0, 2))) == "B") { + print("Pass") + } else { + print("Fail") + } + println("") + + } +} diff --git a/challenge-335/roger-bell-west/tests.json b/challenge-335/roger-bell-west/tests.json new file mode 100644 index 0000000000..a789534428 --- /dev/null +++ b/challenge-335/roger-bell-west/tests.json @@ -0,0 +1,76 @@ +{ + "ch-1" : [ + { + "function" : "commoncharacters", + "arguments" : [ + "bella", "label", "roller" + ], + "result" : [ + "e", "l", "l" + ] + }, + { + "arguments" : [ + "cool", "lock", "cook" + ], + "result" : [ + "c", "o" + ] + }, + { + "arguments" : [ + "hello", "world", "pole" + ], + "result" : [ + "l", "o" + ] + }, + { + "arguments" : [ + "abc", "def", "ghi" + ], + "result" : [] + }, + { + "arguments" : [ + "aab", "aac", "aaa" + ], + "result" : [ + "a", "a" + ] + } + ], + "ch-2" : [ + { + "function" : "findwinner", + "arguments" : [ + [0,0],[2,0],[1,1],[2,1],[2,2] + ], + "result" : "A" + }, + { + "arguments" : [ + [0,0],[1,1],[0,1],[0,2],[1,0],[2,0] + ], + "result" : "B" + }, + { + "arguments" : [ + [0,0],[1,1],[2,0],[1,0],[1,2],[2,1],[0,1],[0,2],[2,2] + ], + "result" : "Draw" + }, + { + "arguments" : [ + [0,0],[1,1] + ], + "result" : "Pending" + }, + { + "arguments" : [ + [1,1],[0,0],[2,2],[0,1],[1,0],[0,2] + ], + "result" : "B" + } + ] +} diff --git a/challenge-335/roger-bell-west/typst/ch-1.typ b/challenge-335/roger-bell-west/typst/ch-1.typ new file mode 100644 index 0000000000..de5edcfd6d --- /dev/null +++ b/challenge-335/roger-bell-west/typst/ch-1.typ @@ -0,0 +1,58 @@ +#let testresult(pass) = { + if pass { + text(fill: green, "Pass") + } else { + text(fill: red, "Fail") + } +} + +#let counterify(a) = { + let c = (:) + for n in a { + c.insert(n, c.at(n, default: 0) + 1) + } + c +} + +#let commoncharacters(a) = { + let mc = (:) + let first = true + for s in a { + let mk = counterify(s.codepoints()) + if first { + mc = mk + first = false + } else { + for k in mc.keys() { + if k in mk { + mc.insert(k, calc.min(mc.at(k), mk.at(k))) + } else { + let _ = mc.remove(k) + } + } + } + } + let out = () + for c in mc.keys().sorted() { + for _ in range(mc.at(c)) { + out.push(c) + } + } + out +} + +Test 1: + #testresult(commoncharacters(("bella", "label", "roller")) == ("e", "l", "l")) + +Test 2: + #testresult(commoncharacters(("cool", "lock", "cook")) == ("c", "o")) + +Test 3: + #testresult(commoncharacters(("hello", "world", "pole")) == ("l", "o")) + +Test 4: + #testresult(commoncharacters(("abc", "def", "ghi")) == ()) + +Test 5: + #testresult(commoncharacters(("aab", "aac", "aaa")) == ("a", "a")) + diff --git a/challenge-335/roger-bell-west/typst/ch-2.typ b/challenge-335/roger-bell-west/typst/ch-2.typ new file mode 100644 index 0000000000..9f1d009396 --- /dev/null +++ b/challenge-335/roger-bell-west/typst/ch-2.typ @@ -0,0 +1,72 @@ +#let testresult(pass) = { + if pass { + text(fill: green, "Pass") + } else { + text(fill: red, "Fail") + } +} + +#let findwinner(a) = { + let outcome = "Null" + let board = ( + ( 0, 0, 0 ), + ( 0, 0, 0 ), + ( 0, 0, 0 ) + ) + let player = 1 + for play in a { + board.at(play.at(0)).at(play.at(1)) = player + player = 3 - player + } + for pattern in ( + (0, 0, 1, 0), + (0, 1, 1, 0), + (0, 2, 1, 0), + (0, 0, 0, 1), + (1, 0, 0, 1), + (2, 0, 0, 1), + (0, 0, 1, 1), + (0, 2, 1, -1), + ) { + let cellvals = (:) + for i in range(3) { + let x = pattern.at(0) + i * pattern.at(2) + let y = pattern.at(1) + i * pattern.at(3) + cellvals.insert(str(board.at(y).at(x)), true) + } + if cellvals.len() == 1 { + let winner = cellvals.keys().at(0) + if winner == "1" { + outcome = "A" + break + } else if winner == "2" { + outcome = "B" + break + } + } + } + if outcome == "Null" { + if a.len() == 9 { + outcome = "Draw" + } else { + outcome = "Pending" + } + } + outcome +} + +Test 1: + #testresult(findwinner(((0, 0), (2, 0), (1, 1), (2, 1), (2, 2))) == "A") + +Test 2: + #testresult(findwinner(((0, 0), (1, 1), (0, 1), (0, 2), (1, 0), (2, 0))) == "B") + +Test 3: + #testresult(findwinner(((0, 0), (1, 1), (2, 0), (1, 0), (1, 2), (2, 1), (0, 1), (0, 2), (2, 2))) == "Draw") + +Test 4: + #testresult(findwinner(((0, 0), (1, 1))) == "Pending") + +Test 5: + #testresult(findwinner(((1, 1), (0, 0), (2, 2), (0, 1), (1, 0), (0, 2))) == "B") + -- cgit