FA-82281 / Poker hand evaluation / Open access
Dead cards still counted as live outs · case 01
Outs exposed in other players' hands are counted as live.
ROOT CAUSE
Only the player's own cards are subtracted from each completing rank.
VERIFIED REPAIR
Subtract every seen card: the player's cards and the dead cards.
Unsuccessful approach: Subtracting a single card when the rank has been seen at all undercounts when two or more copies are dead.
Case contract
Input: {"cards": known hole and board cards (4 to 6, no straight yet), "dead": other seen cards}. Return how many unseen cards would give the player a five-card straight (ace plays high or low): for every rank that completes a straight, count its four cards minus those already seen in cards or dead.
Why this case matters
Out counts feed pot-odds displays and all-in equity shortcuts.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
R='23456789TJQKA'
known=x['cards']+x.get('dead',[])
ranks={R.index(c[0])+2 for c in x['cards']}
def has(rs):
rs=set(rs)
if 14 in rs: rs.add(1)
return any(all(t-i in rs for i in range(5)) for t in range(5,15))
if has(ranks): return 0
outs=0
for r in range(2,15):
if has(ranks|{r}):
outs+=4-sum(1 for c in x['cards'] if R.index(c[0])+2==r)
return outs
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('open ended', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': []}, 8),
('gutshot', {'cards': ['8h', '9d', 'Jc', 'Qs', '2h'], 'dead': []}, 4),
('ace-low draw', {'cards': ['Ah', '2d', '3c', '4s', 'Kh'], 'dead': []}, 4),
('ace-high draw', {'cards': ['Ah', 'Kd', 'Qc', 'Js', '2h'], 'dead': []}, 4),
('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
5),
('paired board seen out', {'cards': ['8h', '9d', 'Tc', 'Js', 'Qh'], 'dead': []}, 0),
('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
('two dead copies of an out',
{'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5)],
[('ace-high draw', {'cards': ['Ah', 'Kd', 'Qc', 'Js', '2h'], 'dead': []}, 4),
('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
5),
('paired board seen out', {'cards': ['8h', '9d', 'Tc', 'Js', 'Qh'], 'dead': []}, 0),
('no draw', {'cards': ['2h', '7d', 'Tc', 'Ks', '4h'], 'dead': []}, 0),
('double gutshot', {'cards': ['7h', '9d', 'Tc', 'Js', 'Kh', '2c'], 'dead': []}, 8),
('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
('three to straight only', {'cards': ['8h', '9d', 'Tc', '2s', '3h'], 'dead': []}, 0),
('two dead copies of an out',
{'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5)],
[('open ended', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': []}, 8),
('gutshot', {'cards': ['8h', '9d', 'Jc', 'Qs', '2h'], 'dead': []}, 4),
('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
5),
('double gutshot', {'cards': ['7h', '9d', 'Tc', 'Js', 'Kh', '2c'], 'dead': []}, 8),
('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
('three to straight only', {'cards': ['8h', '9d', 'Tc', '2s', '3h'], 'dead': []}, 0),
('two dead copies of an out',
{'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5),
('open ender with seen nine', {'cards': ['5h', '6d', '7c', '8s', '8h'], 'dead': ['9c', '4d']},
6)],
[('open ended', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': []}, 8),
('gutshot', {'cards': ['8h', '9d', 'Jc', 'Qs', '2h'], 'dead': []}, 4),
('ace-low draw', {'cards': ['Ah', '2d', '3c', '4s', 'Kh'], 'dead': []}, 4),
('ace-high draw', {'cards': ['Ah', 'Kd', 'Qc', 'Js', '2h'], 'dead': []}, 4),
('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
5),
('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
('two dead copies of an out',
{'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5),
('open ender with seen nine', {'cards': ['5h', '6d', '7c', '8s', '8h'], 'dead': ['9c', '4d']},
6)],
[('open ended', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': []}, 8),
('gutshot', {'cards': ['8h', '9d', 'Jc', 'Qs', '2h'], 'dead': []}, 4),
('ace-low draw', {'cards': ['Ah', '2d', '3c', '4s', 'Kh'], 'dead': []}, 4),
('ace-high draw', {'cards': ['Ah', 'Kd', 'Qc', 'Js', '2h'], 'dead': []}, 4),
('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
5),
('paired board seen out', {'cards': ['8h', '9d', 'Tc', 'Js', 'Qh'], 'dead': []}, 0),
('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
('two dead copies of an out',
{'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5)]]
for label, args, expected in fixtures[N-1]:
try:
actual = solve(args)
except Exception as exc:
actual = 'error:' + type(exc).__name__
check(label, actual, 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 |
|---|---|---|---|
| open ended | 8 | 8 | Passed |
| gutshot | 4 | 4 | Passed |
| ace-low draw | 4 | 4 | Passed |
| ace-high draw | 4 | 4 | Passed |
| open ended with dead | 8 | 5 | Failed |
| paired board seen out | 0 | 0 | Passed |
| wheel gutshot with dead | 4 | 3 | Failed |
| two dead copies of an out | 8 | 5 | Failed |
SHA-256 / e66734082d7bcf38352d86c84d3e8c03ae0f69b7b5214c43bb8971fe25786897
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
R='23456789TJQKA'
known=x['cards']+x.get('dead',[])
ranks={R.index(c[0])+2 for c in x['cards']}
def has(rs):
rs=set(rs)
if 14 in rs: rs.add(1)
return any(all(t-i in rs for i in range(5)) for t in range(5,15))
if has(ranks): return 0
outs=0
for r in range(2,15):
if has(ranks|{r}):
outs+=4-(1 if any(R.index(c[0])+2==r for c in known) else 0)
return outs
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('open ended', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': []}, 8),
('gutshot', {'cards': ['8h', '9d', 'Jc', 'Qs', '2h'], 'dead': []}, 4),
('ace-low draw', {'cards': ['Ah', '2d', '3c', '4s', 'Kh'], 'dead': []}, 4),
('ace-high draw', {'cards': ['Ah', 'Kd', 'Qc', 'Js', '2h'], 'dead': []}, 4),
('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
5),
('paired board seen out', {'cards': ['8h', '9d', 'Tc', 'Js', 'Qh'], 'dead': []}, 0),
('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
('two dead copies of an out',
{'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5)],
[('ace-high draw', {'cards': ['Ah', 'Kd', 'Qc', 'Js', '2h'], 'dead': []}, 4),
('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
5),
('paired board seen out', {'cards': ['8h', '9d', 'Tc', 'Js', 'Qh'], 'dead': []}, 0),
('no draw', {'cards': ['2h', '7d', 'Tc', 'Ks', '4h'], 'dead': []}, 0),
('double gutshot', {'cards': ['7h', '9d', 'Tc', 'Js', 'Kh', '2c'], 'dead': []}, 8),
('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
('three to straight only', {'cards': ['8h', '9d', 'Tc', '2s', '3h'], 'dead': []}, 0),
('two dead copies of an out',
{'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5)],
[('open ended', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': []}, 8),
('gutshot', {'cards': ['8h', '9d', 'Jc', 'Qs', '2h'], 'dead': []}, 4),
('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
5),
('double gutshot', {'cards': ['7h', '9d', 'Tc', 'Js', 'Kh', '2c'], 'dead': []}, 8),
('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
('three to straight only', {'cards': ['8h', '9d', 'Tc', '2s', '3h'], 'dead': []}, 0),
('two dead copies of an out',
{'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5),
('open ender with seen nine', {'cards': ['5h', '6d', '7c', '8s', '8h'], 'dead': ['9c', '4d']},
6)],
[('open ended', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': []}, 8),
('gutshot', {'cards': ['8h', '9d', 'Jc', 'Qs', '2h'], 'dead': []}, 4),
('ace-low draw', {'cards': ['Ah', '2d', '3c', '4s', 'Kh'], 'dead': []}, 4),
('ace-high draw', {'cards': ['Ah', 'Kd', 'Qc', 'Js', '2h'], 'dead': []}, 4),
('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
5),
('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
('two dead copies of an out',
{'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5),
('open ender with seen nine', {'cards': ['5h', '6d', '7c', '8s', '8h'], 'dead': ['9c', '4d']},
6)],
[('open ended', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': []}, 8),
('gutshot', {'cards': ['8h', '9d', 'Jc', 'Qs', '2h'], 'dead': []}, 4),
('ace-low draw', {'cards': ['Ah', '2d', '3c', '4s', 'Kh'], 'dead': []}, 4),
('ace-high draw', {'cards': ['Ah', 'Kd', 'Qc', 'Js', '2h'], 'dead': []}, 4),
('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
5),
('paired board seen out', {'cards': ['8h', '9d', 'Tc', 'Js', 'Qh'], 'dead': []}, 0),
('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
('two dead copies of an out',
{'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5)]]
for label, args, expected in fixtures[N-1]:
try:
actual = solve(args)
except Exception as exc:
actual = 'error:' + type(exc).__name__
check(label, actual, 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 |
|---|---|---|---|
| open ended | 8 | 8 | Passed |
| gutshot | 4 | 4 | Passed |
| ace-low draw | 4 | 4 | Passed |
| ace-high draw | 4 | 4 | Passed |
| open ended with dead | 6 | 5 | Failed |
| paired board seen out | 0 | 0 | Passed |
| wheel gutshot with dead | 3 | 3 | Passed |
| two dead copies of an out | 6 | 5 | Failed |
SHA-256 / 1856ca18bf55cfd8f8e74348ce84c40f21770d35591f2eca36d966c9c346190d
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
R='23456789TJQKA'
known=x['cards']+x.get('dead',[])
ranks={R.index(c[0])+2 for c in x['cards']}
def has(rs):
rs=set(rs)
if 14 in rs: rs.add(1)
return any(all(t-i in rs for i in range(5)) for t in range(5,15))
if has(ranks): return 0
outs=0
for r in range(2,15):
if has(ranks|{r}):
outs+=4-sum(1 for c in known if R.index(c[0])+2==r)
return outs
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('open ended', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': []}, 8),
('gutshot', {'cards': ['8h', '9d', 'Jc', 'Qs', '2h'], 'dead': []}, 4),
('ace-low draw', {'cards': ['Ah', '2d', '3c', '4s', 'Kh'], 'dead': []}, 4),
('ace-high draw', {'cards': ['Ah', 'Kd', 'Qc', 'Js', '2h'], 'dead': []}, 4),
('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
5),
('paired board seen out', {'cards': ['8h', '9d', 'Tc', 'Js', 'Qh'], 'dead': []}, 0),
('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
('two dead copies of an out',
{'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5)],
[('ace-high draw', {'cards': ['Ah', 'Kd', 'Qc', 'Js', '2h'], 'dead': []}, 4),
('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
5),
('paired board seen out', {'cards': ['8h', '9d', 'Tc', 'Js', 'Qh'], 'dead': []}, 0),
('no draw', {'cards': ['2h', '7d', 'Tc', 'Ks', '4h'], 'dead': []}, 0),
('double gutshot', {'cards': ['7h', '9d', 'Tc', 'Js', 'Kh', '2c'], 'dead': []}, 8),
('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
('three to straight only', {'cards': ['8h', '9d', 'Tc', '2s', '3h'], 'dead': []}, 0),
('two dead copies of an out',
{'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5)],
[('open ended', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': []}, 8),
('gutshot', {'cards': ['8h', '9d', 'Jc', 'Qs', '2h'], 'dead': []}, 4),
('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
5),
('double gutshot', {'cards': ['7h', '9d', 'Tc', 'Js', 'Kh', '2c'], 'dead': []}, 8),
('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
('three to straight only', {'cards': ['8h', '9d', 'Tc', '2s', '3h'], 'dead': []}, 0),
('two dead copies of an out',
{'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5),
('open ender with seen nine', {'cards': ['5h', '6d', '7c', '8s', '8h'], 'dead': ['9c', '4d']},
6)],
[('open ended', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': []}, 8),
('gutshot', {'cards': ['8h', '9d', 'Jc', 'Qs', '2h'], 'dead': []}, 4),
('ace-low draw', {'cards': ['Ah', '2d', '3c', '4s', 'Kh'], 'dead': []}, 4),
('ace-high draw', {'cards': ['Ah', 'Kd', 'Qc', 'Js', '2h'], 'dead': []}, 4),
('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
5),
('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
('two dead copies of an out',
{'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5),
('open ender with seen nine', {'cards': ['5h', '6d', '7c', '8s', '8h'], 'dead': ['9c', '4d']},
6)],
[('open ended', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': []}, 8),
('gutshot', {'cards': ['8h', '9d', 'Jc', 'Qs', '2h'], 'dead': []}, 4),
('ace-low draw', {'cards': ['Ah', '2d', '3c', '4s', 'Kh'], 'dead': []}, 4),
('ace-high draw', {'cards': ['Ah', 'Kd', 'Qc', 'Js', '2h'], 'dead': []}, 4),
('open ended with dead', {'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', 'Qd', 'Qs']},
5),
('paired board seen out', {'cards': ['8h', '9d', 'Tc', 'Js', 'Qh'], 'dead': []}, 0),
('wheel gutshot with dead', {'cards': ['Ah', '2d', '4c', '5s', 'Jh'], 'dead': ['3h']}, 3),
('two dead copies of an out',
{'cards': ['8h', '9d', 'Tc', 'Js', '2h'], 'dead': ['7c', '7d', 'Qd']}, 5)]]
for label, args, expected in fixtures[N-1]:
try:
actual = solve(args)
except Exception as exc:
actual = 'error:' + type(exc).__name__
check(label, actual, 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 |
|---|---|---|---|
| open ended | 8 | 8 | Passed |
| gutshot | 4 | 4 | Passed |
| ace-low draw | 4 | 4 | Passed |
| ace-high draw | 4 | 4 | Passed |
| open ended with dead | 5 | 5 | Passed |
| paired board seen out | 0 | 0 | Passed |
| wheel gutshot with dead | 3 | 3 | Passed |
| two dead copies of an out | 5 | 5 | Passed |
SHA-256 / b5cf8a10f8154533dd76e0333b536ed58aed0451e3ce32ddf7bc6e110003c009
Verification & scope
A deterministic toy model with an explicitly stated contract; card strings are rank+suit (for example "As", "Td"); no claim of conformance to any casino or tournament rulebook. 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:10.740232+00:00.
Case digest / 1b606ecb08fe5eeb64568a45317544d2e5642eba34e67f190786529412b0f9c1