FAILURE MAP
← Case archive

FA-82176 / Poker hand evaluation / Open access

Announcer says "Sixs" and "Twos" · case 01

A pair of sixes is announced as "Pair of Sixs".

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

ROOT CAUSE

Plurals are formed by appending "s" to every rank name.

VERIFIED REPAIR

Use the irregular plurals Deuces and Sixes before the regular rule.

Unsuccessful approach: Special-casing only Sixes still announces "Twos" instead of "Deuces".

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 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')],
 [('pair of deuces', ['2h', '2d', 'Kc', '9s', '5h'], 'Pair of Deuces'),
  ('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'),
  ('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'),
  ('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'),
  ('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'),
  ('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 fixtureActualExpectedOutcome
pair of sixesPair of SixsPair of SixesFailed
pair of deucesPair of TwosPair of DeucesFailed
wheelStraight, Five highStraight, Five highPassed
steel wheelStraight Flush, Five highStraight Flush, Five highPassed
royalRoyal FlushRoyal FlushPassed
king-high straight flushStraight Flush, King highStraight Flush, King highPassed
threes full of kingsFull House, Threes full of KingsFull House, Threes full of KingsPassed
kings full of threesFull House, Kings full of ThreesFull House, Kings full of ThreesPassed

SHA-256 / 482a1661d8713ce13470ae90d96d3a3f84b7cbddd7388fc7a26a753fa6407aed

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 {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')],
 [('pair of deuces', ['2h', '2d', 'Kc', '9s', '5h'], 'Pair of Deuces'),
  ('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'),
  ('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'),
  ('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'),
  ('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'),
  ('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 fixtureActualExpectedOutcome
pair of sixesPair of SixesPair of SixesPassed
pair of deucesPair of TwosPair of DeucesFailed
wheelStraight, Five highStraight, Five highPassed
steel wheelStraight Flush, Five highStraight Flush, Five highPassed
royalRoyal FlushRoyal FlushPassed
king-high straight flushStraight Flush, King highStraight Flush, King highPassed
threes full of kingsFull House, Threes full of KingsFull House, Threes full of KingsPassed
kings full of threesFull House, Kings full of ThreesFull House, Kings full of ThreesPassed

SHA-256 / 5f3099b34decf4973adb1fa6e7e8fea3fe5b02c57ee22e0db38cf7e824c61790

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')],
 [('pair of deuces', ['2h', '2d', 'Kc', '9s', '5h'], 'Pair of Deuces'),
  ('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'),
  ('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'),
  ('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'),
  ('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'),
  ('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 fixtureActualExpectedOutcome
pair of sixesPair of SixesPair of SixesPassed
pair of deucesPair of DeucesPair of DeucesPassed
wheelStraight, Five highStraight, Five highPassed
steel wheelStraight Flush, Five highStraight Flush, Five highPassed
royalRoyal FlushRoyal FlushPassed
king-high straight flushStraight Flush, King highStraight Flush, King highPassed
threes full of kingsFull House, Threes full of KingsFull House, Threes full of KingsPassed
kings full of threesFull House, Kings full of ThreesFull House, Kings full of ThreesPassed

SHA-256 / 761f0070301a139e5150c54af332cbe0c819c33f04b4ba4b4f221cffd5f45493

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

Case digest / a458885ff7ee61e1c671c95a32a6575bb780d95ea627c2233ad8123338a67d29