FA-84201 / Sports scoring and tiebreakers / Open access
Bust only undoes the last dart · case 01
After a bust the remaining score keeps the earlier darts of the turn.
ROOT CAUSE
The bust handler adds back only the value of the busting dart.
VERIFIED REPAIR
Restore the score captured at the start of the turn.
Unsuccessful approach: Reverting to the leg starting score wipes out earlier completed turns.
Case contract
Double-out darts leg from a remaining score. darts lists thrown darts: S/D/T followed by 1-20, SB (25), DB (50, a double) or M (miss). Turns are three darts. After each dart: reaching exactly 0 with a double (D* or DB) checks out and later darts are ignored; a remaining score below 2 otherwise is a bust, the score reverts to its value at the start of the turn and the turn ends immediately (the next dart in the list starts a new turn). Return [remaining, turns used, checked_out].
Why this case matters
Darts scoring apps must implement bust reversion and double-out exactly.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(start, darts):
def value(d):
if d == 'M':
return 0, False
if d == 'SB':
return 25, False
if d == 'DB':
return 50, True
mult = {'S': 1, 'D': 2, 'T': 3}[d[0]]
return mult * int(d[1:]), d[0] == 'D'
score = start
turns = 0
i = 0
while i < len(darts):
turns += 1
turn_start = score
for k in range(3):
if i >= len(darts):
break
v, dbl = value(darts[i])
i += 1
score -= v
if score == 0 and dbl:
return [0, turns, True]
if score < 2:
score += v
break
return [score, turns, False]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
def run(args):
try:
return solve(*args)
except Exception as exc:
return 'raised ' + type(exc).__name__
cases = [[('control checkout on double', (40, ['D20']), [0, 1, True]),
('boundary finish on single busts', (20, ['S20', 'D10']), [0, 2, True]),
('boundary leave one busts', (21, ['S20', 'S1']), [20, 2, False]),
('control bull finish', (50, ['DB']), [0, 1, True]),
('boundary bust mid-turn reverts', (32, ['S10', 'T20', 'D16']), [0, 2, True]),
('control scoring turn', (101, ['T20', 'S1', 'S20']), [20, 1, False]),
('regression: bust reversion scope',
(20, ['S13', 'D5', 'T12', 'T17', 'D7', 'D13', 'S6']),
[14, 5, False]),
('regression: bust reversion scope',
(54, ['D13', 'S13', 'DB', 'M', 'S9', 'S16', 'D16', 'M']),
[29, 4, False]),
('variant scenario 1',
(45, ['T10', 'S14', 'S20', 'D1', 'SB', 'D19', 'D20', 'D16', 'S14']),
[45, 4, False]),
('variant scenario 2',
(36, ['S18', 'D12', 'D4', 'D15', 'D11', 'D12', 'D11', 'D11']),
[36, 4, False])],
[('control checkout on double', (40, ['D20']), [0, 1, True]),
('boundary finish on single busts', (20, ['S20', 'D10']), [0, 2, True]),
('boundary leave one busts', (21, ['S20', 'S1']), [20, 2, False]),
('control bull finish', (50, ['DB']), [0, 1, True]),
('boundary bust mid-turn reverts', (32, ['S10', 'T20', 'D16']), [0, 2, True]),
('control scoring turn', (101, ['T20', 'S1', 'S20']), [20, 1, False]),
('regression: bust reversion scope', (50, ['T3', 'D4', 'S8', 'T8', 'S9', 'SB']), [25, 3, False]),
('variant scenario 1', (32, ['D4', 'D14', 'SB', 'DB', 'D15', 'S4', 'S5', 'T5']), [12, 4, False]),
('variant scenario 2', (50, ['DB']), [0, 1, True])],
[('control checkout on double', (40, ['D20']), [0, 1, True]),
('boundary finish on single busts', (20, ['S20', 'D10']), [0, 2, True]),
('boundary leave one busts', (21, ['S20', 'S1']), [20, 2, False]),
('control bull finish', (50, ['DB']), [0, 1, True]),
('boundary bust mid-turn reverts', (32, ['S10', 'T20', 'D16']), [0, 2, True]),
('control scoring turn', (101, ['T20', 'S1', 'S20']), [20, 1, False]),
('regression: bust reversion scope', (32, ['T2', 'S18', 'S12', 'D7']), [18, 2, False]),
('regression: bust reversion scope',
(101, ['D11', 'D9', 'S5', 'D12', 'D11', 'DB']),
[56, 2, False]),
('variant scenario 1', (3, ['D10', 'T9']), [3, 2, False]),
('variant scenario 2', (101, ['D15', 'S1', 'D1']), [68, 1, False])],
[('control checkout on double', (40, ['D20']), [0, 1, True]),
('boundary finish on single busts', (20, ['S20', 'D10']), [0, 2, True]),
('boundary leave one busts', (21, ['S20', 'S1']), [20, 2, False]),
('control bull finish', (50, ['DB']), [0, 1, True]),
('boundary bust mid-turn reverts', (32, ['S10', 'T20', 'D16']), [0, 2, True]),
('control scoring turn', (101, ['T20', 'S1', 'S20']), [20, 1, False]),
('regression: bust reversion scope', (50, ['T4', 'S8', 'S4', 'T1', 'SB', 'T12']), [26, 3, False]),
('variant scenario 1', (3, ['S19', 'D6', 'D4', 'D19', 'D5', 'D9', 'T10', 'S14']), [3, 8, False]),
('variant scenario 2', (16, ['D13', 'D17', 'D8', 'S8']), [0, 3, True])],
[('control checkout on double', (40, ['D20']), [0, 1, True]),
('boundary finish on single busts', (20, ['S20', 'D10']), [0, 2, True]),
('boundary leave one busts', (21, ['S20', 'S1']), [20, 2, False]),
('control bull finish', (50, ['DB']), [0, 1, True]),
('boundary bust mid-turn reverts', (32, ['S10', 'T20', 'D16']), [0, 2, True]),
('control scoring turn', (101, ['T20', 'S1', 'S20']), [20, 1, False]),
('regression: bust reversion scope',
(10, ['S16', 'D18', 'T5', 'D20', 'D2', 'D4', 'S9', 'D16', 'D2']),
[6, 8, False]),
('regression: bust reversion scope',
(101, ['D9', 'T11', 'SB', 'D15', 'T19', 'S7']),
[18, 4, False]),
('variant scenario 1', (3, ['M', 'D19', 'T10', 'T8', 'D5', 'S4', 'M', 'S3']), [3, 6, False]),
('variant scenario 2', (101, ['D5', 'D12']), [67, 1, False])]]
for label, args, expected in cases[N - 1]:
check(label, run(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 |
|---|---|---|---|
| control checkout on double | [0, 1, True] | [0, 1, True] | Passed |
| boundary finish on single busts | [0, 2, True] | [0, 2, True] | Passed |
| boundary leave one busts | [20, 2, False] | [20, 2, False] | Passed |
| control bull finish | [0, 1, True] | [0, 1, True] | Passed |
| boundary bust mid-turn reverts | [22, 2, False] | [0, 2, True] | Failed |
| control scoring turn | [20, 1, False] | [20, 1, False] | Passed |
| regression: bust reversion scope | [7, 6, False] | [14, 5, False] | Failed |
| regression: bust reversion scope | [6, 4, False] | [29, 4, False] | Failed |
| variant scenario 1 | [13, 7, False] | [45, 4, False] | Failed |
| variant scenario 2 | [10, 6, False] | [36, 4, False] | Failed |
SHA-256 / b8f2ffd7bf5b2411af737cb190ddc1b5141e24bdabba49ddc27defcbfacd7a52
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(start, darts):
def value(d):
if d == 'M':
return 0, False
if d == 'SB':
return 25, False
if d == 'DB':
return 50, True
mult = {'S': 1, 'D': 2, 'T': 3}[d[0]]
return mult * int(d[1:]), d[0] == 'D'
score = start
turns = 0
i = 0
while i < len(darts):
turns += 1
turn_start = score
for k in range(3):
if i >= len(darts):
break
v, dbl = value(darts[i])
i += 1
score -= v
if score == 0 and dbl:
return [0, turns, True]
if score < 2:
score = start
break
return [score, turns, False]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
def run(args):
try:
return solve(*args)
except Exception as exc:
return 'raised ' + type(exc).__name__
cases = [[('control checkout on double', (40, ['D20']), [0, 1, True]),
('boundary finish on single busts', (20, ['S20', 'D10']), [0, 2, True]),
('boundary leave one busts', (21, ['S20', 'S1']), [20, 2, False]),
('control bull finish', (50, ['DB']), [0, 1, True]),
('boundary bust mid-turn reverts', (32, ['S10', 'T20', 'D16']), [0, 2, True]),
('control scoring turn', (101, ['T20', 'S1', 'S20']), [20, 1, False]),
('regression: bust reversion scope',
(20, ['S13', 'D5', 'T12', 'T17', 'D7', 'D13', 'S6']),
[14, 5, False]),
('regression: bust reversion scope',
(54, ['D13', 'S13', 'DB', 'M', 'S9', 'S16', 'D16', 'M']),
[29, 4, False]),
('variant scenario 1',
(45, ['T10', 'S14', 'S20', 'D1', 'SB', 'D19', 'D20', 'D16', 'S14']),
[45, 4, False]),
('variant scenario 2',
(36, ['S18', 'D12', 'D4', 'D15', 'D11', 'D12', 'D11', 'D11']),
[36, 4, False])],
[('control checkout on double', (40, ['D20']), [0, 1, True]),
('boundary finish on single busts', (20, ['S20', 'D10']), [0, 2, True]),
('boundary leave one busts', (21, ['S20', 'S1']), [20, 2, False]),
('control bull finish', (50, ['DB']), [0, 1, True]),
('boundary bust mid-turn reverts', (32, ['S10', 'T20', 'D16']), [0, 2, True]),
('control scoring turn', (101, ['T20', 'S1', 'S20']), [20, 1, False]),
('regression: bust reversion scope', (50, ['T3', 'D4', 'S8', 'T8', 'S9', 'SB']), [25, 3, False]),
('variant scenario 1', (32, ['D4', 'D14', 'SB', 'DB', 'D15', 'S4', 'S5', 'T5']), [12, 4, False]),
('variant scenario 2', (50, ['DB']), [0, 1, True])],
[('control checkout on double', (40, ['D20']), [0, 1, True]),
('boundary finish on single busts', (20, ['S20', 'D10']), [0, 2, True]),
('boundary leave one busts', (21, ['S20', 'S1']), [20, 2, False]),
('control bull finish', (50, ['DB']), [0, 1, True]),
('boundary bust mid-turn reverts', (32, ['S10', 'T20', 'D16']), [0, 2, True]),
('control scoring turn', (101, ['T20', 'S1', 'S20']), [20, 1, False]),
('regression: bust reversion scope', (32, ['T2', 'S18', 'S12', 'D7']), [18, 2, False]),
('regression: bust reversion scope',
(101, ['D11', 'D9', 'S5', 'D12', 'D11', 'DB']),
[56, 2, False]),
('variant scenario 1', (3, ['D10', 'T9']), [3, 2, False]),
('variant scenario 2', (101, ['D15', 'S1', 'D1']), [68, 1, False])],
[('control checkout on double', (40, ['D20']), [0, 1, True]),
('boundary finish on single busts', (20, ['S20', 'D10']), [0, 2, True]),
('boundary leave one busts', (21, ['S20', 'S1']), [20, 2, False]),
('control bull finish', (50, ['DB']), [0, 1, True]),
('boundary bust mid-turn reverts', (32, ['S10', 'T20', 'D16']), [0, 2, True]),
('control scoring turn', (101, ['T20', 'S1', 'S20']), [20, 1, False]),
('regression: bust reversion scope', (50, ['T4', 'S8', 'S4', 'T1', 'SB', 'T12']), [26, 3, False]),
('variant scenario 1', (3, ['S19', 'D6', 'D4', 'D19', 'D5', 'D9', 'T10', 'S14']), [3, 8, False]),
('variant scenario 2', (16, ['D13', 'D17', 'D8', 'S8']), [0, 3, True])],
[('control checkout on double', (40, ['D20']), [0, 1, True]),
('boundary finish on single busts', (20, ['S20', 'D10']), [0, 2, True]),
('boundary leave one busts', (21, ['S20', 'S1']), [20, 2, False]),
('control bull finish', (50, ['DB']), [0, 1, True]),
('boundary bust mid-turn reverts', (32, ['S10', 'T20', 'D16']), [0, 2, True]),
('control scoring turn', (101, ['T20', 'S1', 'S20']), [20, 1, False]),
('regression: bust reversion scope',
(10, ['S16', 'D18', 'T5', 'D20', 'D2', 'D4', 'S9', 'D16', 'D2']),
[6, 8, False]),
('regression: bust reversion scope',
(101, ['D9', 'T11', 'SB', 'D15', 'T19', 'S7']),
[18, 4, False]),
('variant scenario 1', (3, ['M', 'D19', 'T10', 'T8', 'D5', 'S4', 'M', 'S3']), [3, 6, False]),
('variant scenario 2', (101, ['D5', 'D12']), [67, 1, False])]]
for label, args, expected in cases[N - 1]:
check(label, run(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 |
|---|---|---|---|
| control checkout on double | [0, 1, True] | [0, 1, True] | Passed |
| boundary finish on single busts | [0, 2, True] | [0, 2, True] | Passed |
| boundary leave one busts | [20, 2, False] | [20, 2, False] | Passed |
| control bull finish | [0, 1, True] | [0, 1, True] | Passed |
| boundary bust mid-turn reverts | [0, 2, True] | [0, 2, True] | Passed |
| control scoring turn | [20, 1, False] | [20, 1, False] | Passed |
| regression: bust reversion scope | [14, 5, False] | [14, 5, False] | Passed |
| regression: bust reversion scope | [54, 4, False] | [29, 4, False] | Failed |
| variant scenario 1 | [45, 4, False] | [45, 4, False] | Passed |
| variant scenario 2 | [36, 4, False] | [36, 4, False] | Passed |
SHA-256 / 1991203535b6f4034ae749d588e07e2e23abb53f69582e8f3ac786fcff582515
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(start, darts):
def value(d):
if d == 'M':
return 0, False
if d == 'SB':
return 25, False
if d == 'DB':
return 50, True
mult = {'S': 1, 'D': 2, 'T': 3}[d[0]]
return mult * int(d[1:]), d[0] == 'D'
score = start
turns = 0
i = 0
while i < len(darts):
turns += 1
turn_start = score
for k in range(3):
if i >= len(darts):
break
v, dbl = value(darts[i])
i += 1
score -= v
if score == 0 and dbl:
return [0, turns, True]
if score < 2:
score = turn_start
break
return [score, turns, False]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
def run(args):
try:
return solve(*args)
except Exception as exc:
return 'raised ' + type(exc).__name__
cases = [[('control checkout on double', (40, ['D20']), [0, 1, True]),
('boundary finish on single busts', (20, ['S20', 'D10']), [0, 2, True]),
('boundary leave one busts', (21, ['S20', 'S1']), [20, 2, False]),
('control bull finish', (50, ['DB']), [0, 1, True]),
('boundary bust mid-turn reverts', (32, ['S10', 'T20', 'D16']), [0, 2, True]),
('control scoring turn', (101, ['T20', 'S1', 'S20']), [20, 1, False]),
('regression: bust reversion scope',
(20, ['S13', 'D5', 'T12', 'T17', 'D7', 'D13', 'S6']),
[14, 5, False]),
('regression: bust reversion scope',
(54, ['D13', 'S13', 'DB', 'M', 'S9', 'S16', 'D16', 'M']),
[29, 4, False]),
('variant scenario 1',
(45, ['T10', 'S14', 'S20', 'D1', 'SB', 'D19', 'D20', 'D16', 'S14']),
[45, 4, False]),
('variant scenario 2',
(36, ['S18', 'D12', 'D4', 'D15', 'D11', 'D12', 'D11', 'D11']),
[36, 4, False])],
[('control checkout on double', (40, ['D20']), [0, 1, True]),
('boundary finish on single busts', (20, ['S20', 'D10']), [0, 2, True]),
('boundary leave one busts', (21, ['S20', 'S1']), [20, 2, False]),
('control bull finish', (50, ['DB']), [0, 1, True]),
('boundary bust mid-turn reverts', (32, ['S10', 'T20', 'D16']), [0, 2, True]),
('control scoring turn', (101, ['T20', 'S1', 'S20']), [20, 1, False]),
('regression: bust reversion scope', (50, ['T3', 'D4', 'S8', 'T8', 'S9', 'SB']), [25, 3, False]),
('variant scenario 1', (32, ['D4', 'D14', 'SB', 'DB', 'D15', 'S4', 'S5', 'T5']), [12, 4, False]),
('variant scenario 2', (50, ['DB']), [0, 1, True])],
[('control checkout on double', (40, ['D20']), [0, 1, True]),
('boundary finish on single busts', (20, ['S20', 'D10']), [0, 2, True]),
('boundary leave one busts', (21, ['S20', 'S1']), [20, 2, False]),
('control bull finish', (50, ['DB']), [0, 1, True]),
('boundary bust mid-turn reverts', (32, ['S10', 'T20', 'D16']), [0, 2, True]),
('control scoring turn', (101, ['T20', 'S1', 'S20']), [20, 1, False]),
('regression: bust reversion scope', (32, ['T2', 'S18', 'S12', 'D7']), [18, 2, False]),
('regression: bust reversion scope',
(101, ['D11', 'D9', 'S5', 'D12', 'D11', 'DB']),
[56, 2, False]),
('variant scenario 1', (3, ['D10', 'T9']), [3, 2, False]),
('variant scenario 2', (101, ['D15', 'S1', 'D1']), [68, 1, False])],
[('control checkout on double', (40, ['D20']), [0, 1, True]),
('boundary finish on single busts', (20, ['S20', 'D10']), [0, 2, True]),
('boundary leave one busts', (21, ['S20', 'S1']), [20, 2, False]),
('control bull finish', (50, ['DB']), [0, 1, True]),
('boundary bust mid-turn reverts', (32, ['S10', 'T20', 'D16']), [0, 2, True]),
('control scoring turn', (101, ['T20', 'S1', 'S20']), [20, 1, False]),
('regression: bust reversion scope', (50, ['T4', 'S8', 'S4', 'T1', 'SB', 'T12']), [26, 3, False]),
('variant scenario 1', (3, ['S19', 'D6', 'D4', 'D19', 'D5', 'D9', 'T10', 'S14']), [3, 8, False]),
('variant scenario 2', (16, ['D13', 'D17', 'D8', 'S8']), [0, 3, True])],
[('control checkout on double', (40, ['D20']), [0, 1, True]),
('boundary finish on single busts', (20, ['S20', 'D10']), [0, 2, True]),
('boundary leave one busts', (21, ['S20', 'S1']), [20, 2, False]),
('control bull finish', (50, ['DB']), [0, 1, True]),
('boundary bust mid-turn reverts', (32, ['S10', 'T20', 'D16']), [0, 2, True]),
('control scoring turn', (101, ['T20', 'S1', 'S20']), [20, 1, False]),
('regression: bust reversion scope',
(10, ['S16', 'D18', 'T5', 'D20', 'D2', 'D4', 'S9', 'D16', 'D2']),
[6, 8, False]),
('regression: bust reversion scope',
(101, ['D9', 'T11', 'SB', 'D15', 'T19', 'S7']),
[18, 4, False]),
('variant scenario 1', (3, ['M', 'D19', 'T10', 'T8', 'D5', 'S4', 'M', 'S3']), [3, 6, False]),
('variant scenario 2', (101, ['D5', 'D12']), [67, 1, False])]]
for label, args, expected in cases[N - 1]:
check(label, run(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 |
|---|---|---|---|
| control checkout on double | [0, 1, True] | [0, 1, True] | Passed |
| boundary finish on single busts | [0, 2, True] | [0, 2, True] | Passed |
| boundary leave one busts | [20, 2, False] | [20, 2, False] | Passed |
| control bull finish | [0, 1, True] | [0, 1, True] | Passed |
| boundary bust mid-turn reverts | [0, 2, True] | [0, 2, True] | Passed |
| control scoring turn | [20, 1, False] | [20, 1, False] | Passed |
| regression: bust reversion scope | [14, 5, False] | [14, 5, False] | Passed |
| regression: bust reversion scope | [29, 4, False] | [29, 4, False] | Passed |
| variant scenario 1 | [45, 4, False] | [45, 4, False] | Passed |
| variant scenario 2 | [36, 4, False] | [36, 4, False] | Passed |
SHA-256 / 5ed3d0a1d01361928cf7df381f473e690c20f94221af572a9df5feafdbad60b8
Verification & scope
Stipulated, bounded toy contract stated in the contract field; not a claim of conformance with any governing body rulebook or operator house rules. 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:28.535308+00:00.
Case digest / c38866168016f32c113ab744a5e01c93ca15ed05195352feb33d1c42daed3c18