prompt:
Clicking one group also marks a diagonally touching group.

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.

split: open-access


meaning: Fixture-count band, not measured model difficulty

deps: stdlib

prompt:
A misclick during counting resets the dead-stone agreement.

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.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    board, seki = x
    n = len(board)
    m = len(board[0])
    sk = {tuple(p) for p in seki}
    tb = 0
    tw = 0
    seen = set()
    for r in range(n):
        for c in range(m):
            if board[r][c] != '.' or (r, c) in seen:
                continue
            seen.add((r, c))
            stack = [(r, c)]
            size = 0
            cols = set()
            frozen = False
            while stack:
                i, j = stack.pop()
                frozen = False
                size += 1
                if (i, j) in sk:
                    frozen = True
                for p, q in ((i, j + 1), (i + 1, j), (i, j - 1), (i - 1, j)):
                    if not (0 <= p < n and 0 <= q < m):
                        continue
                    if board[p][q] == '.':
                        if (p, q) not in seen:
                            seen.add((p, q))
                            stack.append((p, q))
                    else:
                        cols.add(board[p][q])
                        if (p, q) in sk:
                            frozen = True
            if frozen or len(cols) != 1:
                continue
            if 'B' in cols:
                tb += size
            else:
                tw += size
    return [tb, tw]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['..BW..', '..BW..', '..BW..', '..BW..'], [[1, 2], [3, 2], [3, 0]]], [0, 8]], [[['....BW', '....BW', '....BW', '....BW', '....BW', '...WBW', 'W...BW'], []], [0, 0]], [[['...BW..', '.W.BW..', '...BW..', '..WBW..'], [[1, 1]]], [0, 8]], [[['...BW.', 'W..BW.', '...BWB', '.W.BW.', '...BW.'], [[4, 3]]], [0, 0]], [[['....BW', '....BW', '.W..BW', '....BW', '....BW'], [[1, 5], [2, 1]]], [0, 0]], [[['WBW.', '.BW.', 'WBW.', '.BW.', '.BW.', '.BW.'], [[2, 0], [4, 3]]], [0, 0]], [[['.WBW', '..BW', '.WBW', '..BW'], [[2, 3], [2, 0]]], [0, 0]], [[['..B.', '.B..', '.BB.'], [[0, 2]]], [0, 0]]], [[[['.....BW', '.....BW', '.....BW', '.....BW', '.....BW', '.W...BW'], [[4, 6], [2, 6]]], [0, 0]], [[['..BWB', 'W.BW.', '..BW.', '..BW.'], [[3, 2]]], [0, 0]], [[['.W.BWB', '...BW.', '...BW.', '...BW.'], [[2, 4], [0, 5]]], [0, 0]], [[['.BW.B.', '.BW...', '.BW...', '.BW...'], [[1, 1], [0, 4], [3, 3]]], [0, 0]], [[['.WBW.', '..BW.', '..BW.', '..BW.'], []], [0, 4]], [[['....BW', '.W.WBW', '....BW', 'WW.WBW', '..W.BW', '.W..BW', '....BW'], [[2, 5], [1, 2]]], [0, 0]], [[['..BW.', '..BW.', '..BW.', '..BW.', '.WBW.'], [[0, 0]]], [0, 5]], [[['.BW.', '.BW.', '.BW.', '.BW.'], [[2, 2], [1, 0]]], [0, 0]]], [[[['..BWB.', '..BW..', '..BW..', '..BW..', '..BW..'], [[2, 2]]], [0, 0]], [[['.BW.', '.BW.', '.BW.', '.BW.'], [[0, 2], [3, 1], [0, 0]]], [0, 0]], [[['WW.BW.', '...BWB', '...BW.', '.W.BW.'], [[1, 5]]], [0, 0]], [[['..BW.', '..BW.', '..BW.', 'W.BWB', '..BWB', '..BW.', 'W.BW.'], [[3, 3], [0, 1]]], [0, 0]], [[['..BW..', '..BW..', '..BW..', '..BW..', '..BW..', '.WBW..'], [[2, 3]]], [0, 0]], [[['..BW.', '..BW.', '..BW.', 'WWBW.', '.WBW.'], []], [0, 6]], [[['.BW.', '.BWB', '.BW.', '.BWB', '.BW.'], [[4, 3]]], [5, 0]], [[['WBW..', '.BW..', '.BW..', '.BW..', '.BW.B', '.BW..'], [[4, 1]]], [0, 0]]], [[[['.BW..', '.BW..', '.BW..', '.BW..'], [[1, 1], [0, 2], [3, 3]]], [0, 0]], [[['..BW.', '..BW.', '..BWB', '..BW.', 'W.BW.', '..BW.', '..BW.'], [[2, 3], [2, 4], [6, 1]]], [0, 0]], [[['....', '....', '....', '....'], [[0, 0]]], [0, 0]], [[['...', '...', '...'], []], [0, 0]], [[['.B.', 'B.B', '.B.'], [[1, 1]]], [4, 0]], [[['B..W', 'B..W', 'B..W', 'B..W'], [[2, 3], [0, 0], [3, 2]]], [0, 0]], [[['.BW.', '.BW.', '.BW.', '.BW.'], [[2, 2], [1, 0]]], [0, 0]], [[['.....', '.BBB.', '.B.B.', '.BBB.', '.....'], [[1, 2], [3, 2], [4, 0]]], [0, 0]]], [[[['..B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], [[3, 3]]], [8, 2]], [[['B.B.W', '.B.W.', 'B.BW.', 'BBW.W', '..W..'], []], [3, 5]], [[['W....', '.....', '.....', '.....', '....B'], [[0, 4]]], [0, 0]], [[['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], [[1, 2], [2, 0]]], [11, 1]], [[['BBBB', 'B..B', 'B..B', 'BBBB'], []], [4, 0]], [[['WWW', 'W.W', 'WWW'], [[0, 2]]], [0, 1]], [[['..W', '.W.', 'W..'], [[0, 2]]], [0, 0]], [[['B.BWW', '.BW..', 'WBWWW', '.BBBW'], [[1, 3]]], [1, 0]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("seki territory 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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    board, seki = x
    n = len(board)
    m = len(board[0])
    sk = {tuple(p) for p in seki}
    tb = 0
    tw = 0
    seen = set()
    for r in range(n):
        for c in range(m):
            if board[r][c] != '.' or (r, c) in seen:
                continue
            seen.add((r, c))
            stack = [(r, c)]
            size = 0
            cols = set()
            frozen = False
            while stack:
                i, j = stack.pop()
                size += 1
                if (i, j) in sk:
                    frozen = True
                for p, q in ((i, j + 1), (i + 1, j), (i, j - 1), (i - 1, j)):
                    if not (0 <= p < n and 0 <= q < m):
                        continue
                    if board[p][q] == '.':
                        if (p, q) not in seen:
                            seen.add((p, q))
                            stack.append((p, q))
                    else:
                        cols.add(board[p][q])
                        if (p, q) in sk and (i, j) == (r, c):
                            frozen = True
            if frozen or len(cols) != 1:
                continue
            if 'B' in cols:
                tb += size
            else:
                tw += size
    return [tb, tw]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['..BW..', '..BW..', '..BW..', '..BW..'], [[1, 2], [3, 2], [3, 0]]], [0, 8]], [[['....BW', '....BW', '....BW', '....BW', '....BW', '...WBW', 'W...BW'], []], [0, 0]], [[['...BW..', '.W.BW..', '...BW..', '..WBW..'], [[1, 1]]], [0, 8]], [[['...BW.', 'W..BW.', '...BWB', '.W.BW.', '...BW.'], [[4, 3]]], [0, 0]], [[['....BW', '....BW', '.W..BW', '....BW', '....BW'], [[1, 5], [2, 1]]], [0, 0]], [[['WBW.', '.BW.', 'WBW.', '.BW.', '.BW.', '.BW.'], [[2, 0], [4, 3]]], [0, 0]], [[['.WBW', '..BW', '.WBW', '..BW'], [[2, 3], [2, 0]]], [0, 0]], [[['..B.', '.B..', '.BB.'], [[0, 2]]], [0, 0]]], [[[['.....BW', '.....BW', '.....BW', '.....BW', '.....BW', '.W...BW'], [[4, 6], [2, 6]]], [0, 0]], [[['..BWB', 'W.BW.', '..BW.', '..BW.'], [[3, 2]]], [0, 0]], [[['.W.BWB', '...BW.', '...BW.', '...BW.'], [[2, 4], [0, 5]]], [0, 0]], [[['.BW.B.', '.BW...', '.BW...', '.BW...'], [[1, 1], [0, 4], [3, 3]]], [0, 0]], [[['.WBW.', '..BW.', '..BW.', '..BW.'], []], [0, 4]], [[['....BW', '.W.WBW', '....BW', 'WW.WBW', '..W.BW', '.W..BW', '....BW'], [[2, 5], [1, 2]]], [0, 0]], [[['..BW.', '..BW.', '..BW.', '..BW.', '.WBW.'], [[0, 0]]], [0, 5]], [[['.BW.', '.BW.', '.BW.', '.BW.'], [[2, 2], [1, 0]]], [0, 0]]], [[[['..BWB.', '..BW..', '..BW..', '..BW..', '..BW..'], [[2, 2]]], [0, 0]], [[['.BW.', '.BW.', '.BW.', '.BW.'], [[0, 2], [3, 1], [0, 0]]], [0, 0]], [[['WW.BW.', '...BWB', '...BW.', '.W.BW.'], [[1, 5]]], [0, 0]], [[['..BW.', '..BW.', '..BW.', 'W.BWB', '..BWB', '..BW.', 'W.BW.'], [[3, 3], [0, 1]]], [0, 0]], [[['..BW..', '..BW..', '..BW..', '..BW..', '..BW..', '.WBW..'], [[2, 3]]], [0, 0]], [[['..BW.', '..BW.', '..BW.', 'WWBW.', '.WBW.'], []], [0, 6]], [[['.BW.', '.BWB', '.BW.', '.BWB', '.BW.'], [[4, 3]]], [5, 0]], [[['WBW..', '.BW..', '.BW..', '.BW..', '.BW.B', '.BW..'], [[4, 1]]], [0, 0]]], [[[['.BW..', '.BW..', '.BW..', '.BW..'], [[1, 1], [0, 2], [3, 3]]], [0, 0]], [[['..BW.', '..BW.', '..BWB', '..BW.', 'W.BW.', '..BW.', '..BW.'], [[2, 3], [2, 4], [6, 1]]], [0, 0]], [[['....', '....', '....', '....'], [[0, 0]]], [0, 0]], [[['...', '...', '...'], []], [0, 0]], [[['.B.', 'B.B', '.B.'], [[1, 1]]], [4, 0]], [[['B..W', 'B..W', 'B..W', 'B..W'], [[2, 3], [0, 0], [3, 2]]], [0, 0]], [[['.BW.', '.BW.', '.BW.', '.BW.'], [[2, 2], [1, 0]]], [0, 0]], [[['.....', '.BBB.', '.B.B.', '.BBB.', '.....'], [[1, 2], [3, 2], [4, 0]]], [0, 0]]], [[[['..B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], [[3, 3]]], [8, 2]], [[['B.B.W', '.B.W.', 'B.BW.', 'BBW.W', '..W..'], []], [3, 5]], [[['W....', '.....', '.....', '.....', '....B'], [[0, 4]]], [0, 0]], [[['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], [[1, 2], [2, 0]]], [11, 1]], [[['BBBB', 'B..B', 'B..B', 'BBBB'], []], [4, 0]], [[['WWW', 'W.W', 'WWW'], [[0, 2]]], [0, 1]], [[['..W', '.W.', 'W..'], [[0, 2]]], [0, 0]], [[['B.BWW', '.BW..', 'WBWWW', '.BBBW'], [[1, 3]]], [1, 0]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("seki territory 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)

prompt:
Regions touching seki stones are still counted if the last processed point does not touch them.

Input [board, seki_points]. Empty regions bordered by exactly one colour are territory, unless the region touches a stone listed as seki or contains a listed empty point. Return [terr_b, terr_w].

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    board, seki = x
    n = len(board)
    m = len(board[0])
    sk = {tuple(p) for p in seki}
    tb = 0
    tw = 0
    seen = set()
    for r in range(n):
        for c in range(m):
            if board[r][c] != '.' or (r, c) in seen:
                continue
            seen.add((r, c))
            stack = [(r, c)]
            size = 0
            cols = set()
            frozen = False
            while stack:
                i, j = stack.pop()
                size += 1
                if (i, j) in sk:
                    frozen = True
                for p, q in ((i, j + 1), (i + 1, j), (i, j - 1), (i - 1, j)):
                    if not (0 <= p < n and 0 <= q < m):
                        continue
                    if board[p][q] == '.':
                        if (p, q) not in seen:
                            seen.add((p, q))
                            stack.append((p, q))
                    else:
                        cols.add(board[p][q])
                        if (p, q) in sk:
                            frozen = True
            if len(cols) != 1:
                continue
            if 'B' in cols:
                tb += size
            else:
                tw += size
    return [tb, tw]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['..BW..', '..BW..', '..BW..', '..BW..'], [[1, 2], [3, 2], [3, 0]]], [0, 8]], [[['....BW', '....BW', '....BW', '....BW', '....BW', '...WBW', 'W...BW'], []], [0, 0]], [[['...BW..', '.W.BW..', '...BW..', '..WBW..'], [[1, 1]]], [0, 8]], [[['...BW.', 'W..BW.', '...BWB', '.W.BW.', '...BW.'], [[4, 3]]], [0, 0]], [[['....BW', '....BW', '.W..BW', '....BW', '....BW'], [[1, 5], [2, 1]]], [0, 0]], [[['WBW.', '.BW.', 'WBW.', '.BW.', '.BW.', '.BW.'], [[2, 0], [4, 3]]], [0, 0]], [[['.WBW', '..BW', '.WBW', '..BW'], [[2, 3], [2, 0]]], [0, 0]], [[['..BW..', '..BW..', '..BW..', '..BW..', '..BW..', '.WBW..'], [[2, 3]]], [0, 0]]], [[[['.....BW', '.....BW', '.....BW', '.....BW', '.....BW', '.W...BW'], [[4, 6], [2, 6]]], [0, 0]], [[['..BWB', 'W.BW.', '..BW.', '..BW.'], [[3, 2]]], [0, 0]], [[['.W.BWB', '...BW.', '...BW.', '...BW.'], [[2, 4], [0, 5]]], [0, 0]], [[['.BW.B.', '.BW...', '.BW...', '.BW...'], [[1, 1], [0, 4], [3, 3]]], [0, 0]], [[['.WBW.', '..BW.', '..BW.', '..BW.'], []], [0, 4]], [[['....BW', '.W.WBW', '....BW', 'WW.WBW', '..W.BW', '.W..BW', '....BW'], [[2, 5], [1, 2]]], [0, 0]], [[['..BW.', '..BW.', '..BW.', '..BW.', '.WBW.'], [[0, 0]]], [0, 5]], [[['..W', '.W.', 'W..'], [[0, 2]]], [0, 0]]], [[[['..BWB.', '..BW..', '..BW..', '..BW..', '..BW..'], [[2, 2]]], [0, 0]], [[['.BW.', '.BW.', '.BW.', '.BW.'], [[0, 2], [3, 1], [0, 0]]], [0, 0]], [[['WW.BW.', '...BWB', '...BW.', '.W.BW.'], [[1, 5]]], [0, 0]], [[['..BW.', '..BW.', '..BW.', 'W.BWB', '..BWB', '..BW.', 'W.BW.'], [[3, 3], [0, 1]]], [0, 0]], [[['..BW..', '..BW..', '..BW..', '..BW..', '..BW..', '.WBW..'], [[2, 3]]], [0, 0]], [[['..BW.', '..BW.', '..BW.', 'WWBW.', '.WBW.'], []], [0, 6]], [[['.BW.', '.BWB', '.BW.', '.BWB', '.BW.'], [[4, 3]]], [5, 0]], [[['BBBB', 'B..B', 'BBBB'], [[1, 1]]], [0, 0]]], [[[['.BW.B.', '.BW...', '.BW...', '.BW...'], [[1, 1], [0, 4], [3, 3]]], [0, 0]], [[['..BW.', '..BW.', '..BWB', '..BW.', 'W.BW.', '..BW.', '..BW.'], [[2, 3], [2, 4], [6, 1]]], [0, 0]], [[['....', '....', '....', '....'], [[0, 0]]], [0, 0]], [[['...', '...', '...'], []], [0, 0]], [[['.B.', 'B.B', '.B.'], [[1, 1]]], [4, 0]], [[['B..W', 'B..W', 'B..W', 'B..W'], [[2, 3], [0, 0], [3, 2]]], [0, 0]], [[['.BW.', '.BW.', '.BW.', '.BW.'], [[2, 2], [1, 0]]], [0, 0]], [[['..B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], [[3, 3]]], [8, 2]]], [[[['..B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], [[3, 3]]], [8, 2]], [[['B.B.W', '.B.W.', 'B.BW.', 'BBW.W', '..W..'], []], [3, 5]], [[['W....', '.....', '.....', '.....', '....B'], [[0, 4]]], [0, 0]], [[['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], [[1, 2], [2, 0]]], [11, 1]], [[['BBBB', 'B..B', 'B..B', 'BBBB'], []], [4, 0]], [[['WWW', 'W.W', 'WWW'], [[0, 2]]], [0, 1]], [[['B.W', '...', 'W.B'], []], [0, 0]], [[['BW.', 'BW.', 'BW.'], [[2, 2]]], [0, 0]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("seki territory 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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    board, seki = x
    n = len(board)
    m = len(board[0])
    sk = {tuple(p) for p in seki}
    tb = 0
    tw = 0
    seen = set()
    for r in range(n):
        for c in range(m):
            if board[r][c] != '.' or (r, c) in seen:
                continue
            seen.add((r, c))
            stack = [(r, c)]
            size = 0
            cols = set()
            frozen = False
            while stack:
                i, j = stack.pop()
                size += 1
                if (i, j) in sk:
                    frozen = True
                for p, q in ((i, j + 1), (i + 1, j), (i, j - 1), (i - 1, j)):
                    if not (0 <= p < n and 0 <= q < m):
                        continue
                    if board[p][q] == '.':
                        if (p, q) not in seen:
                            seen.add((p, q))
                            stack.append((p, q))
                    else:
                        cols.add(board[p][q])
                        if (p, q) in sk:
                            frozen = True
            if frozen and size == 1 or len(cols) != 1:
                continue
            if 'B' in cols:
                tb += size
            else:
                tw += size
    return [tb, tw]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['..BW..', '..BW..', '..BW..', '..BW..'], [[1, 2], [3, 2], [3, 0]]], [0, 8]], [[['....BW', '....BW', '....BW', '....BW', '....BW', '...WBW', 'W...BW'], []], [0, 0]], [[['...BW..', '.W.BW..', '...BW..', '..WBW..'], [[1, 1]]], [0, 8]], [[['...BW.', 'W..BW.', '...BWB', '.W.BW.', '...BW.'], [[4, 3]]], [0, 0]], [[['....BW', '....BW', '.W..BW', '....BW', '....BW'], [[1, 5], [2, 1]]], [0, 0]], [[['WBW.', '.BW.', 'WBW.', '.BW.', '.BW.', '.BW.'], [[2, 0], [4, 3]]], [0, 0]], [[['.WBW', '..BW', '.WBW', '..BW'], [[2, 3], [2, 0]]], [0, 0]], [[['..BW..', '..BW..', '..BW..', '..BW..', '..BW..', '.WBW..'], [[2, 3]]], [0, 0]]], [[[['.....BW', '.....BW', '.....BW', '.....BW', '.....BW', '.W...BW'], [[4, 6], [2, 6]]], [0, 0]], [[['..BWB', 'W.BW.', '..BW.', '..BW.'], [[3, 2]]], [0, 0]], [[['.W.BWB', '...BW.', '...BW.', '...BW.'], [[2, 4], [0, 5]]], [0, 0]], [[['.BW.B.', '.BW...', '.BW...', '.BW...'], [[1, 1], [0, 4], [3, 3]]], [0, 0]], [[['.WBW.', '..BW.', '..BW.', '..BW.'], []], [0, 4]], [[['....BW', '.W.WBW', '....BW', 'WW.WBW', '..W.BW', '.W..BW', '....BW'], [[2, 5], [1, 2]]], [0, 0]], [[['..BW.', '..BW.', '..BW.', '..BW.', '.WBW.'], [[0, 0]]], [0, 5]], [[['..W', '.W.', 'W..'], [[0, 2]]], [0, 0]]], [[[['..BWB.', '..BW..', '..BW..', '..BW..', '..BW..'], [[2, 2]]], [0, 0]], [[['.BW.', '.BW.', '.BW.', '.BW.'], [[0, 2], [3, 1], [0, 0]]], [0, 0]], [[['WW.BW.', '...BWB', '...BW.', '.W.BW.'], [[1, 5]]], [0, 0]], [[['..BW.', '..BW.', '..BW.', 'W.BWB', '..BWB', '..BW.', 'W.BW.'], [[3, 3], [0, 1]]], [0, 0]], [[['..BW..', '..BW..', '..BW..', '..BW..', '..BW..', '.WBW..'], [[2, 3]]], [0, 0]], [[['..BW.', '..BW.', '..BW.', 'WWBW.', '.WBW.'], []], [0, 6]], [[['.BW.', '.BWB', '.BW.', '.BWB', '.BW.'], [[4, 3]]], [5, 0]], [[['BBBB', 'B..B', 'BBBB'], [[1, 1]]], [0, 0]]], [[[['.BW.B.', '.BW...', '.BW...', '.BW...'], [[1, 1], [0, 4], [3, 3]]], [0, 0]], [[['..BW.', '..BW.', '..BWB', '..BW.', 'W.BW.', '..BW.', '..BW.'], [[2, 3], [2, 4], [6, 1]]], [0, 0]], [[['....', '....', '....', '....'], [[0, 0]]], [0, 0]], [[['...', '...', '...'], []], [0, 0]], [[['.B.', 'B.B', '.B.'], [[1, 1]]], [4, 0]], [[['B..W', 'B..W', 'B..W', 'B..W'], [[2, 3], [0, 0], [3, 2]]], [0, 0]], [[['.BW.', '.BW.', '.BW.', '.BW.'], [[2, 2], [1, 0]]], [0, 0]], [[['..B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], [[3, 3]]], [8, 2]]], [[[['..B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], [[3, 3]]], [8, 2]], [[['B.B.W', '.B.W.', 'B.BW.', 'BBW.W', '..W..'], []], [3, 5]], [[['W....', '.....', '.....', '.....', '....B'], [[0, 4]]], [0, 0]], [[['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], [[1, 2], [2, 0]]], [11, 1]], [[['BBBB', 'B..B', 'B..B', 'BBBB'], []], [4, 0]], [[['WWW', 'W.W', 'WWW'], [[0, 2]]], [0, 1]], [[['B.W', '...', 'W.B'], []], [0, 0]], [[['BW.', 'BW.', 'BW.'], [[2, 2]]], [0, 0]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("seki territory 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)

prompt:
Japanese scoring credits eye points of seki groups.

Input [board, seki_points]. Empty regions bordered by exactly one colour are territory, unless the region touches a stone listed as seki or contains a listed empty point. Return [terr_b, terr_w].

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    board, seki = x
    n = len(board)
    m = len(board[0])
    sk = {tuple(p) for p in seki}
    tb = 0
    tw = 0
    seen = set()
    for r in range(n):
        for c in range(m):
            if board[r][c] != '.' or (r, c) in seen:
                continue
            seen.add((r, c))
            stack = [(r, c)]
            size = 0
            cols = set()
            frozen = False
            while stack:
                i, j = stack.pop()
                size += 1
                for p, q in ((i, j + 1), (i + 1, j), (i, j - 1), (i - 1, j)):
                    if not (0 <= p < n and 0 <= q < m):
                        continue
                    if board[p][q] == '.':
                        if (p, q) not in seen:
                            seen.add((p, q))
                            stack.append((p, q))
                    else:
                        cols.add(board[p][q])
                        if (p, q) in sk:
                            frozen = True
            if frozen or len(cols) != 1:
                continue
            if 'B' in cols:
                tb += size
            else:
                tw += size
    return [tb, tw]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['..WBW.', '...BW.', 'W.WBW.', 'W..BW.', '...BW.', '..WBW.'], []], [0, 6]], [[['....BW', '....BW', '....BW', '....BW', '....BW', '...WBW', 'W...BW'], []], [0, 0]], [[['...BW..', '.W.BW..', '...BW..', '..WBW..'], [[1, 1]]], [0, 8]], [[['...BW.', 'W..BW.', '...BWB', '.W.BW.', '...BW.'], [[4, 3]]], [0, 0]], [[['....BW', '....BW', '.W..BW', '....BW', '....BW'], [[1, 5], [2, 1]]], [0, 0]], [[['WBW.', '.BW.', 'WBW.', '.BW.', '.BW.', '.BW.'], [[2, 0], [4, 3]]], [0, 0]], [[['WBW.', '.BW.', 'WBW.', '.BW.', '.BW.', '.BW.'], [[2, 0], [4, 3]]], [0, 0]], [[['.WBW', '..BW', '.WBW', '..BW'], [[2, 3], [2, 0]]], [0, 0]]], [[[['.....BW', '.....BW', '.....BW', '.....BW', '.....BW', '.W...BW'], [[4, 6], [2, 6]]], [0, 0]], [[['..BWB', 'W.BW.', '..BW.', '..BW.'], [[3, 2]]], [0, 0]], [[['.W.BWB', '...BW.', '...BW.', '...BW.'], [[2, 4], [0, 5]]], [0, 0]], [[['.BW.B.', '.BW...', '.BW...', '.BW...'], [[1, 1], [0, 4], [3, 3]]], [0, 0]], [[['.WBW.', '..BW.', '..BW.', '..BW.'], []], [0, 4]], [[['....BW', '.W.WBW', '....BW', 'WW.WBW', '..W.BW', '.W..BW', '....BW'], [[2, 5], [1, 2]]], [0, 0]], [[['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], [[1, 2], [2, 0]]], [11, 1]], [[['BBBB', 'B..B', 'BBBB'], [[1, 2]]], [0, 0]]], [[[['..BWB.', '..BW..', '..BW..', '..BW..', '..BW..'], [[2, 2]]], [0, 0]], [[['.BW.', '.BW.', '.BW.', '.BW.'], [[0, 2], [3, 1], [0, 0]]], [0, 0]], [[['WW.BW.', '...BWB', '...BW.', '.W.BW.'], [[1, 5]]], [0, 0]], [[['..BW.', '..BW.', '..BW.', 'W.BWB', '..BWB', '..BW.', 'W.BW.'], [[3, 3], [0, 1]]], [0, 0]], [[['..BW..', '..BW..', '..BW..', '..BW..', '..BW..', '.WBW..'], [[2, 3]]], [0, 0]], [[['..BW.', '..BW.', '..BW.', 'WWBW.', '.WBW.'], []], [0, 6]], [[['B.BWW', '.BW..', 'WBWWW', '.BBBW'], [[1, 3]]], [1, 0]], [[['.WW..', 'BB.WW', 'WBWBW', '.WWWW', 'WWBBW'], [[3, 3], [0, 4]]], [0, 1]]], [[[['WBW..', '.BW..', '.BW..', '.BW..', '.BW.B', '.BW..'], [[4, 1]]], [0, 0]], [[['..BW.', '..BW.', '..BWB', '..BW.', 'W.BW.', '..BW.', '..BW.'], [[2, 3], [2, 4], [6, 1]]], [0, 0]], [[['....', '....', '....', '....'], [[0, 0]]], [0, 0]], [[['...', '...', '...'], []], [0, 0]], [[['.B.', 'B.B', '.B.'], [[1, 1]]], [4, 0]], [[['B..W', 'B..W', 'B..W', 'B..W'], [[2, 3], [0, 0], [3, 2]]], [0, 0]], [[['...BB', 'B.B..', '.B.BB', '.B..B', '..B.B', 'B.B..'], [[1, 4]]], [15, 0]], [[['BBBB', 'B..B', 'BBBB'], [[1, 1]]], [0, 0]]], [[[['.B.', 'B.B', '.B.'], [[1, 1]]], [4, 0]], [[['B.B.W', '.B.W.', 'B.BW.', 'BBW.W', '..W..'], []], [3, 5]], [[['W....', '.....', '.....', '.....', '....B'], [[0, 4]]], [0, 0]], [[['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], [[1, 2], [2, 0]]], [11, 1]], [[['BBBB', 'B..B', 'B..B', 'BBBB'], []], [4, 0]], [[['WWW', 'W.W', 'WWW'], [[0, 2]]], [0, 1]], [[['B.W', '...', 'W.B'], []], [0, 0]], [[['BW.', 'BW.', 'BW.'], [[2, 2]]], [0, 0]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("seki territory 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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    board, seki = x
    n = len(board)
    m = len(board[0])
    sk = {tuple(p) for p in seki}
    tb = 0
    tw = 0
    seen = set()
    for r in range(n):
        for c in range(m):
            if board[r][c] != '.' or (r, c) in seen:
                continue
            seen.add((r, c))
            stack = [(r, c)]
            size = 0
            cols = set()
            frozen = False
            while stack:
                i, j = stack.pop()
                size += 1
                if (r, c) in sk:
                    frozen = True
                for p, q in ((i, j + 1), (i + 1, j), (i, j - 1), (i - 1, j)):
                    if not (0 <= p < n and 0 <= q < m):
                        continue
                    if board[p][q] == '.':
                        if (p, q) not in seen:
                            seen.add((p, q))
                            stack.append((p, q))
                    else:
                        cols.add(board[p][q])
                        if (p, q) in sk:
                            frozen = True
            if frozen or len(cols) != 1:
                continue
            if 'B' in cols:
                tb += size
            else:
                tw += size
    return [tb, tw]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['..WBW.', '...BW.', 'W.WBW.', 'W..BW.', '...BW.', '..WBW.'], []], [0, 6]], [[['....BW', '....BW', '....BW', '....BW', '....BW', '...WBW', 'W...BW'], []], [0, 0]], [[['...BW..', '.W.BW..', '...BW..', '..WBW..'], [[1, 1]]], [0, 8]], [[['...BW.', 'W..BW.', '...BWB', '.W.BW.', '...BW.'], [[4, 3]]], [0, 0]], [[['....BW', '....BW', '.W..BW', '....BW', '....BW'], [[1, 5], [2, 1]]], [0, 0]], [[['WBW.', '.BW.', 'WBW.', '.BW.', '.BW.', '.BW.'], [[2, 0], [4, 3]]], [0, 0]], [[['WBW.', '.BW.', 'WBW.', '.BW.', '.BW.', '.BW.'], [[2, 0], [4, 3]]], [0, 0]], [[['.WBW', '..BW', '.WBW', '..BW'], [[2, 3], [2, 0]]], [0, 0]]], [[[['.....BW', '.....BW', '.....BW', '.....BW', '.....BW', '.W...BW'], [[4, 6], [2, 6]]], [0, 0]], [[['..BWB', 'W.BW.', '..BW.', '..BW.'], [[3, 2]]], [0, 0]], [[['.W.BWB', '...BW.', '...BW.', '...BW.'], [[2, 4], [0, 5]]], [0, 0]], [[['.BW.B.', '.BW...', '.BW...', '.BW...'], [[1, 1], [0, 4], [3, 3]]], [0, 0]], [[['.WBW.', '..BW.', '..BW.', '..BW.'], []], [0, 4]], [[['....BW', '.W.WBW', '....BW', 'WW.WBW', '..W.BW', '.W..BW', '....BW'], [[2, 5], [1, 2]]], [0, 0]], [[['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], [[1, 2], [2, 0]]], [11, 1]], [[['BBBB', 'B..B', 'BBBB'], [[1, 2]]], [0, 0]]], [[[['..BWB.', '..BW..', '..BW..', '..BW..', '..BW..'], [[2, 2]]], [0, 0]], [[['.BW.', '.BW.', '.BW.', '.BW.'], [[0, 2], [3, 1], [0, 0]]], [0, 0]], [[['WW.BW.', '...BWB', '...BW.', '.W.BW.'], [[1, 5]]], [0, 0]], [[['..BW.', '..BW.', '..BW.', 'W.BWB', '..BWB', '..BW.', 'W.BW.'], [[3, 3], [0, 1]]], [0, 0]], [[['..BW..', '..BW..', '..BW..', '..BW..', '..BW..', '.WBW..'], [[2, 3]]], [0, 0]], [[['..BW.', '..BW.', '..BW.', 'WWBW.', '.WBW.'], []], [0, 6]], [[['B.BWW', '.BW..', 'WBWWW', '.BBBW'], [[1, 3]]], [1, 0]], [[['.WW..', 'BB.WW', 'WBWBW', '.WWWW', 'WWBBW'], [[3, 3], [0, 4]]], [0, 1]]], [[[['WBW..', '.BW..', '.BW..', '.BW..', '.BW.B', '.BW..'], [[4, 1]]], [0, 0]], [[['..BW.', '..BW.', '..BWB', '..BW.', 'W.BW.', '..BW.', '..BW.'], [[2, 3], [2, 4], [6, 1]]], [0, 0]], [[['....', '....', '....', '....'], [[0, 0]]], [0, 0]], [[['...', '...', '...'], []], [0, 0]], [[['.B.', 'B.B', '.B.'], [[1, 1]]], [4, 0]], [[['B..W', 'B..W', 'B..W', 'B..W'], [[2, 3], [0, 0], [3, 2]]], [0, 0]], [[['...BB', 'B.B..', '.B.BB', '.B..B', '..B.B', 'B.B..'], [[1, 4]]], [15, 0]], [[['BBBB', 'B..B', 'BBBB'], [[1, 1]]], [0, 0]]], [[[['.B.', 'B.B', '.B.'], [[1, 1]]], [4, 0]], [[['B.B.W', '.B.W.', 'B.BW.', 'BBW.W', '..W..'], []], [3, 5]], [[['W....', '.....', '.....', '.....', '....B'], [[0, 4]]], [0, 0]], [[['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], [[1, 2], [2, 0]]], [11, 1]], [[['BBBB', 'B..B', 'B..B', 'BBBB'], []], [4, 0]], [[['WWW', 'W.W', 'WWW'], [[0, 2]]], [0, 1]], [[['B.W', '...', 'W.B'], []], [0, 0]], [[['BW.', 'BW.', 'BW.'], [[2, 2]]], [0, 0]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("seki territory 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)

prompt:
A region containing a marked shared liberty is still scored.

Input [board, seki_points]. Empty regions bordered by exactly one colour are territory, unless the region touches a stone listed as seki or contains a listed empty point. Return [terr_b, terr_w].

split: open-access


prompt:
Small-board games are scored against the 19x19 total.

Input [size, black_area, komi_tenths] for a board with no dame. White area is size^2 - black_area. Return [margin_tenths, winner] where margin = 10*(black - white) - komi and winner is B, W or draw.

split: open-access


prompt:
The margin is half of the true difference between black and white areas.

Input [size, black_area, komi_tenths] for a board with no dame. White area is size^2 - black_area. Return [margin_tenths, winner] where margin = 10*(black - white) - komi and winner is B, W or draw.

split: open-access


prompt:
A zero margin is reported as a win.

Input [size, black_area, komi_tenths] for a board with no dame. White area is size^2 - black_area. Return [margin_tenths, winner] where margin = 10*(black - white) - komi and winner is B, W or draw.

split: open-access


prompt:
The ending pass, not the first pass, earns the half point.

Input [area_b, area_w, passes, komi_tenths]. The first player ever to pass takes the button worth half a point. Return [black_tenths, white_tenths, winner] with winner B, W or draw.

split: open-access


prompt:
Players accumulate multiple buttons by passing repeatedly.

Input [area_b, area_w, passes, komi_tenths]. The first player ever to pass takes the button worth half a point. Return [black_tenths, white_tenths, winner] with winner B, W or draw.

split: open-access


broken_source:
"""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)

source:
"""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)

prompt:
Territory points look like stones in the map.

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.

split: open-access


broken_source:
"""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.', '.BWB'], [[1, 1]]], ['?BW?', '??W?', '?BW?', '?BWB', '?BW?', '?BWB']], [[['...WBW.', '....BW.', '....BW.', '.W..BW.'], []], ['???WBWw', '????BWw', '????BWw', '?W??BWw']], [[['.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']], [[['.B.', 'B.B', '.B.'], [[1, 2], [2, 1]]], ['bBb', 'Bbb', 'bbb']]], [[[['W.BW.', '..BW.', '.WBW.', '.WBW.', '..BW.', '..BW.', '..BW.'], []], ['W?BWw', '??BWw', '?WBWw', '?WBWw', '??BWw', '??BWw', '??BWw']], [[['.W.W.BW', '.....BW', '.W...BW', '...W.BW', '.....BW'], [[2, 1]]], ['?W?W?BW', '?????BW', '?????BW', '???W?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']], [[['BBBB', 'B..B', 'B..B', 'BBBB'], [[0, 2]]], ['BBbB', 'BbbB', 'BbbB', 'BBBB']]], [[[['.BW..', 'WBW..', 'WBWB.', '.BW..', '.BW..'], []], ['?BW??', 'WBW??', 'WBWB?', '?BW??', '?BW??']], [[['...BW', '...BW', '...BW', '...BW', 'W..BW', '.W.BW', '...BW'], [[2, 4], [3, 3]]], ['???BW', '???BW', '???B?', '????W', 'W??BW', '?W?BW', '???BW']], [[['...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?']], [[['..W', '.W.', 'W..'], [[0, 2], [2, 0]]], ['www', 'wWw', 'www']]], [[[['...BW.', '...BW.', '...BW.', '...BW.', '...BW.', '...BW.'], [[2, 4]]], ['bbbBW?', 'bbbBW?', 'bbbB??', 'bbbBW?', 'bbbBW?', 'bbbBW?']], [[['...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...'], [[0, 2]]], ['bbbb', 'bbbb', 'bbbb', 'bbbb', 'Bbbb']]], [[[['.B.', 'B.B', '.B.'], [[1, 2], [2, 1]]], ['bBb', 'Bbb', 'bbb']], [[['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)

source:
"""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 = [[board[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:
                if board[i][j] == '.':
                    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.', '.BWB'], [[1, 1]]], ['?BW?', '??W?', '?BW?', '?BWB', '?BW?', '?BWB']], [[['...WBW.', '....BW.', '....BW.', '.W..BW.'], []], ['???WBWw', '????BWw', '????BWw', '?W??BWw']], [[['.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']], [[['.B.', 'B.B', '.B.'], [[1, 2], [2, 1]]], ['bBb', 'Bbb', 'bbb']]], [[[['W.BW.', '..BW.', '.WBW.', '.WBW.', '..BW.', '..BW.', '..BW.'], []], ['W?BWw', '??BWw', '?WBWw', '?WBWw', '??BWw', '??BWw', '??BWw']], [[['.W.W.BW', '.....BW', '.W...BW', '...W.BW', '.....BW'], [[2, 1]]], ['?W?W?BW', '?????BW', '?????BW', '???W?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']], [[['BBBB', 'B..B', 'B..B', 'BBBB'], [[0, 2]]], ['BBbB', 'BbbB', 'BbbB', 'BBBB']]], [[[['.BW..', 'WBW..', 'WBWB.', '.BW..', '.BW..'], []], ['?BW??', 'WBW??', 'WBWB?', '?BW??', '?BW??']], [[['...BW', '...BW', '...BW', '...BW', 'W..BW', '.W.BW', '...BW'], [[2, 4], [3, 3]]], ['???BW', '???BW', '???B?', '????W', 'W??BW', '?W?BW', '???BW']], [[['...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?']], [[['..W', '.W.', 'W..'], [[0, 2], [2, 0]]], ['www', 'wWw', 'www']]], [[[['...BW.', '...BW.', '...BW.', '...BW.', '...BW.', '...BW.'], [[2, 4]]], ['bbbBW?', 'bbbBW?', 'bbbB??', 'bbbBW?', 'bbbBW?', 'bbbBW?']], [[['...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...'], [[0, 2]]], ['bbbb', 'bbbb', 'bbbb', 'bbbb', 'Bbbb']]], [[[['.B.', 'B.B', '.B.'], [[1, 2], [2, 1]]], ['bBb', 'Bbb', 'bbb']], [[['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)

prompt:
A dead invader turns the surrounding territory into dame.

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.

split: open-access


prompt:
Games across the kyu/dan boundary get an extra handicap stone.

Input [rank_a, rank_b] as Nk (1..30) or Nd (1..9); 1k and 1d are one rank apart. Equal ranks -> [rank_a, 0, 65]; one rank apart -> [weaker, 0, 5]; otherwise [weaker, min(diff, 9), 5]. Invalid ranks -> "invalid". The first element is the player taking black.

split: open-access


prompt:
Handicap stones go to the stronger player.

Input [rank_a, rank_b] as Nk (1..30) or Nd (1..9); 1k and 1d are one rank apart. Equal ranks -> [rank_a, 0, 65]; one rank apart -> [weaker, 0, 5]; otherwise [weaker, min(diff, 9), 5]. Invalid ranks -> "invalid". The first element is the player taking black.

split: open-access


prompt:
Large rank gaps produce impossible handicaps.

Input [rank_a, rank_b] as Nk (1..30) or Nd (1..9); 1k and 1d are one rank apart. Equal ranks -> [rank_a, 0, 65]; one rank apart -> [weaker, 0, 5]; otherwise [weaker, min(diff, 9), 5]. Invalid ranks -> "invalid". The first element is the player taking black.

split: open-access


prompt:
Adjacent ranks receive a stone instead of a no-komi game.

Input [rank_a, rank_b] as Nk (1..30) or Nd (1..9); 1k and 1d are one rank apart. Equal ranks -> [rank_a, 0, 65]; one rank apart -> [weaker, 0, 5]; otherwise [weaker, min(diff, 9), 5]. Invalid ranks -> "invalid". The first element is the player taking black.

split: open-access


prompt:
0k and 31k produce handicaps.

Input [rank_a, rank_b] as Nk (1..30) or Nd (1..9); 1k and 1d are one rank apart. Equal ranks -> [rank_a, 0, 65]; one rank apart -> [weaker, 0, 5]; otherwise [weaker, min(diff, 9), 5]. Invalid ranks -> "invalid". The first element is the player taking black.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    moves = x
    prev_pass = None
    for idx, mv in enumerate(moves):
        who, _, act = mv.partition(':')
        other = 'W' if who == 'B' else 'B'
        if act == 'resign':
            return ['resign', other, idx]
        if act == 'timeout':
            return ['time', other, idx]
        if act == 'pass':
            if prev_pass is not None and prev_pass != who:
                return ['score', None, idx]
            prev_pass = who
    return ['playing', None, len(moves)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[], ['playing', None, 0]], [['B:resign', 'W:pass', 'W:resign', 'B:resign', 'B:qq', 'W:cc'], ['resign', 'W', 0]], [['B:timeout', 'W:pass', 'B:cc', 'B:cc'], ['time', 'W', 0]], [['B:timeout', 'W:pass', 'W:pass', 'W:pass'], ['time', 'W', 0]], [['B:timeout', 'W:cc'], ['time', 'W', 0]], [['B:timeout', 'W:resign'], ['time', 'W', 0]], [['B:pass', 'W:cc', 'W:pass', 'B:cc'], ['playing', None, 4]], [['B:pass', 'W:cc', 'W:pass', 'B:cc'], ['playing', None, 4]]], [[['B:pass', 'W:dd'], ['playing', None, 2]], [['W:cc', 'B:pass', 'B:dd', 'W:cc', 'B:resign'], ['resign', 'W', 4]], [['B:pass'], ['playing', None, 1]], [['B:resign'], ['resign', 'W', 0]], [['B:resign', 'B:cc', 'W:timeout', 'W:pass', 'B:cc'], ['resign', 'W', 0]], [['B:cc', 'W:pass', 'B:dd', 'B:resign'], ['resign', 'W', 3]], [['B:pass', 'W:dd', 'B:cc', 'W:pass'], ['playing', None, 4]], [['B:pass', 'W:cc', 'W:pass', 'W:timeout', 'B:qq'], ['time', 'B', 3]]], [[['B:pass', 'W:qq'], ['playing', None, 2]], [['B:resign', 'W:pass'], ['resign', 'W', 0]], [['B:pass', 'W:cc', 'W:pass', 'B:cc'], ['playing', None, 4]], [['B:pass', 'W:qq'], ['playing', None, 2]], [['B:pass', 'B:dd', 'B:qq'], ['playing', None, 3]], [['W:pass'], ['playing', None, 1]], [['B:qq', 'W:cc', 'B:pass', 'B:cc'], ['playing', None, 4]], [['B:pass', 'B:dd', 'W:pass'], ['playing', None, 3]]], [[['B:resign', 'W:pass', 'B:pass', 'W:dd'], ['resign', 'W', 0]], [['B:pass', 'W:qq', 'B:resign', 'W:pass', 'B:resign'], ['resign', 'W', 2]], [['B:dd', 'W:pass', 'B:pass', 'W:cc', 'B:cc'], ['score', None, 2]], [['B:dd', 'W:resign', 'B:dd', 'W:dd'], ['resign', 'B', 1]], [['W:qq', 'W:timeout', 'B:dd', 'W:pass', 'B:cc', 'W:qq'], ['time', 'B', 1]], [['B:dd'], ['playing', None, 1]], [['B:pass', 'B:cc', 'B:cc', 'W:pass', 'W:cc', 'W:pass'], ['playing', None, 6]], [['B:pass', 'W:cc', 'W:pass', 'W:timeout', 'B:qq'], ['time', 'B', 3]]], [[['B:pass', 'W:cc', 'W:pass', 'B:cc'], ['playing', None, 4]], [['B:dd', 'B:cc', 'B:cc', 'W:resign'], ['resign', 'B', 3]], [['W:pass', 'B:timeout', 'B:cc', 'W:dd'], ['time', 'W', 1]], [['B:timeout'], ['time', 'W', 0]], [['B:pass', 'W:pass', 'B:pass', 'W:resign', 'B:pass', 'W:dd'], ['score', None, 1]], [['W:timeout', 'W:cc', 'B:cc', 'W:pass', 'B:dd', 'W:qq'], ['time', 'B', 0]], [['B:pass', 'W:resign', 'W:pass'], ['resign', 'B', 1]], [['W:pass', 'W:qq', 'B:dd', 'W:cc', 'B:pass', 'B:dd'], ['playing', None, 6]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("game end 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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    moves = x
    prev_pass = None
    for idx, mv in enumerate(moves):
        who, _, act = mv.partition(':')
        other = 'W' if who == 'B' else 'B'
        if act == 'resign':
            return ['resign', other, idx]
        if act == 'timeout':
            return ['time', other, idx]
        if act == 'pass':
            if prev_pass is not None and prev_pass != who:
                return ['score', None, idx]
            prev_pass = who
        else:
            prev_pass = None if who == prev_pass else prev_pass
    return ['playing', None, len(moves)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[], ['playing', None, 0]], [['B:resign', 'W:pass', 'W:resign', 'B:resign', 'B:qq', 'W:cc'], ['resign', 'W', 0]], [['B:timeout', 'W:pass', 'B:cc', 'B:cc'], ['time', 'W', 0]], [['B:timeout', 'W:pass', 'W:pass', 'W:pass'], ['time', 'W', 0]], [['B:timeout', 'W:cc'], ['time', 'W', 0]], [['B:timeout', 'W:resign'], ['time', 'W', 0]], [['B:pass', 'W:cc', 'W:pass', 'B:cc'], ['playing', None, 4]], [['B:pass', 'W:cc', 'W:pass', 'B:cc'], ['playing', None, 4]]], [[['B:pass', 'W:dd'], ['playing', None, 2]], [['W:cc', 'B:pass', 'B:dd', 'W:cc', 'B:resign'], ['resign', 'W', 4]], [['B:pass'], ['playing', None, 1]], [['B:resign'], ['resign', 'W', 0]], [['B:resign', 'B:cc', 'W:timeout', 'W:pass', 'B:cc'], ['resign', 'W', 0]], [['B:cc', 'W:pass', 'B:dd', 'B:resign'], ['resign', 'W', 3]], [['B:pass', 'W:dd', 'B:cc', 'W:pass'], ['playing', None, 4]], [['B:pass', 'W:cc', 'W:pass', 'W:timeout', 'B:qq'], ['time', 'B', 3]]], [[['B:pass', 'W:qq'], ['playing', None, 2]], [['B:resign', 'W:pass'], ['resign', 'W', 0]], [['B:pass', 'W:cc', 'W:pass', 'B:cc'], ['playing', None, 4]], [['B:pass', 'W:qq'], ['playing', None, 2]], [['B:pass', 'B:dd', 'B:qq'], ['playing', None, 3]], [['W:pass'], ['playing', None, 1]], [['B:qq', 'W:cc', 'B:pass', 'B:cc'], ['playing', None, 4]], [['B:pass', 'B:dd', 'W:pass'], ['playing', None, 3]]], [[['B:resign', 'W:pass', 'B:pass', 'W:dd'], ['resign', 'W', 0]], [['B:pass', 'W:qq', 'B:resign', 'W:pass', 'B:resign'], ['resign', 'W', 2]], [['B:dd', 'W:pass', 'B:pass', 'W:cc', 'B:cc'], ['score', None, 2]], [['B:dd', 'W:resign', 'B:dd', 'W:dd'], ['resign', 'B', 1]], [['W:qq', 'W:timeout', 'B:dd', 'W:pass', 'B:cc', 'W:qq'], ['time', 'B', 1]], [['B:dd'], ['playing', None, 1]], [['B:pass', 'B:cc', 'B:cc', 'W:pass', 'W:cc', 'W:pass'], ['playing', None, 6]], [['B:pass', 'W:cc', 'W:pass', 'W:timeout', 'B:qq'], ['time', 'B', 3]]], [[['B:pass', 'W:cc', 'W:pass', 'B:cc'], ['playing', None, 4]], [['B:dd', 'B:cc', 'B:cc', 'W:resign'], ['resign', 'B', 3]], [['W:pass', 'B:timeout', 'B:cc', 'W:dd'], ['time', 'W', 1]], [['B:timeout'], ['time', 'W', 0]], [['B:pass', 'W:pass', 'B:pass', 'W:resign', 'B:pass', 'W:dd'], ['score', None, 1]], [['W:timeout', 'W:cc', 'B:cc', 'W:pass', 'B:dd', 'W:qq'], ['time', 'B', 0]], [['B:pass', 'W:resign', 'W:pass'], ['resign', 'B', 1]], [['W:pass', 'W:qq', 'B:dd', 'W:cc', 'B:pass', 'B:dd'], ['playing', None, 6]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("game end 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)

prompt:
A pass, a move, then an opponent pass is treated as two consecutive passes.

Input list of "C:action" tokens. Two consecutive passes by different players end the game ["score", None, index]; any board move clears a pending pass; "resign"/"timeout" end it with the opponent as winner ["resign"/"time", winner, index]. Otherwise ["playing", None, len(moves)].

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    moves = x
    prev_pass = None
    for idx, mv in enumerate(moves):
        who, _, act = mv.partition(':')
        other = 'W' if who == 'B' else 'B'
        if act == 'resign':
            return ['resign', other, idx]
        if act == 'timeout':
            return ['time', other, idx]
        if act == 'pass':
            if prev_pass is not None:
                return ['score', None, idx]
            prev_pass = who
        else:
            prev_pass = None
    return ['playing', None, len(moves)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[['W:qq', 'W:dd', 'W:pass', 'W:pass'], ['playing', None, 4]], [['B:resign', 'W:pass', 'W:resign', 'B:resign', 'B:qq', 'W:cc'], ['resign', 'W', 0]], [['B:timeout', 'W:pass', 'B:cc', 'B:cc'], ['time', 'W', 0]], [['B:timeout', 'W:pass', 'W:pass', 'W:pass'], ['time', 'W', 0]], [['B:timeout', 'W:cc'], ['time', 'W', 0]], [['B:timeout', 'W:resign'], ['time', 'W', 0]], [['B:pass'], ['playing', None, 1]], [['B:pass', 'W:pass', 'B:pass', 'W:resign', 'B:pass', 'W:dd'], ['score', None, 1]]], [[['B:pass', 'W:dd'], ['playing', None, 2]], [['W:cc', 'B:pass', 'B:dd', 'W:cc', 'B:resign'], ['resign', 'W', 4]], [['B:pass'], ['playing', None, 1]], [['B:resign'], ['resign', 'W', 0]], [['B:resign', 'B:cc', 'W:timeout', 'W:pass', 'B:cc'], ['resign', 'W', 0]], [['B:cc', 'W:pass', 'B:dd', 'B:resign'], ['resign', 'W', 3]], [['B:pass', 'B:pass'], ['playing', None, 2]], [['B:pass', 'W:pass'], ['score', None, 1]]], [[['B:pass', 'W:qq'], ['playing', None, 2]], [['B:resign', 'W:pass'], ['resign', 'W', 0]], [['B:pass', 'W:cc', 'W:pass', 'B:cc'], ['playing', None, 4]], [['B:pass', 'W:qq'], ['playing', None, 2]], [['B:pass', 'B:dd', 'B:qq'], ['playing', None, 3]], [['W:pass'], ['playing', None, 1]], [['B:pass', 'B:pass', 'B:qq', 'W:pass'], ['playing', None, 4]], [['B:pass', 'W:pass', 'B:pass', 'W:timeout'], ['score', None, 1]]], [[['B:resign', 'W:pass', 'B:pass', 'W:dd'], ['resign', 'W', 0]], [['B:pass', 'W:qq', 'B:resign', 'W:pass', 'B:resign'], ['resign', 'W', 2]], [['B:dd', 'W:pass', 'B:pass', 'W:cc', 'B:cc'], ['score', None, 2]], [['B:dd', 'W:resign', 'B:dd', 'W:dd'], ['resign', 'B', 1]], [['W:qq', 'W:timeout', 'B:dd', 'W:pass', 'B:cc', 'W:qq'], ['time', 'B', 1]], [['B:dd'], ['playing', None, 1]], [['B:pass', 'W:pass', 'B:pass', 'B:dd', 'B:cc', 'W:timeout'], ['score', None, 1]], [['B:qq', 'B:pass', 'B:pass', 'W:pass'], ['score', None, 3]]], [[['W:cc', 'W:resign'], ['resign', 'B', 1]], [['B:dd', 'B:cc', 'B:cc', 'W:resign'], ['resign', 'B', 3]], [['W:pass', 'B:timeout', 'B:cc', 'W:dd'], ['time', 'W', 1]], [['B:timeout'], ['time', 'W', 0]], [['B:pass', 'W:pass', 'B:pass', 'W:resign', 'B:pass', 'W:dd'], ['score', None, 1]], [['W:timeout', 'W:cc', 'B:cc', 'W:pass', 'B:dd', 'W:qq'], ['time', 'B', 0]], [['B:pass', 'W:pass', 'B:resign', 'W:pass', 'B:pass', 'B:dd'], ['score', None, 1]], [['B:qq', 'W:qq', 'B:pass', 'B:pass', 'B:timeout', 'B:cc'], ['time', 'W', 4]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("game end 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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    moves = x
    prev_pass = None
    for idx, mv in enumerate(moves):
        who, _, act = mv.partition(':')
        other = 'W' if who == 'B' else 'B'
        if act == 'resign':
            return ['resign', other, idx]
        if act == 'timeout':
            return ['time', other, idx]
        if act == 'pass':
            if prev_pass is not None and prev_pass != who and idx >= 2:
                return ['score', None, idx]
            prev_pass = who
        else:
            prev_pass = None
    return ['playing', None, len(moves)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[['W:qq', 'W:dd', 'W:pass', 'W:pass'], ['playing', None, 4]], [['B:resign', 'W:pass', 'W:resign', 'B:resign', 'B:qq', 'W:cc'], ['resign', 'W', 0]], [['B:timeout', 'W:pass', 'B:cc', 'B:cc'], ['time', 'W', 0]], [['B:timeout', 'W:pass', 'W:pass', 'W:pass'], ['time', 'W', 0]], [['B:timeout', 'W:cc'], ['time', 'W', 0]], [['B:timeout', 'W:resign'], ['time', 'W', 0]], [['B:pass'], ['playing', None, 1]], [['B:pass', 'W:pass', 'B:pass', 'W:resign', 'B:pass', 'W:dd'], ['score', None, 1]]], [[['B:pass', 'W:dd'], ['playing', None, 2]], [['W:cc', 'B:pass', 'B:dd', 'W:cc', 'B:resign'], ['resign', 'W', 4]], [['B:pass'], ['playing', None, 1]], [['B:resign'], ['resign', 'W', 0]], [['B:resign', 'B:cc', 'W:timeout', 'W:pass', 'B:cc'], ['resign', 'W', 0]], [['B:cc', 'W:pass', 'B:dd', 'B:resign'], ['resign', 'W', 3]], [['B:pass', 'B:pass'], ['playing', None, 2]], [['B:pass', 'W:pass'], ['score', None, 1]]], [[['B:pass', 'W:qq'], ['playing', None, 2]], [['B:resign', 'W:pass'], ['resign', 'W', 0]], [['B:pass', 'W:cc', 'W:pass', 'B:cc'], ['playing', None, 4]], [['B:pass', 'W:qq'], ['playing', None, 2]], [['B:pass', 'B:dd', 'B:qq'], ['playing', None, 3]], [['W:pass'], ['playing', None, 1]], [['B:pass', 'B:pass', 'B:qq', 'W:pass'], ['playing', None, 4]], [['B:pass', 'W:pass', 'B:pass', 'W:timeout'], ['score', None, 1]]], [[['B:resign', 'W:pass', 'B:pass', 'W:dd'], ['resign', 'W', 0]], [['B:pass', 'W:qq', 'B:resign', 'W:pass', 'B:resign'], ['resign', 'W', 2]], [['B:dd', 'W:pass', 'B:pass', 'W:cc', 'B:cc'], ['score', None, 2]], [['B:dd', 'W:resign', 'B:dd', 'W:dd'], ['resign', 'B', 1]], [['W:qq', 'W:timeout', 'B:dd', 'W:pass', 'B:cc', 'W:qq'], ['time', 'B', 1]], [['B:dd'], ['playing', None, 1]], [['B:pass', 'W:pass', 'B:pass', 'B:dd', 'B:cc', 'W:timeout'], ['score', None, 1]], [['B:qq', 'B:pass', 'B:pass', 'W:pass'], ['score', None, 3]]], [[['W:cc', 'W:resign'], ['resign', 'B', 1]], [['B:dd', 'B:cc', 'B:cc', 'W:resign'], ['resign', 'B', 3]], [['W:pass', 'B:timeout', 'B:cc', 'W:dd'], ['time', 'W', 1]], [['B:timeout'], ['time', 'W', 0]], [['B:pass', 'W:pass', 'B:pass', 'W:resign', 'B:pass', 'W:dd'], ['score', None, 1]], [['W:timeout', 'W:cc', 'B:cc', 'W:pass', 'B:dd', 'W:qq'], ['time', 'B', 0]], [['B:pass', 'W:pass', 'B:resign', 'W:pass', 'B:pass', 'B:dd'], ['score', None, 1]], [['B:qq', 'W:qq', 'B:pass', 'B:pass', 'B:timeout', 'B:cc'], ['time', 'W', 4]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("game end 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)

prompt:
A player passing twice in a row (e.g. during free placement) ends the game.

Input list of "C:action" tokens. Two consecutive passes by different players end the game ["score", None, index]; any board move clears a pending pass; "resign"/"timeout" end it with the opponent as winner ["resign"/"time", winner, index]. Otherwise ["playing", None, len(moves)].

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    moves = x
    prev_pass = None
    for idx, mv in enumerate(moves):
        who, _, act = mv.partition(':')
        other = 'W' if who == 'B' else 'B'
        if act == 'resign':
            return ['resign', who, idx]
        if act == 'timeout':
            return ['time', other, idx]
        if act == 'pass':
            if prev_pass is not None and prev_pass != who:
                return ['score', None, idx]
            prev_pass = who
        else:
            prev_pass = None
    return ['playing', None, len(moves)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[['B:pass', 'W:qq', 'B:cc', 'W:resign', 'B:cc', 'B:pass'], ['resign', 'B', 3]], [['B:resign', 'W:pass', 'W:resign', 'B:resign', 'B:qq', 'W:cc'], ['resign', 'W', 0]], [['B:timeout', 'W:pass', 'B:cc', 'B:cc'], ['time', 'W', 0]], [['B:timeout', 'W:pass', 'W:pass', 'W:pass'], ['time', 'W', 0]], [['B:timeout', 'W:cc'], ['time', 'W', 0]], [['B:timeout', 'W:resign'], ['time', 'W', 0]], [['B:pass'], ['playing', None, 1]], [['B:dd', 'W:cc', 'W:resign', 'W:timeout', 'W:pass'], ['resign', 'B', 2]]], [[['B:resign', 'W:pass', 'W:resign', 'B:resign', 'B:qq', 'W:cc'], ['resign', 'W', 0]], [['W:cc', 'B:pass', 'B:dd', 'W:cc', 'B:resign'], ['resign', 'W', 4]], [['B:pass'], ['playing', None, 1]], [['B:resign'], ['resign', 'W', 0]], [['B:resign', 'B:cc', 'W:timeout', 'W:pass', 'B:cc'], ['resign', 'W', 0]], [['B:cc', 'W:pass', 'B:dd', 'B:resign'], ['resign', 'W', 3]], [[], ['playing', None, 0]], [['B:cc', 'B:resign', 'B:qq', 'W:timeout', 'B:pass'], ['resign', 'W', 1]]], [[['B:resign', 'B:cc', 'W:timeout', 'W:pass', 'B:cc'], ['resign', 'W', 0]], [['B:resign', 'W:pass'], ['resign', 'W', 0]], [['B:pass', 'W:cc', 'W:pass', 'B:cc'], ['playing', None, 4]], [['B:pass', 'W:qq'], ['playing', None, 2]], [['B:pass', 'B:dd', 'B:qq'], ['playing', None, 3]], [['W:pass'], ['playing', None, 1]], [['B:qq', 'W:cc', 'B:pass', 'B:cc'], ['playing', None, 4]], [['B:dd', 'W:cc', 'W:resign', 'W:timeout', 'W:pass'], ['resign', 'B', 2]]], [[['B:resign', 'W:pass', 'B:pass', 'W:dd'], ['resign', 'W', 0]], [['B:pass', 'W:qq', 'B:resign', 'W:pass', 'B:resign'], ['resign', 'W', 2]], [['B:dd', 'W:pass', 'B:pass', 'W:cc', 'B:cc'], ['score', None, 2]], [['B:dd', 'W:resign', 'B:dd', 'W:dd'], ['resign', 'B', 1]], [['W:qq', 'W:timeout', 'B:dd', 'W:pass', 'B:cc', 'W:qq'], ['time', 'B', 1]], [['B:dd'], ['playing', None, 1]], [['B:cc'], ['playing', None, 1]], [['B:cc', 'B:resign', 'B:qq', 'W:timeout', 'B:pass'], ['resign', 'W', 1]]], [[['W:cc', 'W:resign'], ['resign', 'B', 1]], [['B:dd', 'B:cc', 'B:cc', 'W:resign'], ['resign', 'B', 3]], [['W:pass', 'B:timeout', 'B:cc', 'W:dd'], ['time', 'W', 1]], [['B:timeout'], ['time', 'W', 0]], [['B:pass', 'W:pass', 'B:pass', 'W:resign', 'B:pass', 'W:dd'], ['score', None, 1]], [['W:timeout', 'W:cc', 'B:cc', 'W:pass', 'B:dd', 'W:qq'], ['time', 'B', 0]], [['B:pass', 'W:resign', 'W:pass'], ['resign', 'B', 1]], [['B:dd', 'W:cc', 'W:resign', 'W:timeout', 'W:pass'], ['resign', 'B', 2]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("game end 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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    moves = x
    prev_pass = None
    for idx, mv in enumerate(moves):
        who, _, act = mv.partition(':')
        other = 'W' if who == 'B' else 'B'
        if act == 'resign':
            return ['resign', 'W' if idx % 2 == 0 else 'B', idx]
        if act == 'timeout':
            return ['time', other, idx]
        if act == 'pass':
            if prev_pass is not None and prev_pass != who:
                return ['score', None, idx]
            prev_pass = who
        else:
            prev_pass = None
    return ['playing', None, len(moves)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[['B:pass', 'W:qq', 'B:cc', 'W:resign', 'B:cc', 'B:pass'], ['resign', 'B', 3]], [['B:resign', 'W:pass', 'W:resign', 'B:resign', 'B:qq', 'W:cc'], ['resign', 'W', 0]], [['B:timeout', 'W:pass', 'B:cc', 'B:cc'], ['time', 'W', 0]], [['B:timeout', 'W:pass', 'W:pass', 'W:pass'], ['time', 'W', 0]], [['B:timeout', 'W:cc'], ['time', 'W', 0]], [['B:timeout', 'W:resign'], ['time', 'W', 0]], [['B:pass'], ['playing', None, 1]], [['B:dd', 'W:cc', 'W:resign', 'W:timeout', 'W:pass'], ['resign', 'B', 2]]], [[['B:resign', 'W:pass', 'W:resign', 'B:resign', 'B:qq', 'W:cc'], ['resign', 'W', 0]], [['W:cc', 'B:pass', 'B:dd', 'W:cc', 'B:resign'], ['resign', 'W', 4]], [['B:pass'], ['playing', None, 1]], [['B:resign'], ['resign', 'W', 0]], [['B:resign', 'B:cc', 'W:timeout', 'W:pass', 'B:cc'], ['resign', 'W', 0]], [['B:cc', 'W:pass', 'B:dd', 'B:resign'], ['resign', 'W', 3]], [[], ['playing', None, 0]], [['B:cc', 'B:resign', 'B:qq', 'W:timeout', 'B:pass'], ['resign', 'W', 1]]], [[['B:resign', 'B:cc', 'W:timeout', 'W:pass', 'B:cc'], ['resign', 'W', 0]], [['B:resign', 'W:pass'], ['resign', 'W', 0]], [['B:pass', 'W:cc', 'W:pass', 'B:cc'], ['playing', None, 4]], [['B:pass', 'W:qq'], ['playing', None, 2]], [['B:pass', 'B:dd', 'B:qq'], ['playing', None, 3]], [['W:pass'], ['playing', None, 1]], [['B:qq', 'W:cc', 'B:pass', 'B:cc'], ['playing', None, 4]], [['B:dd', 'W:cc', 'W:resign', 'W:timeout', 'W:pass'], ['resign', 'B', 2]]], [[['B:resign', 'W:pass', 'B:pass', 'W:dd'], ['resign', 'W', 0]], [['B:pass', 'W:qq', 'B:resign', 'W:pass', 'B:resign'], ['resign', 'W', 2]], [['B:dd', 'W:pass', 'B:pass', 'W:cc', 'B:cc'], ['score', None, 2]], [['B:dd', 'W:resign', 'B:dd', 'W:dd'], ['resign', 'B', 1]], [['W:qq', 'W:timeout', 'B:dd', 'W:pass', 'B:cc', 'W:qq'], ['time', 'B', 1]], [['B:dd'], ['playing', None, 1]], [['B:cc'], ['playing', None, 1]], [['B:cc', 'B:resign', 'B:qq', 'W:timeout', 'B:pass'], ['resign', 'W', 1]]], [[['W:cc', 'W:resign'], ['resign', 'B', 1]], [['B:dd', 'B:cc', 'B:cc', 'W:resign'], ['resign', 'B', 3]], [['W:pass', 'B:timeout', 'B:cc', 'W:dd'], ['time', 'W', 1]], [['B:timeout'], ['time', 'W', 0]], [['B:pass', 'W:pass', 'B:pass', 'W:resign', 'B:pass', 'W:dd'], ['score', None, 1]], [['W:timeout', 'W:cc', 'B:cc', 'W:pass', 'B:dd', 'W:qq'], ['time', 'B', 0]], [['B:pass', 'W:resign', 'W:pass'], ['resign', 'B', 1]], [['B:dd', 'W:cc', 'W:resign', 'W:timeout', 'W:pass'], ['resign', 'B', 2]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("game end 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)

prompt:
Resignations invert the result.

Input list of "C:action" tokens. Two consecutive passes by different players end the game ["score", None, index]; any board move clears a pending pass; "resign"/"timeout" end it with the opponent as winner ["resign"/"time", winner, index]. Otherwise ["playing", None, len(moves)].

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    moves = x
    prev_pass = None
    for idx, mv in enumerate(moves):
        who, _, act = mv.partition(':')
        other = 'W' if who == 'B' else 'B'
        if act == 'resign':
            return ['resign', other, idx]
        if act == 'pass':
            if prev_pass is not None and prev_pass != who:
                return ['score', None, idx]
            prev_pass = who
        else:
            prev_pass = None
    return ['playing', None, len(moves)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[['B:cc', 'W:cc', 'B:timeout', 'W:timeout'], ['time', 'W', 2]], [['B:resign', 'W:pass', 'W:resign', 'B:resign', 'B:qq', 'W:cc'], ['resign', 'W', 0]], [['B:timeout', 'W:pass', 'B:cc', 'B:cc'], ['time', 'W', 0]], [['B:timeout', 'W:pass', 'W:pass', 'W:pass'], ['time', 'W', 0]], [['B:timeout', 'W:cc'], ['time', 'W', 0]], [['B:timeout', 'W:resign'], ['time', 'W', 0]], [['B:pass'], ['playing', None, 1]], [['W:pass', 'B:timeout', 'B:cc', 'W:dd'], ['time', 'W', 1]]], [[['B:timeout', 'W:cc'], ['time', 'W', 0]], [['W:cc', 'B:pass', 'B:dd', 'W:cc', 'B:resign'], ['resign', 'W', 4]], [['B:pass'], ['playing', None, 1]], [['B:resign'], ['resign', 'W', 0]], [['B:resign', 'B:cc', 'W:timeout', 'W:pass', 'B:cc'], ['resign', 'W', 0]], [['B:cc', 'W:pass', 'B:dd', 'B:resign'], ['resign', 'W', 3]], [[], ['playing', None, 0]], [['B:timeout', 'B:qq'], ['time', 'W', 0]]], [[['B:pass', 'W:qq'], ['playing', None, 2]], [['B:resign', 'W:pass'], ['resign', 'W', 0]], [['B:pass', 'W:cc', 'W:pass', 'B:cc'], ['playing', None, 4]], [['B:pass', 'W:qq'], ['playing', None, 2]], [['B:pass', 'B:dd', 'B:qq'], ['playing', None, 3]], [['W:pass'], ['playing', None, 1]], [['W:pass', 'B:timeout', 'B:cc', 'W:dd'], ['time', 'W', 1]], [['B:qq', 'B:timeout', 'B:timeout', 'W:qq', 'B:cc'], ['time', 'W', 1]]], [[['B:resign', 'W:pass', 'B:pass', 'W:dd'], ['resign', 'W', 0]], [['B:pass', 'W:qq', 'B:resign', 'W:pass', 'B:resign'], ['resign', 'W', 2]], [['B:dd', 'W:pass', 'B:pass', 'W:cc', 'B:cc'], ['score', None, 2]], [['B:dd', 'W:resign', 'B:dd', 'W:dd'], ['resign', 'B', 1]], [['W:qq', 'W:timeout', 'B:dd', 'W:pass', 'B:cc', 'W:qq'], ['time', 'B', 1]], [['B:dd'], ['playing', None, 1]], [['B:qq', 'B:timeout'], ['time', 'W', 1]], [['B:timeout', 'W:qq', 'B:dd', 'W:cc', 'B:dd'], ['time', 'W', 0]]], [[['W:cc', 'W:resign'], ['resign', 'B', 1]], [['B:dd', 'B:cc', 'B:cc', 'W:resign'], ['resign', 'B', 3]], [['W:pass', 'B:timeout', 'B:cc', 'W:dd'], ['time', 'W', 1]], [['B:timeout'], ['time', 'W', 0]], [['B:pass', 'W:pass', 'B:pass', 'W:resign', 'B:pass', 'W:dd'], ['score', None, 1]], [['W:timeout', 'W:cc', 'B:cc', 'W:pass', 'B:dd', 'W:qq'], ['time', 'B', 0]], [['W:timeout', 'W:resign', 'B:pass', 'W:timeout', 'B:pass', 'W:pass'], ['time', 'B', 0]], [['B:timeout', 'W:dd', 'B:pass', 'W:qq'], ['time', 'W', 0]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("game end 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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    moves = x
    prev_pass = None
    for idx, mv in enumerate(moves):
        who, _, act = mv.partition(':')
        other = 'W' if who == 'B' else 'B'
        if act == 'resign':
            return ['resign', other, idx]
        if act == 'timeout':
            return ['time', None, idx]
        if act == 'pass':
            if prev_pass is not None and prev_pass != who:
                return ['score', None, idx]
            prev_pass = who
        else:
            prev_pass = None
    return ['playing', None, len(moves)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[['B:cc', 'W:cc', 'B:timeout', 'W:timeout'], ['time', 'W', 2]], [['B:resign', 'W:pass', 'W:resign', 'B:resign', 'B:qq', 'W:cc'], ['resign', 'W', 0]], [['B:timeout', 'W:pass', 'B:cc', 'B:cc'], ['time', 'W', 0]], [['B:timeout', 'W:pass', 'W:pass', 'W:pass'], ['time', 'W', 0]], [['B:timeout', 'W:cc'], ['time', 'W', 0]], [['B:timeout', 'W:resign'], ['time', 'W', 0]], [['B:pass'], ['playing', None, 1]], [['W:pass', 'B:timeout', 'B:cc', 'W:dd'], ['time', 'W', 1]]], [[['B:timeout', 'W:cc'], ['time', 'W', 0]], [['W:cc', 'B:pass', 'B:dd', 'W:cc', 'B:resign'], ['resign', 'W', 4]], [['B:pass'], ['playing', None, 1]], [['B:resign'], ['resign', 'W', 0]], [['B:resign', 'B:cc', 'W:timeout', 'W:pass', 'B:cc'], ['resign', 'W', 0]], [['B:cc', 'W:pass', 'B:dd', 'B:resign'], ['resign', 'W', 3]], [[], ['playing', None, 0]], [['B:timeout', 'B:qq'], ['time', 'W', 0]]], [[['B:pass', 'W:qq'], ['playing', None, 2]], [['B:resign', 'W:pass'], ['resign', 'W', 0]], [['B:pass', 'W:cc', 'W:pass', 'B:cc'], ['playing', None, 4]], [['B:pass', 'W:qq'], ['playing', None, 2]], [['B:pass', 'B:dd', 'B:qq'], ['playing', None, 3]], [['W:pass'], ['playing', None, 1]], [['W:pass', 'B:timeout', 'B:cc', 'W:dd'], ['time', 'W', 1]], [['B:qq', 'B:timeout', 'B:timeout', 'W:qq', 'B:cc'], ['time', 'W', 1]]], [[['B:resign', 'W:pass', 'B:pass', 'W:dd'], ['resign', 'W', 0]], [['B:pass', 'W:qq', 'B:resign', 'W:pass', 'B:resign'], ['resign', 'W', 2]], [['B:dd', 'W:pass', 'B:pass', 'W:cc', 'B:cc'], ['score', None, 2]], [['B:dd', 'W:resign', 'B:dd', 'W:dd'], ['resign', 'B', 1]], [['W:qq', 'W:timeout', 'B:dd', 'W:pass', 'B:cc', 'W:qq'], ['time', 'B', 1]], [['B:dd'], ['playing', None, 1]], [['B:qq', 'B:timeout'], ['time', 'W', 1]], [['B:timeout', 'W:qq', 'B:dd', 'W:cc', 'B:dd'], ['time', 'W', 0]]], [[['W:cc', 'W:resign'], ['resign', 'B', 1]], [['B:dd', 'B:cc', 'B:cc', 'W:resign'], ['resign', 'B', 3]], [['W:pass', 'B:timeout', 'B:cc', 'W:dd'], ['time', 'W', 1]], [['B:timeout'], ['time', 'W', 0]], [['B:pass', 'W:pass', 'B:pass', 'W:resign', 'B:pass', 'W:dd'], ['score', None, 1]], [['W:timeout', 'W:cc', 'B:cc', 'W:pass', 'B:dd', 'W:qq'], ['time', 'B', 0]], [['W:timeout', 'W:resign', 'B:pass', 'W:timeout', 'B:pass', 'W:pass'], ['time', 'B', 0]], [['B:timeout', 'W:dd', 'B:pass', 'W:qq'], ['time', 'W', 0]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("game end 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)

prompt:
A game lost on time continues and may later end by passes.

Input list of "C:action" tokens. Two consecutive passes by different players end the game ["score", None, index]; any board move clears a pending pass; "resign"/"timeout" end it with the opponent as winner ["resign"/"time", winner, index]. Otherwise ["playing", None, len(moves)].

split: open-access