FA-83191 / Go territory scoring / Open access
Territory is rendered with live-stone letters · case 01
Territory points look like stones in the map.
ROOT CAUSE
The owner colour is used without lower-casing.
VERIFIED REPAIR
Render territory as lower-case b/w.
Unsuccessful approach: Rendering dame as "." instead of "?" makes neutral points look unscored.
Case contract
Input [board, dead_points]. Remove dead stones, then render each point: live stones as B/W, territory (region bordered by one colour) as lower-case b/w, other empty points as "?". Return rows.
Why this case matters
Go servers and scoring tools compute this value automatically; a wrong answer changes a game result.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
board, dead = x
n = len(board)
m = len(board[0])
dd = {tuple(p) for p in dead}
g = [[('.' if (r, c) in dd else board[r][c]) for c in range(m)] for r in range(n)]
out = [[g[r][c] for c in range(m)] for r in range(n)]
seen = set()
for r in range(n):
for c in range(m):
if g[r][c] != '.' or (r, c) in seen:
continue
seen.add((r, c))
region = [(r, c)]
k = 0
cols = set()
while k < len(region):
i, j = region[k]
k += 1
for p, q in ((i - 1, j), (i, j - 1), (i + 1, j), (i, j + 1)):
if 0 <= p < n and 0 <= q < m:
if g[p][q] == '.':
if (p, q) not in seen:
seen.add((p, q))
region.append((p, q))
else:
cols.add(g[p][q])
mark = cols.pop() if len(cols) == 1 else '?'
for i, j in region:
out[i][j] = mark
return [''.join(row) for row in out]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['...BW..', '...BW..', '...BW..', '...BWB.', '...BW.B'], [[4, 6], [4, 4]]], ['bbbBW??', 'bbbBW??', 'bbbBW??', 'bbbBWB?', 'bbbB???']], [[['.BW.', '.BW.', 'WBW.', '.BW.', '.BW.', 'WBW.'], [[0, 1], [2, 0]]], ['??Ww', '?BWw', '?BWw', '?BWw', '?BWw', 'WBWw']], [[['.BWB.', '.BW..', '.BW..', '.BWB.'], [[2, 2], [0, 2]]], ['bB?B?', 'bBW??', 'bB???', 'bBWB?']], [[['WBW...', '.BW...', '.BW..B', '.BW...', '.BW...'], [[0, 2]]], ['WB????', '?BW???', '?BW??B', '?BW???', '?BW???']], [[['.BW.B..', 'WBW....', '.BW....', '.BW....', '.BW....'], [[2, 2]]], ['?BW?B??', 'WBW????', '?B?????', '?BW????', '?BW????']], [[['....BW', '....BW', '....BW', '....BW', '....BW', '....BW'], [[2, 5], [2, 4]]], ['????BW', '????BW', '??????', '????BW', '????BW', '????BW']], [[['..BW', '..BW', '..BW', '..BW', '..BW', '..BW', '..BW'], [[3, 2]]], ['??BW', '??BW', '??BW', '???W', '??BW', '??BW', '??BW']], [[['W.BW.', '..BW.', '.WBW.', '.WBW.', '..BW.', '..BW.', '..BW.'], []], ['W?BWw', '??BWw', '?WBWw', '?WBWw', '??BWw', '??BWw', '??BWw']]], [[[['...WBW.', '....BW.', '....BW.', '.W..BW.'], []], ['???WBWw', '????BWw', '????BWw', '?W??BWw']], [[['.BW.B..', 'WBW....', '.BW....', '.BW....', '.BW....'], [[2, 2]]], ['?BW?B??', 'WBW????', '?B?????', '?BW????', '?BW????']], [[['.BWB', '.BW.', 'WBW.', '.BW.', '.BW.', 'WBW.'], [[4, 1]]], ['?BWB', '?BW?', 'WBW?', '?BW?', '??W?', 'WBW?']], [[['.BW.', '.BW.', 'WBW.', '.BW.', '.BW.'], [[0, 1], [3, 1]]], ['??Ww', '?BWw', 'WBWw', '??Ww', '?BWw']], [[['.W..BW', '....BW', 'W...BW', '....BW'], [[1, 4]]], ['?W??BW', '?????W', 'W???BW', '????BW']], [[['..BW', '..BW', 'W.BW', '..BW', '..BW'], [[4, 2], [3, 2]]], ['??BW', '??BW', 'W?BW', '???W', '???W']], [[['.BW...', '.BW...', '.BW...', 'WBW..B', '.BW..B', '.BW..B'], []], ['?BW???', '?BW???', '?BW???', 'WBW??B', '?BW??B', '?BW??B']], [[['.BW..', 'WBW..', 'WBWB.', '.BW..', '.BW..'], []], ['?BW??', 'WBW??', 'WBWB?', '?BW??', '?BW??']]], [[[['.BWB', '.BW.', 'WBW.', '.BW.', '.BW.', 'WBW.'], [[4, 1]]], ['?BWB', '?BW?', 'WBW?', '?BW?', '??W?', 'WBW?']], [[['.BW.', '.BW.', 'WBW.', '.BW.', '.BW.'], [[0, 1], [3, 1]]], ['??Ww', '?BWw', 'WBWw', '??Ww', '?BWw']], [[['...BW', '..WBW', '...BW', '...BW', '...BW'], []], ['???BW', '??WBW', '???BW', '???BW', '???BW']], [[['...BW', '...BW', '...BW', 'W..BW'], []], ['???BW', '???BW', '???BW', 'W??BW']], [[['..BW.', '..BW.', '..BWB', '..BW.', '..BW.', '..BW.', '..BW.'], [[2, 2], [3, 3]]], ['??BW?', '??BW?', '???WB', '??B??', '??BW?', '??BW?', '??BW?']], [[['.BW..', '.BW.B', '.BWB.', '.BW..', '.BW.B', '.BW..', 'WBW..'], [[4, 1]]], ['?BW??', '?BW?B', '?BWB?', '?BW??', '??W?B', '?BW??', 'WBW??']], [[['..BW', 'W.BW', '..BW', '..BW', '..BW', 'W.BW'], [[0, 2], [5, 3]]], ['???W', 'W?BW', '??BW', '??BW', '??BW', 'W?B?']], [[['...BW.', '...BW.', '...BW.', '...BW.', '...BW.', '...BW.'], [[2, 4]]], ['bbbBW?', 'bbbBW?', 'bbbB??', 'bbbBW?', 'bbbBW?', 'bbbBW?']]], [[[['.BW..', 'WBW..', 'WBWB.', '.BW..', '.BW..'], []], ['?BW??', 'WBW??', 'WBWB?', '?BW??', '?BW??']], [[['...BW', '...BW', 'W..BW', 'W.WBW', '...BW', '...BW'], []], ['???BW', '???BW', 'W??BW', 'W?WBW', '???BW', '???BW']], [[['....', '....', '....', '....'], []], ['????', '????', '????', '????']], [[['...', '...', '...'], []], ['???', '???', '???']], [[['.B.', 'B.B', '.B.'], [[1, 2], [2, 1]]], ['bBb', 'Bbb', 'bbb']], [[['B..W', 'B..W', 'B..W', 'B..W'], [[2, 3]]], ['B??W', 'B??W', 'B???', 'B??W']], [[['.BW.', '.BW.', '.BW.', '.BW.'], [[0, 2]]], ['bB??', 'bBW?', 'bBW?', 'bBW?']], [[['..B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], [[0, 2]]], ['bbbbb', 'bbBbb', 'BBBBB', 'WWWWW', 'wwWww']]], [[[['.BW..', '.BW.B', '.BWB.', '.BW..', '.BW.B', '.BW..', 'WBW..'], [[4, 1]]], ['?BW??', '?BW?B', '?BWB?', '?BW??', '??W?B', '?BW??', 'WBW??']], [[['B.B.W', '.B.W.', 'B.BW.', 'BBW.W', '..W..'], []], ['BbB?W', 'bB?Ww', 'BbBWw', 'BBWwW', '??Www']], [[['W....', '.....', '.....', '.....', '....B'], [[4, 4]]], ['Wwwww', 'wwwww', 'wwwww', 'wwwww', 'wwwww']], [[['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], [[3, 1], [3, 0]]], ['wW?B?', 'WwWB?', '?WB??', '?????', 'B????']], [[['BBBB', 'B..B', 'B..B', 'BBBB'], [[0, 2]]], ['BBbB', 'BbbB', 'BbbB', 'BBBB']], [[['WWW', 'W.W', 'WWW'], []], ['WWW', 'WwW', 'WWW']], [[['B.W', '...', 'W.B'], [[2, 2], [0, 0]]], ['wwW', 'www', 'Www']], [[['.B...', 'B....', '.....', '....W', '...W.'], [[1, 0]]], ['?B???', '?????', '?????', '????W', '???Ww']]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("ownership map case %d" % i, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| ownership map case 0 | ['BBBBW??', 'BBBBW??', 'BBBBW??', 'BBBBWB?', 'BBBB???'] | ['bbbBW??', 'bbbBW??', 'bbbBW??', 'bbbBWB?', 'bbbB???'] | Failed |
| ownership map case 1 | ['??WW', '?BWW', '?BWW', '?BWW', '?BWW', 'WBWW'] | ['??Ww', '?BWw', '?BWw', '?BWw', '?BWw', 'WBWw'] | Failed |
| ownership map case 2 | ['BB?B?', 'BBW??', 'BB???', 'BBWB?'] | ['bB?B?', 'bBW??', 'bB???', 'bBWB?'] | Failed |
| ownership map case 3 | ['WB????', '?BW???', '?BW??B', '?BW???', '?BW???'] | ['WB????', '?BW???', '?BW??B', '?BW???', '?BW???'] | Passed |
| ownership map case 4 | ['?BW?B??', 'WBW????', '?B?????', '?BW????', '?BW????'] | ['?BW?B??', 'WBW????', '?B?????', '?BW????', '?BW????'] | Passed |
| ownership map case 5 | ['????BW', '????BW', '??????', '????BW', '????BW', '????BW'] | ['????BW', '????BW', '??????', '????BW', '????BW', '????BW'] | Passed |
| ownership map case 6 | ['??BW', '??BW', '??BW', '???W', '??BW', '??BW', '??BW'] | ['??BW', '??BW', '??BW', '???W', '??BW', '??BW', '??BW'] | Passed |
| ownership map case 7 | ['W?BWW', '??BWW', '?WBWW', '?WBWW', '??BWW', '??BWW', '??BWW'] | ['W?BWw', '??BWw', '?WBWw', '?WBWw', '??BWw', '??BWw', '??BWw'] | Failed |
SHA-256 / 82cd385c5c3ad8e93770f44a0fe2eb3c46c61baa468bf7be1f6b4ce3ef020b68
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
board, dead = x
n = len(board)
m = len(board[0])
dd = {tuple(p) for p in dead}
g = [[('.' if (r, c) in dd else board[r][c]) for c in range(m)] for r in range(n)]
out = [[g[r][c] for c in range(m)] for r in range(n)]
seen = set()
for r in range(n):
for c in range(m):
if g[r][c] != '.' or (r, c) in seen:
continue
seen.add((r, c))
region = [(r, c)]
k = 0
cols = set()
while k < len(region):
i, j = region[k]
k += 1
for p, q in ((i - 1, j), (i, j - 1), (i + 1, j), (i, j + 1)):
if 0 <= p < n and 0 <= q < m:
if g[p][q] == '.':
if (p, q) not in seen:
seen.add((p, q))
region.append((p, q))
else:
cols.add(g[p][q])
mark = cols.pop().lower() if len(cols) == 1 else '.'
for i, j in region:
out[i][j] = mark
return [''.join(row) for row in out]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['...BW..', '...BW..', '...BW..', '...BWB.', '...BW.B'], [[4, 6], [4, 4]]], ['bbbBW??', 'bbbBW??', 'bbbBW??', 'bbbBWB?', 'bbbB???']], [[['.BW.', '.BW.', 'WBW.', '.BW.', '.BW.', 'WBW.'], [[0, 1], [2, 0]]], ['??Ww', '?BWw', '?BWw', '?BWw', '?BWw', 'WBWw']], [[['.BWB.', '.BW..', '.BW..', '.BWB.'], [[2, 2], [0, 2]]], ['bB?B?', 'bBW??', 'bB???', 'bBWB?']], [[['WBW...', '.BW...', '.BW..B', '.BW...', '.BW...'], [[0, 2]]], ['WB????', '?BW???', '?BW??B', '?BW???', '?BW???']], [[['.BW.B..', 'WBW....', '.BW....', '.BW....', '.BW....'], [[2, 2]]], ['?BW?B??', 'WBW????', '?B?????', '?BW????', '?BW????']], [[['....BW', '....BW', '....BW', '....BW', '....BW', '....BW'], [[2, 5], [2, 4]]], ['????BW', '????BW', '??????', '????BW', '????BW', '????BW']], [[['..BW', '..BW', '..BW', '..BW', '..BW', '..BW', '..BW'], [[3, 2]]], ['??BW', '??BW', '??BW', '???W', '??BW', '??BW', '??BW']], [[['W.BW.', '..BW.', '.WBW.', '.WBW.', '..BW.', '..BW.', '..BW.'], []], ['W?BWw', '??BWw', '?WBWw', '?WBWw', '??BWw', '??BWw', '??BWw']]], [[[['...WBW.', '....BW.', '....BW.', '.W..BW.'], []], ['???WBWw', '????BWw', '????BWw', '?W??BWw']], [[['.BW.B..', 'WBW....', '.BW....', '.BW....', '.BW....'], [[2, 2]]], ['?BW?B??', 'WBW????', '?B?????', '?BW????', '?BW????']], [[['.BWB', '.BW.', 'WBW.', '.BW.', '.BW.', 'WBW.'], [[4, 1]]], ['?BWB', '?BW?', 'WBW?', '?BW?', '??W?', 'WBW?']], [[['.BW.', '.BW.', 'WBW.', '.BW.', '.BW.'], [[0, 1], [3, 1]]], ['??Ww', '?BWw', 'WBWw', '??Ww', '?BWw']], [[['.W..BW', '....BW', 'W...BW', '....BW'], [[1, 4]]], ['?W??BW', '?????W', 'W???BW', '????BW']], [[['..BW', '..BW', 'W.BW', '..BW', '..BW'], [[4, 2], [3, 2]]], ['??BW', '??BW', 'W?BW', '???W', '???W']], [[['.BW...', '.BW...', '.BW...', 'WBW..B', '.BW..B', '.BW..B'], []], ['?BW???', '?BW???', '?BW???', 'WBW??B', '?BW??B', '?BW??B']], [[['.BW..', 'WBW..', 'WBWB.', '.BW..', '.BW..'], []], ['?BW??', 'WBW??', 'WBWB?', '?BW??', '?BW??']]], [[[['.BWB', '.BW.', 'WBW.', '.BW.', '.BW.', 'WBW.'], [[4, 1]]], ['?BWB', '?BW?', 'WBW?', '?BW?', '??W?', 'WBW?']], [[['.BW.', '.BW.', 'WBW.', '.BW.', '.BW.'], [[0, 1], [3, 1]]], ['??Ww', '?BWw', 'WBWw', '??Ww', '?BWw']], [[['...BW', '..WBW', '...BW', '...BW', '...BW'], []], ['???BW', '??WBW', '???BW', '???BW', '???BW']], [[['...BW', '...BW', '...BW', 'W..BW'], []], ['???BW', '???BW', '???BW', 'W??BW']], [[['..BW.', '..BW.', '..BWB', '..BW.', '..BW.', '..BW.', '..BW.'], [[2, 2], [3, 3]]], ['??BW?', '??BW?', '???WB', '??B??', '??BW?', '??BW?', '??BW?']], [[['.BW..', '.BW.B', '.BWB.', '.BW..', '.BW.B', '.BW..', 'WBW..'], [[4, 1]]], ['?BW??', '?BW?B', '?BWB?', '?BW??', '??W?B', '?BW??', 'WBW??']], [[['..BW', 'W.BW', '..BW', '..BW', '..BW', 'W.BW'], [[0, 2], [5, 3]]], ['???W', 'W?BW', '??BW', '??BW', '??BW', 'W?B?']], [[['...BW.', '...BW.', '...BW.', '...BW.', '...BW.', '...BW.'], [[2, 4]]], ['bbbBW?', 'bbbBW?', 'bbbB??', 'bbbBW?', 'bbbBW?', 'bbbBW?']]], [[[['.BW..', 'WBW..', 'WBWB.', '.BW..', '.BW..'], []], ['?BW??', 'WBW??', 'WBWB?', '?BW??', '?BW??']], [[['...BW', '...BW', 'W..BW', 'W.WBW', '...BW', '...BW'], []], ['???BW', '???BW', 'W??BW', 'W?WBW', '???BW', '???BW']], [[['....', '....', '....', '....'], []], ['????', '????', '????', '????']], [[['...', '...', '...'], []], ['???', '???', '???']], [[['.B.', 'B.B', '.B.'], [[1, 2], [2, 1]]], ['bBb', 'Bbb', 'bbb']], [[['B..W', 'B..W', 'B..W', 'B..W'], [[2, 3]]], ['B??W', 'B??W', 'B???', 'B??W']], [[['.BW.', '.BW.', '.BW.', '.BW.'], [[0, 2]]], ['bB??', 'bBW?', 'bBW?', 'bBW?']], [[['..B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], [[0, 2]]], ['bbbbb', 'bbBbb', 'BBBBB', 'WWWWW', 'wwWww']]], [[[['.BW..', '.BW.B', '.BWB.', '.BW..', '.BW.B', '.BW..', 'WBW..'], [[4, 1]]], ['?BW??', '?BW?B', '?BWB?', '?BW??', '??W?B', '?BW??', 'WBW??']], [[['B.B.W', '.B.W.', 'B.BW.', 'BBW.W', '..W..'], []], ['BbB?W', 'bB?Ww', 'BbBWw', 'BBWwW', '??Www']], [[['W....', '.....', '.....', '.....', '....B'], [[4, 4]]], ['Wwwww', 'wwwww', 'wwwww', 'wwwww', 'wwwww']], [[['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], [[3, 1], [3, 0]]], ['wW?B?', 'WwWB?', '?WB??', '?????', 'B????']], [[['BBBB', 'B..B', 'B..B', 'BBBB'], [[0, 2]]], ['BBbB', 'BbbB', 'BbbB', 'BBBB']], [[['WWW', 'W.W', 'WWW'], []], ['WWW', 'WwW', 'WWW']], [[['B.W', '...', 'W.B'], [[2, 2], [0, 0]]], ['wwW', 'www', 'Www']], [[['.B...', 'B....', '.....', '....W', '...W.'], [[1, 0]]], ['?B???', '?????', '?????', '????W', '???Ww']]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("ownership map case %d" % i, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| ownership map case 0 | ['bbbBW..', 'bbbBW..', 'bbbBW..', 'bbbBWB.', 'bbbB...'] | ['bbbBW??', 'bbbBW??', 'bbbBW??', 'bbbBWB?', 'bbbB???'] | Failed |
| ownership map case 1 | ['..Ww', '.BWw', '.BWw', '.BWw', '.BWw', 'WBWw'] | ['??Ww', '?BWw', '?BWw', '?BWw', '?BWw', 'WBWw'] | Failed |
| ownership map case 2 | ['bB.B.', 'bBW..', 'bB...', 'bBWB.'] | ['bB?B?', 'bBW??', 'bB???', 'bBWB?'] | Failed |
| ownership map case 3 | ['WB....', '.BW...', '.BW..B', '.BW...', '.BW...'] | ['WB????', '?BW???', '?BW??B', '?BW???', '?BW???'] | Failed |
| ownership map case 4 | ['.BW.B..', 'WBW....', '.B.....', '.BW....', '.BW....'] | ['?BW?B??', 'WBW????', '?B?????', '?BW????', '?BW????'] | Failed |
| ownership map case 5 | ['....BW', '....BW', '......', '....BW', '....BW', '....BW'] | ['????BW', '????BW', '??????', '????BW', '????BW', '????BW'] | Failed |
| ownership map case 6 | ['..BW', '..BW', '..BW', '...W', '..BW', '..BW', '..BW'] | ['??BW', '??BW', '??BW', '???W', '??BW', '??BW', '??BW'] | Failed |
| ownership map case 7 | ['W.BWw', '..BWw', '.WBWw', '.WBWw', '..BWw', '..BWw', '..BWw'] | ['W?BWw', '??BWw', '?WBWw', '?WBWw', '??BWw', '??BWw', '??BWw'] | Failed |
SHA-256 / 5e50c5b6a5b8984077a3be226fc637c0ace50112bd6ec75c9aa30526f78825bf
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
board, dead = x
n = len(board)
m = len(board[0])
dd = {tuple(p) for p in dead}
g = [[('.' if (r, c) in dd else board[r][c]) for c in range(m)] for r in range(n)]
out = [[g[r][c] for c in range(m)] for r in range(n)]
seen = set()
for r in range(n):
for c in range(m):
if g[r][c] != '.' or (r, c) in seen:
continue
seen.add((r, c))
region = [(r, c)]
k = 0
cols = set()
while k < len(region):
i, j = region[k]
k += 1
for p, q in ((i - 1, j), (i, j - 1), (i + 1, j), (i, j + 1)):
if 0 <= p < n and 0 <= q < m:
if g[p][q] == '.':
if (p, q) not in seen:
seen.add((p, q))
region.append((p, q))
else:
cols.add(g[p][q])
mark = cols.pop().lower() if len(cols) == 1 else '?'
for i, j in region:
out[i][j] = mark
return [''.join(row) for row in out]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['...BW..', '...BW..', '...BW..', '...BWB.', '...BW.B'], [[4, 6], [4, 4]]], ['bbbBW??', 'bbbBW??', 'bbbBW??', 'bbbBWB?', 'bbbB???']], [[['.BW.', '.BW.', 'WBW.', '.BW.', '.BW.', 'WBW.'], [[0, 1], [2, 0]]], ['??Ww', '?BWw', '?BWw', '?BWw', '?BWw', 'WBWw']], [[['.BWB.', '.BW..', '.BW..', '.BWB.'], [[2, 2], [0, 2]]], ['bB?B?', 'bBW??', 'bB???', 'bBWB?']], [[['WBW...', '.BW...', '.BW..B', '.BW...', '.BW...'], [[0, 2]]], ['WB????', '?BW???', '?BW??B', '?BW???', '?BW???']], [[['.BW.B..', 'WBW....', '.BW....', '.BW....', '.BW....'], [[2, 2]]], ['?BW?B??', 'WBW????', '?B?????', '?BW????', '?BW????']], [[['....BW', '....BW', '....BW', '....BW', '....BW', '....BW'], [[2, 5], [2, 4]]], ['????BW', '????BW', '??????', '????BW', '????BW', '????BW']], [[['..BW', '..BW', '..BW', '..BW', '..BW', '..BW', '..BW'], [[3, 2]]], ['??BW', '??BW', '??BW', '???W', '??BW', '??BW', '??BW']], [[['W.BW.', '..BW.', '.WBW.', '.WBW.', '..BW.', '..BW.', '..BW.'], []], ['W?BWw', '??BWw', '?WBWw', '?WBWw', '??BWw', '??BWw', '??BWw']]], [[[['...WBW.', '....BW.', '....BW.', '.W..BW.'], []], ['???WBWw', '????BWw', '????BWw', '?W??BWw']], [[['.BW.B..', 'WBW....', '.BW....', '.BW....', '.BW....'], [[2, 2]]], ['?BW?B??', 'WBW????', '?B?????', '?BW????', '?BW????']], [[['.BWB', '.BW.', 'WBW.', '.BW.', '.BW.', 'WBW.'], [[4, 1]]], ['?BWB', '?BW?', 'WBW?', '?BW?', '??W?', 'WBW?']], [[['.BW.', '.BW.', 'WBW.', '.BW.', '.BW.'], [[0, 1], [3, 1]]], ['??Ww', '?BWw', 'WBWw', '??Ww', '?BWw']], [[['.W..BW', '....BW', 'W...BW', '....BW'], [[1, 4]]], ['?W??BW', '?????W', 'W???BW', '????BW']], [[['..BW', '..BW', 'W.BW', '..BW', '..BW'], [[4, 2], [3, 2]]], ['??BW', '??BW', 'W?BW', '???W', '???W']], [[['.BW...', '.BW...', '.BW...', 'WBW..B', '.BW..B', '.BW..B'], []], ['?BW???', '?BW???', '?BW???', 'WBW??B', '?BW??B', '?BW??B']], [[['.BW..', 'WBW..', 'WBWB.', '.BW..', '.BW..'], []], ['?BW??', 'WBW??', 'WBWB?', '?BW??', '?BW??']]], [[[['.BWB', '.BW.', 'WBW.', '.BW.', '.BW.', 'WBW.'], [[4, 1]]], ['?BWB', '?BW?', 'WBW?', '?BW?', '??W?', 'WBW?']], [[['.BW.', '.BW.', 'WBW.', '.BW.', '.BW.'], [[0, 1], [3, 1]]], ['??Ww', '?BWw', 'WBWw', '??Ww', '?BWw']], [[['...BW', '..WBW', '...BW', '...BW', '...BW'], []], ['???BW', '??WBW', '???BW', '???BW', '???BW']], [[['...BW', '...BW', '...BW', 'W..BW'], []], ['???BW', '???BW', '???BW', 'W??BW']], [[['..BW.', '..BW.', '..BWB', '..BW.', '..BW.', '..BW.', '..BW.'], [[2, 2], [3, 3]]], ['??BW?', '??BW?', '???WB', '??B??', '??BW?', '??BW?', '??BW?']], [[['.BW..', '.BW.B', '.BWB.', '.BW..', '.BW.B', '.BW..', 'WBW..'], [[4, 1]]], ['?BW??', '?BW?B', '?BWB?', '?BW??', '??W?B', '?BW??', 'WBW??']], [[['..BW', 'W.BW', '..BW', '..BW', '..BW', 'W.BW'], [[0, 2], [5, 3]]], ['???W', 'W?BW', '??BW', '??BW', '??BW', 'W?B?']], [[['...BW.', '...BW.', '...BW.', '...BW.', '...BW.', '...BW.'], [[2, 4]]], ['bbbBW?', 'bbbBW?', 'bbbB??', 'bbbBW?', 'bbbBW?', 'bbbBW?']]], [[[['.BW..', 'WBW..', 'WBWB.', '.BW..', '.BW..'], []], ['?BW??', 'WBW??', 'WBWB?', '?BW??', '?BW??']], [[['...BW', '...BW', 'W..BW', 'W.WBW', '...BW', '...BW'], []], ['???BW', '???BW', 'W??BW', 'W?WBW', '???BW', '???BW']], [[['....', '....', '....', '....'], []], ['????', '????', '????', '????']], [[['...', '...', '...'], []], ['???', '???', '???']], [[['.B.', 'B.B', '.B.'], [[1, 2], [2, 1]]], ['bBb', 'Bbb', 'bbb']], [[['B..W', 'B..W', 'B..W', 'B..W'], [[2, 3]]], ['B??W', 'B??W', 'B???', 'B??W']], [[['.BW.', '.BW.', '.BW.', '.BW.'], [[0, 2]]], ['bB??', 'bBW?', 'bBW?', 'bBW?']], [[['..B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], [[0, 2]]], ['bbbbb', 'bbBbb', 'BBBBB', 'WWWWW', 'wwWww']]], [[[['.BW..', '.BW.B', '.BWB.', '.BW..', '.BW.B', '.BW..', 'WBW..'], [[4, 1]]], ['?BW??', '?BW?B', '?BWB?', '?BW??', '??W?B', '?BW??', 'WBW??']], [[['B.B.W', '.B.W.', 'B.BW.', 'BBW.W', '..W..'], []], ['BbB?W', 'bB?Ww', 'BbBWw', 'BBWwW', '??Www']], [[['W....', '.....', '.....', '.....', '....B'], [[4, 4]]], ['Wwwww', 'wwwww', 'wwwww', 'wwwww', 'wwwww']], [[['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], [[3, 1], [3, 0]]], ['wW?B?', 'WwWB?', '?WB??', '?????', 'B????']], [[['BBBB', 'B..B', 'B..B', 'BBBB'], [[0, 2]]], ['BBbB', 'BbbB', 'BbbB', 'BBBB']], [[['WWW', 'W.W', 'WWW'], []], ['WWW', 'WwW', 'WWW']], [[['B.W', '...', 'W.B'], [[2, 2], [0, 0]]], ['wwW', 'www', 'Www']], [[['.B...', 'B....', '.....', '....W', '...W.'], [[1, 0]]], ['?B???', '?????', '?????', '????W', '???Ww']]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("ownership map case %d" % i, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| ownership map case 0 | ['bbbBW??', 'bbbBW??', 'bbbBW??', 'bbbBWB?', 'bbbB???'] | ['bbbBW??', 'bbbBW??', 'bbbBW??', 'bbbBWB?', 'bbbB???'] | Passed |
| ownership map case 1 | ['??Ww', '?BWw', '?BWw', '?BWw', '?BWw', 'WBWw'] | ['??Ww', '?BWw', '?BWw', '?BWw', '?BWw', 'WBWw'] | Passed |
| ownership map case 2 | ['bB?B?', 'bBW??', 'bB???', 'bBWB?'] | ['bB?B?', 'bBW??', 'bB???', 'bBWB?'] | Passed |
| ownership map case 3 | ['WB????', '?BW???', '?BW??B', '?BW???', '?BW???'] | ['WB????', '?BW???', '?BW??B', '?BW???', '?BW???'] | Passed |
| ownership map case 4 | ['?BW?B??', 'WBW????', '?B?????', '?BW????', '?BW????'] | ['?BW?B??', 'WBW????', '?B?????', '?BW????', '?BW????'] | Passed |
| ownership map case 5 | ['????BW', '????BW', '??????', '????BW', '????BW', '????BW'] | ['????BW', '????BW', '??????', '????BW', '????BW', '????BW'] | Passed |
| ownership map case 6 | ['??BW', '??BW', '??BW', '???W', '??BW', '??BW', '??BW'] | ['??BW', '??BW', '??BW', '???W', '??BW', '??BW', '??BW'] | Passed |
| ownership map case 7 | ['W?BWw', '??BWw', '?WBWw', '?WBWw', '??BWw', '??BWw', '??BWw'] | ['W?BWw', '??BWw', '?WBWw', '?WBWw', '??BWw', '??BWw', '??BWw'] | Passed |
SHA-256 / d8324dad261c78577042b9d1261751a76b352756b60d6a3d09401956d1f7b6c8
Verification & scope
Small rectangular toy boards given as strings of B, W and dot; a bounded teaching model of one scoring or bookkeeping rule, not a complete rules engine or server implementation. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:50:19.372310+00:00.
Case digest / 56e8bef0fe2e427cd6506cc669dc3f259e340a32189c6e3099f4e29f87201254