FAILURE MAP
← Case archive

FA-83311 / Go territory scoring / Open access

Arbitrary decimal komi is accepted · case 01

Komi 6.3 is accepted as 6.3 points.

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

ROOT CAUSE

Any digit fraction passes the check.

VERIFIED REPAIR

Allow only .0 and .5.

Unsuccessful approach: Allowing only .5 rejects valid whole-point komi written as 7.0.

Case contract

Input a komi string: optional sign, whole points, and an optional half written ".5"/".0" or "½". A bare half ("½", ".5") is allowed. Return komi in tenths or "invalid".

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):
    s = x.strip()
    neg = s.startswith('-')
    if s[:1] in '+-' and s:
        s = s[1:]
    half = 0
    if s.endswith('½'):
        half = 5
        s = s[:-1]
    elif '.' in s:
        s, _, frac = s.partition('.')
        if not frac.isdigit():
            return 'invalid'
        half = int(frac)
    if not s.isdigit():
        if s == '' and half:
            s = '0'
        else:
            return 'invalid'
    v = int(s) * 10 + half
    return -v if neg else v
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['0', 0], ['+5.5', 55], ['7.0', 70], ['6.3', 'invalid'], ['.5', 5], ['', 'invalid'], ['-', 'invalid'], ['abc', 'invalid']], [['abc', 'invalid'], ['5.', 'invalid'], [' 6.5 ', 65], ['-3', -30], ['-7.5', -75], ['0.0', 0], ['1 1/2', 'invalid'], ['6.50', 'invalid']], [['6.5', 65], ['7', 70], ['-0.5', -5], ['7.0', 70], ['6.3', 'invalid'], ['6.50', 'invalid'], ['+', 'invalid'], ['+½', 5]], [['6½', 65], ['½', 5], ['-6½', -65], ['0', 0], ['+5.5', 55], ['7.0', 70], ['0.0', 0], ['6.50', 'invalid']], [['7.0', 70], ['6.3', 'invalid'], ['-', 'invalid'], ['abc', 'invalid'], ['5.', 'invalid'], [' 6.5 ', 65], ['-3', -30], ['-7.5', -75]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("komi case %d" % i, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
komi case 000Passed
komi case 15555Passed
komi case 27070Passed
komi case 363invalidFailed
komi case 455Passed
komi case 5invalidinvalidPassed
komi case 6invalidinvalidPassed
komi case 7invalidinvalidPassed

SHA-256 / 3f7a461f8aa20fef2b86b6a8efc64509445561e09918eefbc102d62896a56e74

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(x):
    s = x.strip()
    neg = s.startswith('-')
    if s[:1] in '+-' and s:
        s = s[1:]
    half = 0
    if s.endswith('½'):
        half = 5
        s = s[:-1]
    elif '.' in s:
        s, _, frac = s.partition('.')
        if frac not in ('5',):
            return 'invalid'
        half = int(frac)
    if not s.isdigit():
        if s == '' and half:
            s = '0'
        else:
            return 'invalid'
    v = int(s) * 10 + half
    return -v if neg else v
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['0', 0], ['+5.5', 55], ['7.0', 70], ['6.3', 'invalid'], ['.5', 5], ['', 'invalid'], ['-', 'invalid'], ['abc', 'invalid']], [['abc', 'invalid'], ['5.', 'invalid'], [' 6.5 ', 65], ['-3', -30], ['-7.5', -75], ['0.0', 0], ['1 1/2', 'invalid'], ['6.50', 'invalid']], [['6.5', 65], ['7', 70], ['-0.5', -5], ['7.0', 70], ['6.3', 'invalid'], ['6.50', 'invalid'], ['+', 'invalid'], ['+½', 5]], [['6½', 65], ['½', 5], ['-6½', -65], ['0', 0], ['+5.5', 55], ['7.0', 70], ['0.0', 0], ['6.50', 'invalid']], [['7.0', 70], ['6.3', 'invalid'], ['-', 'invalid'], ['abc', 'invalid'], ['5.', 'invalid'], [' 6.5 ', 65], ['-3', -30], ['-7.5', -75]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("komi case %d" % i, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
komi case 000Passed
komi case 15555Passed
komi case 2invalid70Failed
komi case 3invalidinvalidPassed
komi case 455Passed
komi case 5invalidinvalidPassed
komi case 6invalidinvalidPassed
komi case 7invalidinvalidPassed

SHA-256 / cc5d6b50129808f1702b1c7423435c94c09a53d6e7c2c603a44026048dcc9136

3 / The verified repair

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

N = 1
observations = []
def solve(x):
    s = x.strip()
    neg = s.startswith('-')
    if s[:1] in '+-' and s:
        s = s[1:]
    half = 0
    if s.endswith('½'):
        half = 5
        s = s[:-1]
    elif '.' in s:
        s, _, frac = s.partition('.')
        if frac not in ('0', '5'):
            return 'invalid'
        half = int(frac)
    if not s.isdigit():
        if s == '' and half:
            s = '0'
        else:
            return 'invalid'
    v = int(s) * 10 + half
    return -v if neg else v
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['0', 0], ['+5.5', 55], ['7.0', 70], ['6.3', 'invalid'], ['.5', 5], ['', 'invalid'], ['-', 'invalid'], ['abc', 'invalid']], [['abc', 'invalid'], ['5.', 'invalid'], [' 6.5 ', 65], ['-3', -30], ['-7.5', -75], ['0.0', 0], ['1 1/2', 'invalid'], ['6.50', 'invalid']], [['6.5', 65], ['7', 70], ['-0.5', -5], ['7.0', 70], ['6.3', 'invalid'], ['6.50', 'invalid'], ['+', 'invalid'], ['+½', 5]], [['6½', 65], ['½', 5], ['-6½', -65], ['0', 0], ['+5.5', 55], ['7.0', 70], ['0.0', 0], ['6.50', 'invalid']], [['7.0', 70], ['6.3', 'invalid'], ['-', 'invalid'], ['abc', 'invalid'], ['5.', 'invalid'], [' 6.5 ', 65], ['-3', -30], ['-7.5', -75]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("komi case %d" % i, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
komi case 000Passed
komi case 15555Passed
komi case 27070Passed
komi case 3invalidinvalidPassed
komi case 455Passed
komi case 5invalidinvalidPassed
komi case 6invalidinvalidPassed
komi case 7invalidinvalidPassed

SHA-256 / 8333d5f29dd9cc7e360957cb3caba4805d6e316fe9d785299b2a578718b8f0c3

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

Case digest / aa78bcbe2a3c5ee4819340e430afd457482552907784dcdcd43a967fd48d4a94