FA-82186 / Poker hand evaluation / Open access
Steel wheel announced as a royal flush · case 01
A-2-3-4-5 suited is announced as "Royal Flush".
ROOT CAUSE
Royal is decided by the presence of an ace rather than by an ace-high straight flush.
VERIFIED REPAIR
A royal flush is a straight flush whose top card (after wheel handling) is the ace.
Unsuccessful approach: Accepting king-high as royal still misnames a king-high straight flush.
Case contract
Input: five distinct cards. Return the showdown announcement: "Royal Flush", "Straight Flush, <top> high", "Four <plural>", "Full House, <trips plural> full of <pair plural>", "Flush, <top> high", "Straight, <top> high" (wheel is Five high), "Three <plural>", "Two Pair, <higher plural> and <lower plural>", "Pair of <plural>", "High Card, <top>". Rank names Two..Ace; plurals add "s" except Deuces and Sixes.
Why this case matters
Dealer announcements and hand histories must name the same hand the evaluator paid.
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'
NAME={2:'Two',3:'Three',4:'Four',5:'Five',6:'Six',7:'Seven',8:'Eight',9:'Nine',10:'Ten',11:'Jack',12:'Queen',13:'King',14:'Ace'}
def pl(v): return {2:'Deuces',6:'Sixes'}.get(v, NAME[v]+'s')
vals=sorted((R.index(c[0])+2 for c in x), reverse=True)
cnt=collections.Counter(vals)
groups=sorted(cnt, key=lambda v:(cnt[v],v), reverse=True)
shape=sorted(cnt.values(), reverse=True)
flush=len({c[1] for c in x})==1
wheel=vals==[14,5,4,3,2]
straight=len(cnt)==5 and (vals[0]-vals[4]==4 or wheel)
top=5 if wheel else vals[0]
if straight and flush: return 'Royal Flush' if vals[0]==14 else 'Straight Flush, %s high' % NAME[top]
if shape==[4,1]: return 'Four %s' % pl(groups[0])
if shape==[3,2]: return 'Full House, %s full of %s' % (pl(groups[0]), pl(groups[1]))
if flush: return 'Flush, %s high' % NAME[vals[0]]
if straight: return 'Straight, %s high' % NAME[top]
if shape==[3,1,1]: return 'Three %s' % pl(groups[0])
if shape==[2,2,1]: return 'Two Pair, %s and %s' % (pl(groups[0]), pl(groups[1]))
if shape==[2,1,1,1]: return 'Pair of %s' % pl(groups[0])
return 'High Card, %s' % NAME[vals[0]]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('pair of sixes', ['6h', '6d', 'Kc', '9s', '2h'], 'Pair of Sixes'),
('pair of deuces', ['2h', '2d', 'Kc', '9s', '5h'], 'Pair of Deuces'),
('wheel', ['Ah', '2d', '3c', '4s', '5h'], 'Straight, Five high'),
('steel wheel', ['As', '2s', '3s', '4s', '5s'], 'Straight Flush, Five high'),
('royal', ['Th', 'Jh', 'Qh', 'Kh', 'Ah'], 'Royal Flush'),
('king-high straight flush', ['9d', 'Td', 'Jd', 'Qd', 'Kd'], 'Straight Flush, King high'),
('threes full of kings', ['3h', '3d', '3c', 'Ks', 'Kh'], 'Full House, Threes full of Kings'),
('kings full of threes', ['Kh', 'Kd', 'Kc', '3s', '3h'], 'Full House, Kings full of Threes')],
[('steel wheel', ['As', '2s', '3s', '4s', '5s'], 'Straight Flush, Five high'),
('royal', ['Th', 'Jh', 'Qh', 'Kh', 'Ah'], 'Royal Flush'),
('king-high straight flush', ['9d', 'Td', 'Jd', 'Qd', 'Kd'], 'Straight Flush, King high'),
('threes full of kings', ['3h', '3d', '3c', 'Ks', 'Kh'], 'Full House, Threes full of Kings'),
('kings full of threes', ['Kh', 'Kd', 'Kc', '3s', '3h'], 'Full House, Kings full of Threes'),
('two pair ace kicker', ['Ah', 'Kd', 'Kc', '7s', '7h'], 'Two Pair, Kings and Sevens'),
('two pair low kicker', ['Kh', 'Kd', '7c', '7s', '2h'], 'Two Pair, Kings and Sevens'),
('pair below high cards', ['Ah', 'Kd', '5c', '5s', '9h'], 'Pair of Fives')],
[('steel wheel', ['As', '2s', '3s', '4s', '5s'], 'Straight Flush, Five high'),
('king-high straight flush', ['9d', 'Td', 'Jd', 'Qd', 'Kd'], 'Straight Flush, King high'),
('two pair ace kicker', ['Ah', 'Kd', 'Kc', '7s', '7h'], 'Two Pair, Kings and Sevens'),
('two pair low kicker', ['Kh', 'Kd', '7c', '7s', '2h'], 'Two Pair, Kings and Sevens'),
('pair below high cards', ['Ah', 'Kd', '5c', '5s', '9h'], 'Pair of Fives'),
('high card', ['Ah', 'Jd', '8c', '5s', '3h'], 'High Card, Ace'),
('four nines', ['9h', '9d', '9c', '9s', '2h'], 'Four Nines'),
('flush', ['2c', '7c', '9c', 'Jc', 'Qc'], 'Flush, Queen high')],
[('pair of sixes', ['6h', '6d', 'Kc', '9s', '2h'], 'Pair of Sixes'),
('steel wheel', ['As', '2s', '3s', '4s', '5s'], 'Straight Flush, Five high'),
('king-high straight flush', ['9d', 'Td', 'Jd', 'Qd', 'Kd'], 'Straight Flush, King high'),
('high card', ['Ah', 'Jd', '8c', '5s', '3h'], 'High Card, Ace'),
('four nines', ['9h', '9d', '9c', '9s', '2h'], 'Four Nines'),
('flush', ['2c', '7c', '9c', 'Jc', 'Qc'], 'Flush, Queen high'),
('six-high straight', ['2h', '3d', '4c', '5s', '6h'], 'Straight, Six high'),
('three sixes', ['6h', '6d', '6c', 'Ks', '2h'], 'Three Sixes')],
[('pair of sixes', ['6h', '6d', 'Kc', '9s', '2h'], 'Pair of Sixes'),
('pair of deuces', ['2h', '2d', 'Kc', '9s', '5h'], 'Pair of Deuces'),
('wheel', ['Ah', '2d', '3c', '4s', '5h'], 'Straight, Five high'),
('steel wheel', ['As', '2s', '3s', '4s', '5s'], 'Straight Flush, Five high'),
('royal', ['Th', 'Jh', 'Qh', 'Kh', 'Ah'], 'Royal Flush'),
('king-high straight flush', ['9d', 'Td', 'Jd', 'Qd', 'Kd'], 'Straight Flush, King high'),
('six-high straight', ['2h', '3d', '4c', '5s', '6h'], 'Straight, Six high'),
('three sixes', ['6h', '6d', '6c', 'Ks', '2h'], 'Three Sixes')]]
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 |
|---|---|---|---|
| pair of sixes | Pair of Sixes | Pair of Sixes | Passed |
| pair of deuces | Pair of Deuces | Pair of Deuces | Passed |
| wheel | Straight, Five high | Straight, Five high | Passed |
| steel wheel | Royal Flush | Straight Flush, Five high | Failed |
| royal | Royal Flush | Royal Flush | Passed |
| king-high straight flush | Straight Flush, King high | Straight Flush, King high | Passed |
| threes full of kings | Full House, Threes full of Kings | Full House, Threes full of Kings | Passed |
| kings full of threes | Full House, Kings full of Threes | Full House, Kings full of Threes | Passed |
SHA-256 / 07802bfbb10b704db8b5a90295d274a6aa2ae26ff15533f3aff33bfedcea2a90
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'
NAME={2:'Two',3:'Three',4:'Four',5:'Five',6:'Six',7:'Seven',8:'Eight',9:'Nine',10:'Ten',11:'Jack',12:'Queen',13:'King',14:'Ace'}
def pl(v): return {2:'Deuces',6:'Sixes'}.get(v, NAME[v]+'s')
vals=sorted((R.index(c[0])+2 for c in x), reverse=True)
cnt=collections.Counter(vals)
groups=sorted(cnt, key=lambda v:(cnt[v],v), reverse=True)
shape=sorted(cnt.values(), reverse=True)
flush=len({c[1] for c in x})==1
wheel=vals==[14,5,4,3,2]
straight=len(cnt)==5 and (vals[0]-vals[4]==4 or wheel)
top=5 if wheel else vals[0]
if straight and flush: return 'Royal Flush' if top>=13 else 'Straight Flush, %s high' % NAME[top]
if shape==[4,1]: return 'Four %s' % pl(groups[0])
if shape==[3,2]: return 'Full House, %s full of %s' % (pl(groups[0]), pl(groups[1]))
if flush: return 'Flush, %s high' % NAME[vals[0]]
if straight: return 'Straight, %s high' % NAME[top]
if shape==[3,1,1]: return 'Three %s' % pl(groups[0])
if shape==[2,2,1]: return 'Two Pair, %s and %s' % (pl(groups[0]), pl(groups[1]))
if shape==[2,1,1,1]: return 'Pair of %s' % pl(groups[0])
return 'High Card, %s' % NAME[vals[0]]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('pair of sixes', ['6h', '6d', 'Kc', '9s', '2h'], 'Pair of Sixes'),
('pair of deuces', ['2h', '2d', 'Kc', '9s', '5h'], 'Pair of Deuces'),
('wheel', ['Ah', '2d', '3c', '4s', '5h'], 'Straight, Five high'),
('steel wheel', ['As', '2s', '3s', '4s', '5s'], 'Straight Flush, Five high'),
('royal', ['Th', 'Jh', 'Qh', 'Kh', 'Ah'], 'Royal Flush'),
('king-high straight flush', ['9d', 'Td', 'Jd', 'Qd', 'Kd'], 'Straight Flush, King high'),
('threes full of kings', ['3h', '3d', '3c', 'Ks', 'Kh'], 'Full House, Threes full of Kings'),
('kings full of threes', ['Kh', 'Kd', 'Kc', '3s', '3h'], 'Full House, Kings full of Threes')],
[('steel wheel', ['As', '2s', '3s', '4s', '5s'], 'Straight Flush, Five high'),
('royal', ['Th', 'Jh', 'Qh', 'Kh', 'Ah'], 'Royal Flush'),
('king-high straight flush', ['9d', 'Td', 'Jd', 'Qd', 'Kd'], 'Straight Flush, King high'),
('threes full of kings', ['3h', '3d', '3c', 'Ks', 'Kh'], 'Full House, Threes full of Kings'),
('kings full of threes', ['Kh', 'Kd', 'Kc', '3s', '3h'], 'Full House, Kings full of Threes'),
('two pair ace kicker', ['Ah', 'Kd', 'Kc', '7s', '7h'], 'Two Pair, Kings and Sevens'),
('two pair low kicker', ['Kh', 'Kd', '7c', '7s', '2h'], 'Two Pair, Kings and Sevens'),
('pair below high cards', ['Ah', 'Kd', '5c', '5s', '9h'], 'Pair of Fives')],
[('steel wheel', ['As', '2s', '3s', '4s', '5s'], 'Straight Flush, Five high'),
('king-high straight flush', ['9d', 'Td', 'Jd', 'Qd', 'Kd'], 'Straight Flush, King high'),
('two pair ace kicker', ['Ah', 'Kd', 'Kc', '7s', '7h'], 'Two Pair, Kings and Sevens'),
('two pair low kicker', ['Kh', 'Kd', '7c', '7s', '2h'], 'Two Pair, Kings and Sevens'),
('pair below high cards', ['Ah', 'Kd', '5c', '5s', '9h'], 'Pair of Fives'),
('high card', ['Ah', 'Jd', '8c', '5s', '3h'], 'High Card, Ace'),
('four nines', ['9h', '9d', '9c', '9s', '2h'], 'Four Nines'),
('flush', ['2c', '7c', '9c', 'Jc', 'Qc'], 'Flush, Queen high')],
[('pair of sixes', ['6h', '6d', 'Kc', '9s', '2h'], 'Pair of Sixes'),
('steel wheel', ['As', '2s', '3s', '4s', '5s'], 'Straight Flush, Five high'),
('king-high straight flush', ['9d', 'Td', 'Jd', 'Qd', 'Kd'], 'Straight Flush, King high'),
('high card', ['Ah', 'Jd', '8c', '5s', '3h'], 'High Card, Ace'),
('four nines', ['9h', '9d', '9c', '9s', '2h'], 'Four Nines'),
('flush', ['2c', '7c', '9c', 'Jc', 'Qc'], 'Flush, Queen high'),
('six-high straight', ['2h', '3d', '4c', '5s', '6h'], 'Straight, Six high'),
('three sixes', ['6h', '6d', '6c', 'Ks', '2h'], 'Three Sixes')],
[('pair of sixes', ['6h', '6d', 'Kc', '9s', '2h'], 'Pair of Sixes'),
('pair of deuces', ['2h', '2d', 'Kc', '9s', '5h'], 'Pair of Deuces'),
('wheel', ['Ah', '2d', '3c', '4s', '5h'], 'Straight, Five high'),
('steel wheel', ['As', '2s', '3s', '4s', '5s'], 'Straight Flush, Five high'),
('royal', ['Th', 'Jh', 'Qh', 'Kh', 'Ah'], 'Royal Flush'),
('king-high straight flush', ['9d', 'Td', 'Jd', 'Qd', 'Kd'], 'Straight Flush, King high'),
('six-high straight', ['2h', '3d', '4c', '5s', '6h'], 'Straight, Six high'),
('three sixes', ['6h', '6d', '6c', 'Ks', '2h'], 'Three Sixes')]]
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 |
|---|---|---|---|
| pair of sixes | Pair of Sixes | Pair of Sixes | Passed |
| pair of deuces | Pair of Deuces | Pair of Deuces | Passed |
| wheel | Straight, Five high | Straight, Five high | Passed |
| steel wheel | Straight Flush, Five high | Straight Flush, Five high | Passed |
| royal | Royal Flush | Royal Flush | Passed |
| king-high straight flush | Royal Flush | Straight Flush, King high | Failed |
| threes full of kings | Full House, Threes full of Kings | Full House, Threes full of Kings | Passed |
| kings full of threes | Full House, Kings full of Threes | Full House, Kings full of Threes | Passed |
SHA-256 / bf5a8e43861fb94e7c89184de4a3ecf66fc47309d3195634e2c83bc074243169
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import collections
N = 1
observations = []
def solve(x):
R='23456789TJQKA'
NAME={2:'Two',3:'Three',4:'Four',5:'Five',6:'Six',7:'Seven',8:'Eight',9:'Nine',10:'Ten',11:'Jack',12:'Queen',13:'King',14:'Ace'}
def pl(v): return {2:'Deuces',6:'Sixes'}.get(v, NAME[v]+'s')
vals=sorted((R.index(c[0])+2 for c in x), reverse=True)
cnt=collections.Counter(vals)
groups=sorted(cnt, key=lambda v:(cnt[v],v), reverse=True)
shape=sorted(cnt.values(), reverse=True)
flush=len({c[1] for c in x})==1
wheel=vals==[14,5,4,3,2]
straight=len(cnt)==5 and (vals[0]-vals[4]==4 or wheel)
top=5 if wheel else vals[0]
if straight and flush: return 'Royal Flush' if top==14 else 'Straight Flush, %s high' % NAME[top]
if shape==[4,1]: return 'Four %s' % pl(groups[0])
if shape==[3,2]: return 'Full House, %s full of %s' % (pl(groups[0]), pl(groups[1]))
if flush: return 'Flush, %s high' % NAME[vals[0]]
if straight: return 'Straight, %s high' % NAME[top]
if shape==[3,1,1]: return 'Three %s' % pl(groups[0])
if shape==[2,2,1]: return 'Two Pair, %s and %s' % (pl(groups[0]), pl(groups[1]))
if shape==[2,1,1,1]: return 'Pair of %s' % pl(groups[0])
return 'High Card, %s' % NAME[vals[0]]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('pair of sixes', ['6h', '6d', 'Kc', '9s', '2h'], 'Pair of Sixes'),
('pair of deuces', ['2h', '2d', 'Kc', '9s', '5h'], 'Pair of Deuces'),
('wheel', ['Ah', '2d', '3c', '4s', '5h'], 'Straight, Five high'),
('steel wheel', ['As', '2s', '3s', '4s', '5s'], 'Straight Flush, Five high'),
('royal', ['Th', 'Jh', 'Qh', 'Kh', 'Ah'], 'Royal Flush'),
('king-high straight flush', ['9d', 'Td', 'Jd', 'Qd', 'Kd'], 'Straight Flush, King high'),
('threes full of kings', ['3h', '3d', '3c', 'Ks', 'Kh'], 'Full House, Threes full of Kings'),
('kings full of threes', ['Kh', 'Kd', 'Kc', '3s', '3h'], 'Full House, Kings full of Threes')],
[('steel wheel', ['As', '2s', '3s', '4s', '5s'], 'Straight Flush, Five high'),
('royal', ['Th', 'Jh', 'Qh', 'Kh', 'Ah'], 'Royal Flush'),
('king-high straight flush', ['9d', 'Td', 'Jd', 'Qd', 'Kd'], 'Straight Flush, King high'),
('threes full of kings', ['3h', '3d', '3c', 'Ks', 'Kh'], 'Full House, Threes full of Kings'),
('kings full of threes', ['Kh', 'Kd', 'Kc', '3s', '3h'], 'Full House, Kings full of Threes'),
('two pair ace kicker', ['Ah', 'Kd', 'Kc', '7s', '7h'], 'Two Pair, Kings and Sevens'),
('two pair low kicker', ['Kh', 'Kd', '7c', '7s', '2h'], 'Two Pair, Kings and Sevens'),
('pair below high cards', ['Ah', 'Kd', '5c', '5s', '9h'], 'Pair of Fives')],
[('steel wheel', ['As', '2s', '3s', '4s', '5s'], 'Straight Flush, Five high'),
('king-high straight flush', ['9d', 'Td', 'Jd', 'Qd', 'Kd'], 'Straight Flush, King high'),
('two pair ace kicker', ['Ah', 'Kd', 'Kc', '7s', '7h'], 'Two Pair, Kings and Sevens'),
('two pair low kicker', ['Kh', 'Kd', '7c', '7s', '2h'], 'Two Pair, Kings and Sevens'),
('pair below high cards', ['Ah', 'Kd', '5c', '5s', '9h'], 'Pair of Fives'),
('high card', ['Ah', 'Jd', '8c', '5s', '3h'], 'High Card, Ace'),
('four nines', ['9h', '9d', '9c', '9s', '2h'], 'Four Nines'),
('flush', ['2c', '7c', '9c', 'Jc', 'Qc'], 'Flush, Queen high')],
[('pair of sixes', ['6h', '6d', 'Kc', '9s', '2h'], 'Pair of Sixes'),
('steel wheel', ['As', '2s', '3s', '4s', '5s'], 'Straight Flush, Five high'),
('king-high straight flush', ['9d', 'Td', 'Jd', 'Qd', 'Kd'], 'Straight Flush, King high'),
('high card', ['Ah', 'Jd', '8c', '5s', '3h'], 'High Card, Ace'),
('four nines', ['9h', '9d', '9c', '9s', '2h'], 'Four Nines'),
('flush', ['2c', '7c', '9c', 'Jc', 'Qc'], 'Flush, Queen high'),
('six-high straight', ['2h', '3d', '4c', '5s', '6h'], 'Straight, Six high'),
('three sixes', ['6h', '6d', '6c', 'Ks', '2h'], 'Three Sixes')],
[('pair of sixes', ['6h', '6d', 'Kc', '9s', '2h'], 'Pair of Sixes'),
('pair of deuces', ['2h', '2d', 'Kc', '9s', '5h'], 'Pair of Deuces'),
('wheel', ['Ah', '2d', '3c', '4s', '5h'], 'Straight, Five high'),
('steel wheel', ['As', '2s', '3s', '4s', '5s'], 'Straight Flush, Five high'),
('royal', ['Th', 'Jh', 'Qh', 'Kh', 'Ah'], 'Royal Flush'),
('king-high straight flush', ['9d', 'Td', 'Jd', 'Qd', 'Kd'], 'Straight Flush, King high'),
('six-high straight', ['2h', '3d', '4c', '5s', '6h'], 'Straight, Six high'),
('three sixes', ['6h', '6d', '6c', 'Ks', '2h'], 'Three Sixes')]]
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 |
|---|---|---|---|
| pair of sixes | Pair of Sixes | Pair of Sixes | Passed |
| pair of deuces | Pair of Deuces | Pair of Deuces | Passed |
| wheel | Straight, Five high | Straight, Five high | Passed |
| steel wheel | Straight Flush, Five high | Straight Flush, Five high | Passed |
| royal | Royal Flush | Royal Flush | Passed |
| king-high straight flush | Straight Flush, King high | Straight Flush, King high | Passed |
| threes full of kings | Full House, Threes full of Kings | Full House, Threes full of Kings | Passed |
| kings full of threes | Full House, Kings full of Threes | Full House, Kings full of Threes | Passed |
SHA-256 / 974a119dfddcf0d40294affd8130c023fb28d28919e9b160461a62ecac850744
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:09.807810+00:00.
Case digest / 1bad5113a8c50dc0f42a1b647aec6b85bee67a7aed14147be5bd7634cf3ea7f4