FA-83081 / Go territory scoring / Open access
A liberty shared by two stones of a chain hides the atari · case 01
Chains whose only liberty touches two of their stones are not reported.
ROOT CAUSE
Liberties are collected in a list, so a point adjacent to two chain stones counts twice.
VERIFIED REPAIR
Collect liberties as a set of distinct points.
Unsuccessful approach: Keeping the list but accepting up to two entries as atari also reports chains with two distinct liberties.
Case contract
Input a board. Report every chain with exactly one distinct liberty as [colour, lib_row, lib_col, chain_size], sorted ascending.
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 = x
n = len(board)
m = len(board[0])
seen = set()
out = []
for r in range(n):
for c in range(m):
col = board[r][c]
if col == '.' or (r, c) in seen:
continue
seen.add((r, c))
stack = [(r, c)]
size = 0
libs = []
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 0 <= p < n and 0 <= q < m:
if board[p][q] == '.':
libs.append((p, q))
elif board[p][q] == col and (p, q) not in seen:
seen.add((p, q))
stack.append((p, q))
if len(libs) == 1:
p, q = min(libs)
out.append([col, p, q, size])
out.sort()
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[['W....', '.....', '.....', '.....', '....B'], []], [['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], [['B', 4, 1, 1], ['W', 2, 0, 1]]], [['BBBB', 'B..B', 'B..B', 'BBBB'], []], [['WWW', 'W.W', 'WWW'], [['W', 1, 1, 8]]], [['B.W', '...', 'W.B'], []], [['.B...', 'B....', '.....', '....W', '...W.'], []], [['BW.', 'BW.', 'BW.'], []], [['..W', '.W.', 'W..'], []]], [[['.....', '.BBB.', '.B.B.', '.BBB.', '.....'], []], [['WB.B', 'B.B.', '.B..', 'B...'], []], [['..W', '.W.', 'W..'], []], [['B....B', '......', '..WW..', '..WW..', '......', 'B....B'], []], [['B.WW', 'W..W', 'BWWW', 'BWW.'], [['B', 0, 1, 1], ['W', 1, 1, 1]]], [['WW.B', '..B.', '....', '..WW'], []], [['WW..', '.BWB', '...B', 'WBW.'], [['B', 2, 1, 1], ['W', 2, 0, 1]]], [['WWWB', 'W.WB', 'WWWB', 'BBBB'], [['W', 1, 1, 8]]]], [[['WW.', 'WWW', 'WBB'], [['W', 0, 2, 6]]], [['B..BB', 'W.B..', '.W.BB'], [['B', 0, 1, 1]]], [['WW..', '.BWB', '...B', 'WBW.'], [['B', 2, 1, 1], ['W', 2, 0, 1]]], [['...', '...', '..B'], []], [['.....', '.....', 'W....', '.....'], []], [['.B..', '....', 'BW.W', '....', 'W..W'], []], [['WBBB', '.BB.', '.WB.', 'B.B.', 'WB..'], [['W', 1, 0, 1]]], [['W.B', 'WWW', 'W.W', '.WB', 'WBW'], [['B', 0, 1, 1], ['W', 3, 0, 1]]]], [[['WWBB', '.W..', 'WBBB', 'WW.B', 'WBWB'], [['W', 3, 2, 1]]], [['W.B', 'WWW', 'W.W', '.WB', 'WBW'], [['B', 0, 1, 1], ['W', 3, 0, 1]]], [['BBB.', 'W...', 'B.WB', 'WWW.', '.B..'], [['B', 2, 1, 1], ['W', 1, 1, 1]]], [['..WB', '.B.B', '..B.'], []], [['.B.', '..B', 'BB.', 'B.W'], []], [['...', '..B', '...'], []], [['B.B', '..B', '.BB', '.B.', '..B'], []], [['BBBW', 'B.BW', 'BBBW', 'WWW.'], [['B', 1, 1, 8], ['W', 3, 3, 3], ['W', 3, 3, 3]]]], [[['B.B', '..B', '.BB', '.B.', '..B'], []], [['WBW.', '..BB', '.WBB'], [['B', 1, 1, 1], ['W', 0, 3, 1], ['W', 1, 0, 1]]], [['.WW..', '..BW.', '.....'], []], [['BW..', '....', '...B', '.W..'], [['B', 1, 0, 1]]], [['.BBWW', 'WW.W.', 'BB.WW', 'B.W..', '.W.BW'], [['W', 3, 4, 1]]], [['BW.', 'BB.', 'WWB'], [['B', 1, 2, 1], ['B', 1, 2, 3], ['W', 0, 2, 1]]], [['WWW', '..B', '...', '.WW'], []], [['BBB', 'B.B', 'BBB'], [['B', 1, 1, 8]]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("atari case %d" % i, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| atari case 0 | [] | [] | Passed |
| atari case 1 | [['B', 4, 1, 1], ['W', 2, 0, 1]] | [['B', 4, 1, 1], ['W', 2, 0, 1]] | Passed |
| atari case 2 | [] | [] | Passed |
| atari case 3 | [] | [['W', 1, 1, 8]] | Failed |
| atari case 4 | [] | [] | Passed |
| atari case 5 | [] | [] | Passed |
| atari case 6 | [] | [] | Passed |
| atari case 7 | [] | [] | Passed |
SHA-256 / 946c64f5e07fd04d7b45d676288f582a19b7601003bb8c3768d0d90b9fab3a01
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
board = x
n = len(board)
m = len(board[0])
seen = set()
out = []
for r in range(n):
for c in range(m):
col = board[r][c]
if col == '.' or (r, c) in seen:
continue
seen.add((r, c))
stack = [(r, c)]
size = 0
libs = []
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 0 <= p < n and 0 <= q < m:
if board[p][q] == '.':
libs.append((p, q))
elif board[p][q] == col and (p, q) not in seen:
seen.add((p, q))
stack.append((p, q))
if 1 <= len(libs) <= 2:
p, q = min(libs)
out.append([col, p, q, size])
out.sort()
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[['W....', '.....', '.....', '.....', '....B'], []], [['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], [['B', 4, 1, 1], ['W', 2, 0, 1]]], [['BBBB', 'B..B', 'B..B', 'BBBB'], []], [['WWW', 'W.W', 'WWW'], [['W', 1, 1, 8]]], [['B.W', '...', 'W.B'], []], [['.B...', 'B....', '.....', '....W', '...W.'], []], [['BW.', 'BW.', 'BW.'], []], [['..W', '.W.', 'W..'], []]], [[['.....', '.BBB.', '.B.B.', '.BBB.', '.....'], []], [['WB.B', 'B.B.', '.B..', 'B...'], []], [['..W', '.W.', 'W..'], []], [['B....B', '......', '..WW..', '..WW..', '......', 'B....B'], []], [['B.WW', 'W..W', 'BWWW', 'BWW.'], [['B', 0, 1, 1], ['W', 1, 1, 1]]], [['WW.B', '..B.', '....', '..WW'], []], [['WW..', '.BWB', '...B', 'WBW.'], [['B', 2, 1, 1], ['W', 2, 0, 1]]], [['WWWB', 'W.WB', 'WWWB', 'BBBB'], [['W', 1, 1, 8]]]], [[['WW.', 'WWW', 'WBB'], [['W', 0, 2, 6]]], [['B..BB', 'W.B..', '.W.BB'], [['B', 0, 1, 1]]], [['WW..', '.BWB', '...B', 'WBW.'], [['B', 2, 1, 1], ['W', 2, 0, 1]]], [['...', '...', '..B'], []], [['.....', '.....', 'W....', '.....'], []], [['.B..', '....', 'BW.W', '....', 'W..W'], []], [['WBBB', '.BB.', '.WB.', 'B.B.', 'WB..'], [['W', 1, 0, 1]]], [['W.B', 'WWW', 'W.W', '.WB', 'WBW'], [['B', 0, 1, 1], ['W', 3, 0, 1]]]], [[['WWBB', '.W..', 'WBBB', 'WW.B', 'WBWB'], [['W', 3, 2, 1]]], [['W.B', 'WWW', 'W.W', '.WB', 'WBW'], [['B', 0, 1, 1], ['W', 3, 0, 1]]], [['BBB.', 'W...', 'B.WB', 'WWW.', '.B..'], [['B', 2, 1, 1], ['W', 1, 1, 1]]], [['..WB', '.B.B', '..B.'], []], [['.B.', '..B', 'BB.', 'B.W'], []], [['...', '..B', '...'], []], [['B.B', '..B', '.BB', '.B.', '..B'], []], [['BBBW', 'B.BW', 'BBBW', 'WWW.'], [['B', 1, 1, 8], ['W', 3, 3, 3], ['W', 3, 3, 3]]]], [[['B.B', '..B', '.BB', '.B.', '..B'], []], [['WBW.', '..BB', '.WBB'], [['B', 1, 1, 1], ['W', 0, 3, 1], ['W', 1, 0, 1]]], [['.WW..', '..BW.', '.....'], []], [['BW..', '....', '...B', '.W..'], [['B', 1, 0, 1]]], [['.BBWW', 'WW.W.', 'BB.WW', 'B.W..', '.W.BW'], [['W', 3, 4, 1]]], [['BW.', 'BB.', 'WWB'], [['B', 1, 2, 1], ['B', 1, 2, 3], ['W', 0, 2, 1]]], [['WWW', '..B', '...', '.WW'], []], [['BBB', 'B.B', 'BBB'], [['B', 1, 1, 8]]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("atari case %d" % i, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| atari case 0 | [['B', 3, 4, 1], ['W', 0, 1, 1]] | [] | Failed |
| atari case 1 | [['B', 2, 3, 1], ['B', 3, 2, 1], ['B', 4, 1, 1], ['W', 0, 2, 1], ['W', 1, 1, 1], ['W', 2, 0, 1]] | [['B', 4, 1, 1], ['W', 2, 0, 1]] | Failed |
| atari case 2 | [] | [] | Passed |
| atari case 3 | [] | [['W', 1, 1, 8]] | Failed |
| atari case 4 | [['B', 0, 1, 1], ['B', 1, 2, 1], ['W', 0, 1, 1], ['W', 1, 0, 1]] | [] | Failed |
| atari case 5 | [] | [] | Passed |
| atari case 6 | [] | [] | Passed |
| atari case 7 | [['W', 0, 1, 1], ['W', 1, 0, 1]] | [] | Failed |
SHA-256 / 023260cc84ce8b6a078eebad2b2527f22aaacd4890ccc73799f35fae9d50fbda
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
board = x
n = len(board)
m = len(board[0])
seen = set()
out = []
for r in range(n):
for c in range(m):
col = board[r][c]
if col == '.' or (r, c) in seen:
continue
seen.add((r, c))
stack = [(r, c)]
size = 0
libs = set()
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 0 <= p < n and 0 <= q < m:
if board[p][q] == '.':
libs.add((p, q))
elif board[p][q] == col and (p, q) not in seen:
seen.add((p, q))
stack.append((p, q))
if len(libs) == 1:
p, q = min(libs)
out.append([col, p, q, size])
out.sort()
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[['W....', '.....', '.....', '.....', '....B'], []], [['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], [['B', 4, 1, 1], ['W', 2, 0, 1]]], [['BBBB', 'B..B', 'B..B', 'BBBB'], []], [['WWW', 'W.W', 'WWW'], [['W', 1, 1, 8]]], [['B.W', '...', 'W.B'], []], [['.B...', 'B....', '.....', '....W', '...W.'], []], [['BW.', 'BW.', 'BW.'], []], [['..W', '.W.', 'W..'], []]], [[['.....', '.BBB.', '.B.B.', '.BBB.', '.....'], []], [['WB.B', 'B.B.', '.B..', 'B...'], []], [['..W', '.W.', 'W..'], []], [['B....B', '......', '..WW..', '..WW..', '......', 'B....B'], []], [['B.WW', 'W..W', 'BWWW', 'BWW.'], [['B', 0, 1, 1], ['W', 1, 1, 1]]], [['WW.B', '..B.', '....', '..WW'], []], [['WW..', '.BWB', '...B', 'WBW.'], [['B', 2, 1, 1], ['W', 2, 0, 1]]], [['WWWB', 'W.WB', 'WWWB', 'BBBB'], [['W', 1, 1, 8]]]], [[['WW.', 'WWW', 'WBB'], [['W', 0, 2, 6]]], [['B..BB', 'W.B..', '.W.BB'], [['B', 0, 1, 1]]], [['WW..', '.BWB', '...B', 'WBW.'], [['B', 2, 1, 1], ['W', 2, 0, 1]]], [['...', '...', '..B'], []], [['.....', '.....', 'W....', '.....'], []], [['.B..', '....', 'BW.W', '....', 'W..W'], []], [['WBBB', '.BB.', '.WB.', 'B.B.', 'WB..'], [['W', 1, 0, 1]]], [['W.B', 'WWW', 'W.W', '.WB', 'WBW'], [['B', 0, 1, 1], ['W', 3, 0, 1]]]], [[['WWBB', '.W..', 'WBBB', 'WW.B', 'WBWB'], [['W', 3, 2, 1]]], [['W.B', 'WWW', 'W.W', '.WB', 'WBW'], [['B', 0, 1, 1], ['W', 3, 0, 1]]], [['BBB.', 'W...', 'B.WB', 'WWW.', '.B..'], [['B', 2, 1, 1], ['W', 1, 1, 1]]], [['..WB', '.B.B', '..B.'], []], [['.B.', '..B', 'BB.', 'B.W'], []], [['...', '..B', '...'], []], [['B.B', '..B', '.BB', '.B.', '..B'], []], [['BBBW', 'B.BW', 'BBBW', 'WWW.'], [['B', 1, 1, 8], ['W', 3, 3, 3], ['W', 3, 3, 3]]]], [[['B.B', '..B', '.BB', '.B.', '..B'], []], [['WBW.', '..BB', '.WBB'], [['B', 1, 1, 1], ['W', 0, 3, 1], ['W', 1, 0, 1]]], [['.WW..', '..BW.', '.....'], []], [['BW..', '....', '...B', '.W..'], [['B', 1, 0, 1]]], [['.BBWW', 'WW.W.', 'BB.WW', 'B.W..', '.W.BW'], [['W', 3, 4, 1]]], [['BW.', 'BB.', 'WWB'], [['B', 1, 2, 1], ['B', 1, 2, 3], ['W', 0, 2, 1]]], [['WWW', '..B', '...', '.WW'], []], [['BBB', 'B.B', 'BBB'], [['B', 1, 1, 8]]]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("atari case %d" % i, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| atari case 0 | [] | [] | Passed |
| atari case 1 | [['B', 4, 1, 1], ['W', 2, 0, 1]] | [['B', 4, 1, 1], ['W', 2, 0, 1]] | Passed |
| atari case 2 | [] | [] | Passed |
| atari case 3 | [['W', 1, 1, 8]] | [['W', 1, 1, 8]] | Passed |
| atari case 4 | [] | [] | Passed |
| atari case 5 | [] | [] | Passed |
| atari case 6 | [] | [] | Passed |
| atari case 7 | [] | [] | Passed |
SHA-256 / da08a52f1b1a54500f97b558aa647b09bd0900c7c2bdce5a1a0db07094b75480
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.160802+00:00.
Case digest / 0665507fee9d01afe92b931c5d847de57a4e106e8473fccfdaa8fef31a3dfa6e