FAILURE MAP
← Case archive

FA-83136 / Go territory scoring / Open access

Toggle direction is decided from the whole chain rather than the clicked stone · case 01

Clicking a marked stone in a partially marked chain marks everything.

Verified by executionVariant 1 · 8 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The code unmarks only when every chain stone is already marked.

VERIFIED REPAIR

Decide by the clicked stone state.

Unsuccessful approach: Unmarking when any chain stone is marked flips the decision for an unmarked clicked stone.

Case contract

Input [board, dead_points, row, col]. Clicking a stone toggles its whole orthogonally connected chain: if the clicked stone is currently marked, unmark the chain, otherwise mark it. Clicking an empty point changes nothing. Return the sorted distinct dead points.

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, r, c = x
    n = len(board)
    m = len(board[0])
    col = board[r][c]
    marked = {tuple(p) for p in dead}
    if col == '.':
        return sorted([list(p) for p in marked])
    chain = {(r, c)}
    stack = [(r, c)]
    while stack:
        i, j = stack.pop()
        for p, q in ((i + 1, j), (i, j + 1), (i - 1, j), (i, j - 1)):
            if 0 <= p < n and 0 <= q < m and board[p][q] == col and (p, q) not in chain:
                chain.add((p, q))
                stack.append((p, q))
    if chain <= marked:
        marked -= chain
    else:
        marked |= chain
    return sorted([list(p) for p in marked])
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['.B.', 'B.B', '.B.'], [[1, 0], [1, 2]], 1, 2], [[1, 0]]], [[['.B.', 'B.B', '.B.'], [[1, 2], [0, 1], [1, 0]], 2, 1], [[0, 1], [1, 0], [1, 2], [2, 1]]], [[['B..W', 'B..W', 'B..W', 'B..W'], [[2, 3], [3, 0]], 3, 1], [[2, 3], [3, 0]]], [[['B..W', 'B..W', 'B..W', 'B..W'], [], 1, 1], []], [[['B..W', 'B..W', 'B..W', 'B..W'], [[0, 0]], 3, 0], [[0, 0], [1, 0], [2, 0], [3, 0]]], [[['.BW.', '.BW.', '.BW.', '.BW.'], [[0, 1], [0, 1], [2, 1], [0, 2]], 0, 1], [[0, 2]]], [[['.BW.', '.BW.', '.BW.', '.BW.'], [[0, 2]], 3, 2], [[0, 2], [1, 2], [2, 2], [3, 2]]], [[['BW.', 'BW.', 'BW.'], [[2, 1], [2, 1]], 0, 1], [[0, 1], [1, 1], [2, 1]]]], [[[['.BW.', '.BW.', '.BW.', '.BW.'], [], 3, 1], [[0, 1], [1, 1], [2, 1], [3, 1]]], [[['..B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], [[3, 3], [1, 2]], 3, 1], [[1, 2], [3, 0], [3, 1], [3, 2], [3, 3], [3, 4], [4, 2]]], [[['..B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], [[4, 2], [4, 2], [1, 2], [0, 2]], 3, 2], [[0, 2], [1, 2], [3, 0], [3, 1], [3, 2], [3, 3], [3, 4], [4, 2]]], [[['..B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], [], 3, 4], [[3, 0], [3, 1], [3, 2], [3, 3], [3, 4], [4, 2]]], [[['B.B.W', '.B.W.', 'B.BW.', 'BBW.W', '..W..'], [[2, 2]], 4, 0], [[2, 2]]], [[['B.B.W', '.B.W.', 'B.BW.', 'BBW.W', '..W..'], [[2, 3], [3, 0]], 2, 1], [[2, 3], [3, 0]]], [[['..W.', '..W.', 'W..W'], [[0, 2], [2, 3], [0, 2]], 0, 2], [[2, 3]]], [[['BWWW', 'B.WW', 'W.WB', 'WWWW'], [[0, 0], [0, 2], [3, 1]], 2, 2], [[0, 0], [0, 1], [0, 2], [0, 3], [1, 2], [1, 3], [2, 0], [2, 2], [3, 0], [3, 1], [3, 2], [3, 3]]]], [[[['W....', '.....', '.....', '.....', '....B'], [], 4, 4], [[4, 4]]], [[['W....', '.....', '.....', '.....', '....B'], [[4, 4], [0, 0]], 0, 0], [[4, 4]]], [[['W....', '.....', '.....', '.....', '....B'], [[4, 4], [4, 4], [0, 0]], 0, 0], [[4, 4]]], [[['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], [], 3, 0], [[3, 0]]], [[['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], [[0, 1]], 4, 2], [[0, 1]]], [[['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], [[2, 2], [1, 3], [1, 3]], 4, 1], [[1, 3], [2, 2]]], [[['BB.', 'BBW', 'WW.', '..W'], [[1, 1], [1, 2]], 0, 0], [[0, 0], [0, 1], [1, 0], [1, 1], [1, 2]]], [[['.WWB.', 'B.WWW', '..BW.', 'WW.WW', 'W....'], [[0, 2], [3, 1], [0, 3], [0, 2]], 0, 2], [[0, 3], [3, 1]]]], [[[['BBBB', 'B..B', 'B..B', 'BBBB'], [], 2, 3], [[0, 0], [0, 1], [0, 2], [0, 3], [1, 0], [1, 3], [2, 0], [2, 3], [3, 0], [3, 1], [3, 2], [3, 3]]], [[['BBBB', 'B..B', 'B..B', 'BBBB'], [[1, 0], [3, 2], [1, 0], [0, 2]], 3, 1], [[0, 0], [0, 1], [0, 2], [0, 3], [1, 0], [1, 3], [2, 0], [2, 3], [3, 0], [3, 1], [3, 2], [3, 3]]], [[['WWW', 'W.W', 'WWW'], [[0, 1], [1, 2], [1, 2]], 0, 1], []], [[['WWW', 'W.W', 'WWW'], [[0, 1], [0, 0]], 1, 1], [[0, 0], [0, 1]]], [[['WWW', 'W.W', 'WWW'], [[1, 2], [0, 2], [2, 1]], 1, 1], [[0, 2], [1, 2], [2, 1]]], [[['B.W', '...', 'W.B'], [], 2, 2], [[2, 2]]], [[['BWW', '..W', '...', 'WW.', '..W'], [[0, 1]], 0, 2], [[0, 1], [0, 2], [1, 2]]], [[['.B.W.', 'WBB.B', '..B.B', '.BW.B'], [[0, 3], [0, 1], [2, 2]], 2, 2], [[0, 3]]]], [[[['B.W', '...', 'W.B'], [], 0, 2], [[0, 2]]], [[['.B...', 'B....', '.....', '....W', '...W.'], [], 0, 1], [[0, 1]]], [[['.B...', 'B....', '.....', '....W', '...W.'], [], 4, 3], [[4, 3]]], [[['.B...', 'B....', '.....', '....W', '...W.'], [[1, 0], [1, 0]], 4, 3], [[1, 0], [4, 3]]], [[['BW.', 'BW.', 'BW.'], [], 2, 0], [[0, 0], [1, 0], [2, 0]]], [[['BW.', 'BW.', 'BW.'], [[2, 1], [1, 1], [1, 1]], 0, 0], [[0, 0], [1, 0], [1, 1], [2, 0], [2, 1]]], [[['W..W', 'WB.W', '.WWW'], [[0, 3], [1, 1]], 1, 3], [[0, 3], [1, 1], [1, 3], [2, 1], [2, 2], [2, 3]]], [[['BWWW', 'BW.W', 'WWWW', '.W.W'], [[2, 3], [0, 0], [0, 1], [2, 3]], 2, 3], [[0, 0]]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("dead marks 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 fixtureActualExpectedOutcome
dead marks case 0[[1, 0]][[1, 0]]Passed
dead marks case 1[[0, 1], [1, 0], [1, 2], [2, 1]][[0, 1], [1, 0], [1, 2], [2, 1]]Passed
dead marks case 2[[2, 3], [3, 0]][[2, 3], [3, 0]]Passed
dead marks case 3[][]Passed
dead marks case 4[[0, 0], [1, 0], [2, 0], [3, 0]][[0, 0], [1, 0], [2, 0], [3, 0]]Passed
dead marks case 5[[0, 1], [0, 2], [1, 1], [2, 1], [3, 1]][[0, 2]]Failed
dead marks case 6[[0, 2], [1, 2], [2, 2], [3, 2]][[0, 2], [1, 2], [2, 2], [3, 2]]Passed
dead marks case 7[[0, 1], [1, 1], [2, 1]][[0, 1], [1, 1], [2, 1]]Passed

SHA-256 / 7d083aab940a9bfddb195626ec61ee34e146a810bbd7ffb1b7a171face04b097

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    board, dead, r, c = x
    n = len(board)
    m = len(board[0])
    col = board[r][c]
    marked = {tuple(p) for p in dead}
    if col == '.':
        return sorted([list(p) for p in marked])
    chain = {(r, c)}
    stack = [(r, c)]
    while stack:
        i, j = stack.pop()
        for p, q in ((i + 1, j), (i, j + 1), (i - 1, j), (i, j - 1)):
            if 0 <= p < n and 0 <= q < m and board[p][q] == col and (p, q) not in chain:
                chain.add((p, q))
                stack.append((p, q))
    if chain & marked:
        marked -= chain
    else:
        marked |= chain
    return sorted([list(p) for p in marked])
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['.B.', 'B.B', '.B.'], [[1, 0], [1, 2]], 1, 2], [[1, 0]]], [[['.B.', 'B.B', '.B.'], [[1, 2], [0, 1], [1, 0]], 2, 1], [[0, 1], [1, 0], [1, 2], [2, 1]]], [[['B..W', 'B..W', 'B..W', 'B..W'], [[2, 3], [3, 0]], 3, 1], [[2, 3], [3, 0]]], [[['B..W', 'B..W', 'B..W', 'B..W'], [], 1, 1], []], [[['B..W', 'B..W', 'B..W', 'B..W'], [[0, 0]], 3, 0], [[0, 0], [1, 0], [2, 0], [3, 0]]], [[['.BW.', '.BW.', '.BW.', '.BW.'], [[0, 1], [0, 1], [2, 1], [0, 2]], 0, 1], [[0, 2]]], [[['.BW.', '.BW.', '.BW.', '.BW.'], [[0, 2]], 3, 2], [[0, 2], [1, 2], [2, 2], [3, 2]]], [[['BW.', 'BW.', 'BW.'], [[2, 1], [2, 1]], 0, 1], [[0, 1], [1, 1], [2, 1]]]], [[[['.BW.', '.BW.', '.BW.', '.BW.'], [], 3, 1], [[0, 1], [1, 1], [2, 1], [3, 1]]], [[['..B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], [[3, 3], [1, 2]], 3, 1], [[1, 2], [3, 0], [3, 1], [3, 2], [3, 3], [3, 4], [4, 2]]], [[['..B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], [[4, 2], [4, 2], [1, 2], [0, 2]], 3, 2], [[0, 2], [1, 2], [3, 0], [3, 1], [3, 2], [3, 3], [3, 4], [4, 2]]], [[['..B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], [], 3, 4], [[3, 0], [3, 1], [3, 2], [3, 3], [3, 4], [4, 2]]], [[['B.B.W', '.B.W.', 'B.BW.', 'BBW.W', '..W..'], [[2, 2]], 4, 0], [[2, 2]]], [[['B.B.W', '.B.W.', 'B.BW.', 'BBW.W', '..W..'], [[2, 3], [3, 0]], 2, 1], [[2, 3], [3, 0]]], [[['..W.', '..W.', 'W..W'], [[0, 2], [2, 3], [0, 2]], 0, 2], [[2, 3]]], [[['BWWW', 'B.WW', 'W.WB', 'WWWW'], [[0, 0], [0, 2], [3, 1]], 2, 2], [[0, 0], [0, 1], [0, 2], [0, 3], [1, 2], [1, 3], [2, 0], [2, 2], [3, 0], [3, 1], [3, 2], [3, 3]]]], [[[['W....', '.....', '.....', '.....', '....B'], [], 4, 4], [[4, 4]]], [[['W....', '.....', '.....', '.....', '....B'], [[4, 4], [0, 0]], 0, 0], [[4, 4]]], [[['W....', '.....', '.....', '.....', '....B'], [[4, 4], [4, 4], [0, 0]], 0, 0], [[4, 4]]], [[['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], [], 3, 0], [[3, 0]]], [[['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], [[0, 1]], 4, 2], [[0, 1]]], [[['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], [[2, 2], [1, 3], [1, 3]], 4, 1], [[1, 3], [2, 2]]], [[['BB.', 'BBW', 'WW.', '..W'], [[1, 1], [1, 2]], 0, 0], [[0, 0], [0, 1], [1, 0], [1, 1], [1, 2]]], [[['.WWB.', 'B.WWW', '..BW.', 'WW.WW', 'W....'], [[0, 2], [3, 1], [0, 3], [0, 2]], 0, 2], [[0, 3], [3, 1]]]], [[[['BBBB', 'B..B', 'B..B', 'BBBB'], [], 2, 3], [[0, 0], [0, 1], [0, 2], [0, 3], [1, 0], [1, 3], [2, 0], [2, 3], [3, 0], [3, 1], [3, 2], [3, 3]]], [[['BBBB', 'B..B', 'B..B', 'BBBB'], [[1, 0], [3, 2], [1, 0], [0, 2]], 3, 1], [[0, 0], [0, 1], [0, 2], [0, 3], [1, 0], [1, 3], [2, 0], [2, 3], [3, 0], [3, 1], [3, 2], [3, 3]]], [[['WWW', 'W.W', 'WWW'], [[0, 1], [1, 2], [1, 2]], 0, 1], []], [[['WWW', 'W.W', 'WWW'], [[0, 1], [0, 0]], 1, 1], [[0, 0], [0, 1]]], [[['WWW', 'W.W', 'WWW'], [[1, 2], [0, 2], [2, 1]], 1, 1], [[0, 2], [1, 2], [2, 1]]], [[['B.W', '...', 'W.B'], [], 2, 2], [[2, 2]]], [[['BWW', '..W', '...', 'WW.', '..W'], [[0, 1]], 0, 2], [[0, 1], [0, 2], [1, 2]]], [[['.B.W.', 'WBB.B', '..B.B', '.BW.B'], [[0, 3], [0, 1], [2, 2]], 2, 2], [[0, 3]]]], [[[['B.W', '...', 'W.B'], [], 0, 2], [[0, 2]]], [[['.B...', 'B....', '.....', '....W', '...W.'], [], 0, 1], [[0, 1]]], [[['.B...', 'B....', '.....', '....W', '...W.'], [], 4, 3], [[4, 3]]], [[['.B...', 'B....', '.....', '....W', '...W.'], [[1, 0], [1, 0]], 4, 3], [[1, 0], [4, 3]]], [[['BW.', 'BW.', 'BW.'], [], 2, 0], [[0, 0], [1, 0], [2, 0]]], [[['BW.', 'BW.', 'BW.'], [[2, 1], [1, 1], [1, 1]], 0, 0], [[0, 0], [1, 0], [1, 1], [2, 0], [2, 1]]], [[['W..W', 'WB.W', '.WWW'], [[0, 3], [1, 1]], 1, 3], [[0, 3], [1, 1], [1, 3], [2, 1], [2, 2], [2, 3]]], [[['BWWW', 'BW.W', 'WWWW', '.W.W'], [[2, 3], [0, 0], [0, 1], [2, 3]], 2, 3], [[0, 0]]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("dead marks 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 fixtureActualExpectedOutcome
dead marks case 0[[1, 0]][[1, 0]]Passed
dead marks case 1[[0, 1], [1, 0], [1, 2], [2, 1]][[0, 1], [1, 0], [1, 2], [2, 1]]Passed
dead marks case 2[[2, 3], [3, 0]][[2, 3], [3, 0]]Passed
dead marks case 3[][]Passed
dead marks case 4[][[0, 0], [1, 0], [2, 0], [3, 0]]Failed
dead marks case 5[[0, 2]][[0, 2]]Passed
dead marks case 6[][[0, 2], [1, 2], [2, 2], [3, 2]]Failed
dead marks case 7[][[0, 1], [1, 1], [2, 1]]Failed

SHA-256 / 484dca1808d991f3527021c42a1cb0800a04b0ea793904ded06de1f38fbcbc44

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    board, dead, r, c = x
    n = len(board)
    m = len(board[0])
    col = board[r][c]
    marked = {tuple(p) for p in dead}
    if col == '.':
        return sorted([list(p) for p in marked])
    chain = {(r, c)}
    stack = [(r, c)]
    while stack:
        i, j = stack.pop()
        for p, q in ((i + 1, j), (i, j + 1), (i - 1, j), (i, j - 1)):
            if 0 <= p < n and 0 <= q < m and board[p][q] == col and (p, q) not in chain:
                chain.add((p, q))
                stack.append((p, q))
    if (r, c) in marked:
        marked -= chain
    else:
        marked |= chain
    return sorted([list(p) for p in marked])
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['.B.', 'B.B', '.B.'], [[1, 0], [1, 2]], 1, 2], [[1, 0]]], [[['.B.', 'B.B', '.B.'], [[1, 2], [0, 1], [1, 0]], 2, 1], [[0, 1], [1, 0], [1, 2], [2, 1]]], [[['B..W', 'B..W', 'B..W', 'B..W'], [[2, 3], [3, 0]], 3, 1], [[2, 3], [3, 0]]], [[['B..W', 'B..W', 'B..W', 'B..W'], [], 1, 1], []], [[['B..W', 'B..W', 'B..W', 'B..W'], [[0, 0]], 3, 0], [[0, 0], [1, 0], [2, 0], [3, 0]]], [[['.BW.', '.BW.', '.BW.', '.BW.'], [[0, 1], [0, 1], [2, 1], [0, 2]], 0, 1], [[0, 2]]], [[['.BW.', '.BW.', '.BW.', '.BW.'], [[0, 2]], 3, 2], [[0, 2], [1, 2], [2, 2], [3, 2]]], [[['BW.', 'BW.', 'BW.'], [[2, 1], [2, 1]], 0, 1], [[0, 1], [1, 1], [2, 1]]]], [[[['.BW.', '.BW.', '.BW.', '.BW.'], [], 3, 1], [[0, 1], [1, 1], [2, 1], [3, 1]]], [[['..B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], [[3, 3], [1, 2]], 3, 1], [[1, 2], [3, 0], [3, 1], [3, 2], [3, 3], [3, 4], [4, 2]]], [[['..B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], [[4, 2], [4, 2], [1, 2], [0, 2]], 3, 2], [[0, 2], [1, 2], [3, 0], [3, 1], [3, 2], [3, 3], [3, 4], [4, 2]]], [[['..B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], [], 3, 4], [[3, 0], [3, 1], [3, 2], [3, 3], [3, 4], [4, 2]]], [[['B.B.W', '.B.W.', 'B.BW.', 'BBW.W', '..W..'], [[2, 2]], 4, 0], [[2, 2]]], [[['B.B.W', '.B.W.', 'B.BW.', 'BBW.W', '..W..'], [[2, 3], [3, 0]], 2, 1], [[2, 3], [3, 0]]], [[['..W.', '..W.', 'W..W'], [[0, 2], [2, 3], [0, 2]], 0, 2], [[2, 3]]], [[['BWWW', 'B.WW', 'W.WB', 'WWWW'], [[0, 0], [0, 2], [3, 1]], 2, 2], [[0, 0], [0, 1], [0, 2], [0, 3], [1, 2], [1, 3], [2, 0], [2, 2], [3, 0], [3, 1], [3, 2], [3, 3]]]], [[[['W....', '.....', '.....', '.....', '....B'], [], 4, 4], [[4, 4]]], [[['W....', '.....', '.....', '.....', '....B'], [[4, 4], [0, 0]], 0, 0], [[4, 4]]], [[['W....', '.....', '.....', '.....', '....B'], [[4, 4], [4, 4], [0, 0]], 0, 0], [[4, 4]]], [[['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], [], 3, 0], [[3, 0]]], [[['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], [[0, 1]], 4, 2], [[0, 1]]], [[['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], [[2, 2], [1, 3], [1, 3]], 4, 1], [[1, 3], [2, 2]]], [[['BB.', 'BBW', 'WW.', '..W'], [[1, 1], [1, 2]], 0, 0], [[0, 0], [0, 1], [1, 0], [1, 1], [1, 2]]], [[['.WWB.', 'B.WWW', '..BW.', 'WW.WW', 'W....'], [[0, 2], [3, 1], [0, 3], [0, 2]], 0, 2], [[0, 3], [3, 1]]]], [[[['BBBB', 'B..B', 'B..B', 'BBBB'], [], 2, 3], [[0, 0], [0, 1], [0, 2], [0, 3], [1, 0], [1, 3], [2, 0], [2, 3], [3, 0], [3, 1], [3, 2], [3, 3]]], [[['BBBB', 'B..B', 'B..B', 'BBBB'], [[1, 0], [3, 2], [1, 0], [0, 2]], 3, 1], [[0, 0], [0, 1], [0, 2], [0, 3], [1, 0], [1, 3], [2, 0], [2, 3], [3, 0], [3, 1], [3, 2], [3, 3]]], [[['WWW', 'W.W', 'WWW'], [[0, 1], [1, 2], [1, 2]], 0, 1], []], [[['WWW', 'W.W', 'WWW'], [[0, 1], [0, 0]], 1, 1], [[0, 0], [0, 1]]], [[['WWW', 'W.W', 'WWW'], [[1, 2], [0, 2], [2, 1]], 1, 1], [[0, 2], [1, 2], [2, 1]]], [[['B.W', '...', 'W.B'], [], 2, 2], [[2, 2]]], [[['BWW', '..W', '...', 'WW.', '..W'], [[0, 1]], 0, 2], [[0, 1], [0, 2], [1, 2]]], [[['.B.W.', 'WBB.B', '..B.B', '.BW.B'], [[0, 3], [0, 1], [2, 2]], 2, 2], [[0, 3]]]], [[[['B.W', '...', 'W.B'], [], 0, 2], [[0, 2]]], [[['.B...', 'B....', '.....', '....W', '...W.'], [], 0, 1], [[0, 1]]], [[['.B...', 'B....', '.....', '....W', '...W.'], [], 4, 3], [[4, 3]]], [[['.B...', 'B....', '.....', '....W', '...W.'], [[1, 0], [1, 0]], 4, 3], [[1, 0], [4, 3]]], [[['BW.', 'BW.', 'BW.'], [], 2, 0], [[0, 0], [1, 0], [2, 0]]], [[['BW.', 'BW.', 'BW.'], [[2, 1], [1, 1], [1, 1]], 0, 0], [[0, 0], [1, 0], [1, 1], [2, 0], [2, 1]]], [[['W..W', 'WB.W', '.WWW'], [[0, 3], [1, 1]], 1, 3], [[0, 3], [1, 1], [1, 3], [2, 1], [2, 2], [2, 3]]], [[['BWWW', 'BW.W', 'WWWW', '.W.W'], [[2, 3], [0, 0], [0, 1], [2, 3]], 2, 3], [[0, 0]]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("dead marks 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 fixtureActualExpectedOutcome
dead marks case 0[[1, 0]][[1, 0]]Passed
dead marks case 1[[0, 1], [1, 0], [1, 2], [2, 1]][[0, 1], [1, 0], [1, 2], [2, 1]]Passed
dead marks case 2[[2, 3], [3, 0]][[2, 3], [3, 0]]Passed
dead marks case 3[][]Passed
dead marks case 4[[0, 0], [1, 0], [2, 0], [3, 0]][[0, 0], [1, 0], [2, 0], [3, 0]]Passed
dead marks case 5[[0, 2]][[0, 2]]Passed
dead marks case 6[[0, 2], [1, 2], [2, 2], [3, 2]][[0, 2], [1, 2], [2, 2], [3, 2]]Passed
dead marks case 7[[0, 1], [1, 1], [2, 1]][[0, 1], [1, 1], [2, 1]]Passed

SHA-256 / 56235351f7324154b979392c890d65c103d2ad3eb791435745b2bfc6af9fbae7

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:18.762525+00:00.

Case digest / 3e70a0370905b12a57a42fed70a2ae4017250928706cf87847ba9709cf67aee4