FA-82076 / Poker hand evaluation / Open access
Ace-to-five wheel treated as a straight in deuce-to-seven · case 01
A-2-3-4-5 is scored as a straight, losing to king-high hands it should beat and never being compared as ace high.
ROOT CAUSE
The high-hand wheel rule is copied into the lowball evaluator where the ace is always high.
THE FAILURE
The high-hand wheel rule is copied into the lowball evaluator where the ace is always high.
Unsuccessful approach: Treating an ace-to-deuce span as a straight marks any A-x-x-x-2 hand as a straight.
Case contract
Input: [hand_a, hand_b] five distinct cards each. Deuce-to-seven lowball: aces are always high, A-2-3-4-5 is not a straight, straights and flushes count against the hand, and the standard high-hand ordering is inverted so the weaker high hand wins. Return 1 if hand_a wins, -1 if hand_b wins, 0 for a tie.
Why this case matters
Lowball variants reuse high-hand evaluators with inverted outcomes, a common source of subtle bugs.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import collections
N = 1
observations = []
def solve(x):
R='23456789TJQKA'
def key(h):
vals=sorted((R.index(c[0])+2 for c in h), reverse=True)
cnt=collections.Counter(vals)
order=sorted(cnt, key=lambda v:(cnt[v],v), reverse=True)
shape=sorted(cnt.values(), reverse=True)
straight=len(cnt)==5 and (vals[0]-vals[4]==4 or vals==[14,5,4,3,2])
flush=len({c[1] for c in h})==1
if straight and flush: return (8,vals)
if shape==[4,1]: return (7,order)
if shape==[3,2]: return (6,order)
if flush: return (5,vals)
if straight: return (4,vals)
if shape==[3,1,1]: return (3,order)
if shape==[2,2,1]: return (2,order)
if shape==[2,1,1,1]: return (1,order)
return (0,vals)
ka,kb=key(x[0]),key(x[1])
if ka==kb: return 0
return 1 if ka<kb else -1
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('number one vs wheel', [['7h', '5d', '4c', '3s', '2h'], ['Ah', '2d', '3c', '4s', '5h']], 1),
('wheel is ace high', [['Ah', '2d', '3c', '4s', '5h'], ['Kh', 'Qd', 'Jc', '9s', '8h']], -1),
('seven low vs eight low', [['8h', '6d', '4c', '3s', '2h'], ['7c', '6h', '4d', '3c', '2d']], -1),
('flush counts against', [['2h', '4h', '5h', '6h', '8h'], ['9c', '6d', '4d', '3c', '2d']], -1),
('straight counts against', [['3h', '4d', '5c', '6s', '7h'], ['Kh', 'Qd', 'Jc', '9s', '7c']], -1),
('pair loses to king high', [['2h', '2d', '4c', '5s', '7h'], ['Kh', '8d', '6c', '4s', '3h']], -1),
('wheel vs pair', [['Ah', '2d', '3c', '4s', '5h'], ['3h', '3d', '6c', '8s', '9h']], 1),
('ace-deuce span vs pair', [['Ah', 'Jd', '8c', '6s', '2h'], ['4h', '4d', '6d', '8d', '9s']], 1)],
[('flush counts against', [['2h', '4h', '5h', '6h', '8h'], ['9c', '6d', '4d', '3c', '2d']], -1),
('straight counts against', [['3h', '4d', '5c', '6s', '7h'], ['Kh', 'Qd', 'Jc', '9s', '7c']], -1),
('pair loses to king high', [['2h', '2d', '4c', '5s', '7h'], ['Kh', '8d', '6c', '4s', '3h']], -1),
('ace-king gap hand', [['Ah', 'Kd', '7c', '4s', '2h'], ['Qh', 'Jd', 'Tc', '8s', '6h']], -1),
('straight flush vs flush', [['2c', '3c', '4c', '5c', '6c'], ['9d', '7d', '5d', '3d', '2d']], -1),
('tie', [['7h', '5d', '4c', '3s', '2h'], ['7c', '5h', '4d', '3c', '2d']], 0),
('wheel vs pair', [['Ah', '2d', '3c', '4s', '5h'], ['3h', '3d', '6c', '8s', '9h']], 1),
('ace-deuce span vs pair', [['Ah', 'Jd', '8c', '6s', '2h'], ['4h', '4d', '6d', '8d', '9s']], 1)],
[('ace-king gap hand', [['Ah', 'Kd', '7c', '4s', '2h'], ['Qh', 'Jd', 'Tc', '8s', '6h']], -1),
('straight flush vs flush', [['2c', '3c', '4c', '5c', '6c'], ['9d', '7d', '5d', '3d', '2d']], -1),
('tie', [['7h', '5d', '4c', '3s', '2h'], ['7c', '5h', '4d', '3c', '2d']], 0),
('ace high vs pair', [['Ah', 'Qd', '9c', '7s', '5h'], ['3h', '3d', '6c', '5s', '4h']], 1),
('both pairs lower pair wins', [['4h', '4d', 'Kc', 'Qs', 'Jh'], ['5h', '5d', '2c', '3s', '7h']],
1),
('wheel vs pair', [['Ah', '2d', '3c', '4s', '5h'], ['3h', '3d', '6c', '8s', '9h']], 1),
('ace-deuce span vs pair', [['Ah', 'Jd', '8c', '6s', '2h'], ['4h', '4d', '6d', '8d', '9s']], 1),
('ace high vs king high', [['Ah', '9d', '7c', '4s', '2h'], ['Kh', 'Qd', 'Jc', '9s', '8c']], -1)],
[('number one vs wheel', [['7h', '5d', '4c', '3s', '2h'], ['Ah', '2d', '3c', '4s', '5h']], 1),
('ace high vs pair', [['Ah', 'Qd', '9c', '7s', '5h'], ['3h', '3d', '6c', '5s', '4h']], 1),
('both pairs lower pair wins', [['4h', '4d', 'Kc', 'Qs', 'Jh'], ['5h', '5d', '2c', '3s', '7h']],
1),
('wheel vs pair', [['Ah', '2d', '3c', '4s', '5h'], ['3h', '3d', '6c', '8s', '9h']], 1),
('ace-deuce span vs pair', [['Ah', 'Jd', '8c', '6s', '2h'], ['4h', '4d', '6d', '8d', '9s']], 1),
('ace high vs king high', [['Ah', '9d', '7c', '4s', '2h'], ['Kh', 'Qd', 'Jc', '9s', '8c']], -1),
('second tie', [['Kh', 'Jd', '9c', '6s', '3h'], ['Kc', 'Jh', '9d', '6c', '3d']], 0),
('nine vs ten', [['9h', '7d', '5c', '3s', '2h'], ['Th', '4d', '3c', '6s', '2c']], 1)],
[('number one vs wheel', [['7h', '5d', '4c', '3s', '2h'], ['Ah', '2d', '3c', '4s', '5h']], 1),
('wheel is ace high', [['Ah', '2d', '3c', '4s', '5h'], ['Kh', 'Qd', 'Jc', '9s', '8h']], -1),
('seven low vs eight low', [['8h', '6d', '4c', '3s', '2h'], ['7c', '6h', '4d', '3c', '2d']], -1),
('flush counts against', [['2h', '4h', '5h', '6h', '8h'], ['9c', '6d', '4d', '3c', '2d']], -1),
('wheel vs pair', [['Ah', '2d', '3c', '4s', '5h'], ['3h', '3d', '6c', '8s', '9h']], 1),
('ace-deuce span vs pair', [['Ah', 'Jd', '8c', '6s', '2h'], ['4h', '4d', '6d', '8d', '9s']], 1),
('second tie', [['Kh', 'Jd', '9c', '6s', '3h'], ['Kc', 'Jh', '9d', '6c', '3d']], 0),
('nine vs ten', [['9h', '7d', '5c', '3s', '2h'], ['Th', '4d', '3c', '6s', '2c']], 1)]]
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 |
|---|---|---|---|
| number one vs wheel | 1 | 1 | Passed |
| wheel is ace high | -1 | -1 | Passed |
| seven low vs eight low | -1 | -1 | Passed |
| flush counts against | -1 | -1 | Passed |
| straight counts against | -1 | -1 | Passed |
| pair loses to king high | -1 | -1 | Passed |
| wheel vs pair | -1 | 1 | Failed |
| ace-deuce span vs pair | 1 | 1 | Passed |
SHA-256 / 43a16acfd52cbb4985f01ce61aa4c67da2f845ac7e845527750ace96b52acc30
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import collections
N = 1
observations = []
def solve(x):
R='23456789TJQKA'
def key(h):
vals=sorted((R.index(c[0])+2 for c in h), reverse=True)
cnt=collections.Counter(vals)
order=sorted(cnt, key=lambda v:(cnt[v],v), reverse=True)
shape=sorted(cnt.values(), reverse=True)
straight=len(cnt)==5 and (vals[0]-vals[4]==4 or vals[0]-vals[4]==12)
flush=len({c[1] for c in h})==1
if straight and flush: return (8,vals)
if shape==[4,1]: return (7,order)
if shape==[3,2]: return (6,order)
if flush: return (5,vals)
if straight: return (4,vals)
if shape==[3,1,1]: return (3,order)
if shape==[2,2,1]: return (2,order)
if shape==[2,1,1,1]: return (1,order)
return (0,vals)
ka,kb=key(x[0]),key(x[1])
if ka==kb: return 0
return 1 if ka<kb else -1
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('number one vs wheel', [['7h', '5d', '4c', '3s', '2h'], ['Ah', '2d', '3c', '4s', '5h']], 1),
('wheel is ace high', [['Ah', '2d', '3c', '4s', '5h'], ['Kh', 'Qd', 'Jc', '9s', '8h']], -1),
('seven low vs eight low', [['8h', '6d', '4c', '3s', '2h'], ['7c', '6h', '4d', '3c', '2d']], -1),
('flush counts against', [['2h', '4h', '5h', '6h', '8h'], ['9c', '6d', '4d', '3c', '2d']], -1),
('straight counts against', [['3h', '4d', '5c', '6s', '7h'], ['Kh', 'Qd', 'Jc', '9s', '7c']], -1),
('pair loses to king high', [['2h', '2d', '4c', '5s', '7h'], ['Kh', '8d', '6c', '4s', '3h']], -1),
('wheel vs pair', [['Ah', '2d', '3c', '4s', '5h'], ['3h', '3d', '6c', '8s', '9h']], 1),
('ace-deuce span vs pair', [['Ah', 'Jd', '8c', '6s', '2h'], ['4h', '4d', '6d', '8d', '9s']], 1)],
[('flush counts against', [['2h', '4h', '5h', '6h', '8h'], ['9c', '6d', '4d', '3c', '2d']], -1),
('straight counts against', [['3h', '4d', '5c', '6s', '7h'], ['Kh', 'Qd', 'Jc', '9s', '7c']], -1),
('pair loses to king high', [['2h', '2d', '4c', '5s', '7h'], ['Kh', '8d', '6c', '4s', '3h']], -1),
('ace-king gap hand', [['Ah', 'Kd', '7c', '4s', '2h'], ['Qh', 'Jd', 'Tc', '8s', '6h']], -1),
('straight flush vs flush', [['2c', '3c', '4c', '5c', '6c'], ['9d', '7d', '5d', '3d', '2d']], -1),
('tie', [['7h', '5d', '4c', '3s', '2h'], ['7c', '5h', '4d', '3c', '2d']], 0),
('wheel vs pair', [['Ah', '2d', '3c', '4s', '5h'], ['3h', '3d', '6c', '8s', '9h']], 1),
('ace-deuce span vs pair', [['Ah', 'Jd', '8c', '6s', '2h'], ['4h', '4d', '6d', '8d', '9s']], 1)],
[('ace-king gap hand', [['Ah', 'Kd', '7c', '4s', '2h'], ['Qh', 'Jd', 'Tc', '8s', '6h']], -1),
('straight flush vs flush', [['2c', '3c', '4c', '5c', '6c'], ['9d', '7d', '5d', '3d', '2d']], -1),
('tie', [['7h', '5d', '4c', '3s', '2h'], ['7c', '5h', '4d', '3c', '2d']], 0),
('ace high vs pair', [['Ah', 'Qd', '9c', '7s', '5h'], ['3h', '3d', '6c', '5s', '4h']], 1),
('both pairs lower pair wins', [['4h', '4d', 'Kc', 'Qs', 'Jh'], ['5h', '5d', '2c', '3s', '7h']],
1),
('wheel vs pair', [['Ah', '2d', '3c', '4s', '5h'], ['3h', '3d', '6c', '8s', '9h']], 1),
('ace-deuce span vs pair', [['Ah', 'Jd', '8c', '6s', '2h'], ['4h', '4d', '6d', '8d', '9s']], 1),
('ace high vs king high', [['Ah', '9d', '7c', '4s', '2h'], ['Kh', 'Qd', 'Jc', '9s', '8c']], -1)],
[('number one vs wheel', [['7h', '5d', '4c', '3s', '2h'], ['Ah', '2d', '3c', '4s', '5h']], 1),
('ace high vs pair', [['Ah', 'Qd', '9c', '7s', '5h'], ['3h', '3d', '6c', '5s', '4h']], 1),
('both pairs lower pair wins', [['4h', '4d', 'Kc', 'Qs', 'Jh'], ['5h', '5d', '2c', '3s', '7h']],
1),
('wheel vs pair', [['Ah', '2d', '3c', '4s', '5h'], ['3h', '3d', '6c', '8s', '9h']], 1),
('ace-deuce span vs pair', [['Ah', 'Jd', '8c', '6s', '2h'], ['4h', '4d', '6d', '8d', '9s']], 1),
('ace high vs king high', [['Ah', '9d', '7c', '4s', '2h'], ['Kh', 'Qd', 'Jc', '9s', '8c']], -1),
('second tie', [['Kh', 'Jd', '9c', '6s', '3h'], ['Kc', 'Jh', '9d', '6c', '3d']], 0),
('nine vs ten', [['9h', '7d', '5c', '3s', '2h'], ['Th', '4d', '3c', '6s', '2c']], 1)],
[('number one vs wheel', [['7h', '5d', '4c', '3s', '2h'], ['Ah', '2d', '3c', '4s', '5h']], 1),
('wheel is ace high', [['Ah', '2d', '3c', '4s', '5h'], ['Kh', 'Qd', 'Jc', '9s', '8h']], -1),
('seven low vs eight low', [['8h', '6d', '4c', '3s', '2h'], ['7c', '6h', '4d', '3c', '2d']], -1),
('flush counts against', [['2h', '4h', '5h', '6h', '8h'], ['9c', '6d', '4d', '3c', '2d']], -1),
('wheel vs pair', [['Ah', '2d', '3c', '4s', '5h'], ['3h', '3d', '6c', '8s', '9h']], 1),
('ace-deuce span vs pair', [['Ah', 'Jd', '8c', '6s', '2h'], ['4h', '4d', '6d', '8d', '9s']], 1),
('second tie', [['Kh', 'Jd', '9c', '6s', '3h'], ['Kc', 'Jh', '9d', '6c', '3d']], 0),
('nine vs ten', [['9h', '7d', '5c', '3s', '2h'], ['Th', '4d', '3c', '6s', '2c']], 1)]]
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 |
|---|---|---|---|
| number one vs wheel | 1 | 1 | Passed |
| wheel is ace high | -1 | -1 | Passed |
| seven low vs eight low | -1 | -1 | Passed |
| flush counts against | -1 | -1 | Passed |
| straight counts against | -1 | -1 | Passed |
| pair loses to king high | -1 | -1 | Passed |
| wheel vs pair | -1 | 1 | Failed |
| ace-deuce span vs pair | -1 | 1 | Failed |
SHA-256 / b6e45e670468144813d0cf729e60fcd8012abc710b2a54e0fff18aef8869c75e
HELD IN THE MEMBER ARCHIVE
The verified repair and its recorded checks are member-only.
This mechanism has 8 recorded checks per implementation. The open-access tier publishes the failure and the unsuccessful fix; the repaired source that passes every check, and the observations that prove it, are available to members.
Every case sharing this mechanism uses the same contract and the same repair, so this one record is held back for all of them.
Member access is invitation-based. Sign in with your invited account to inspect the repair.
Sign in to the archive ↗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:08.834345+00:00.
Case digest / 701939ae25da554261c4373e5b00c968c08bbb01e11cb119654d7b5ac0397f1e