FAILURE MAP
← Case archive

FA-83766 / Card game rule engines / Open access

Double arounds score twice the single value · case 01

Eight aces score 200 instead of 1000.

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

ROOT CAUSE

Arounds are multiplied by the count of complete sets.

VERIFIED REPAIR

A double around is worth ten times the single around.

Unsuccessful approach: Requiring more than two sets for the bonus scores a double around as a single.

Case contract

Input [hand, trump]. Arounds (one of the rank in each suit): A 100, K 80, Q 60, J 40; double around x10. Run in trump (A T K Q J) 150 each; marriages (K+Q same suit) 20, royal marriage in trump 40, but a K+Q used in a run is not also a royal marriage. Pinochle (JD+QS) 40, double pinochle 300. Return the meld total.

Why this case matters

Card-game engines, scoring apps and online tables apply this rule automatically on every hand.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
from collections import Counter
N = 1
observations = []
def solve(x):
    hand, trump = x
    cnt = Counter(hand)
    pts = 0
    for r, v in (('A', 100), ('K', 80), ('Q', 60), ('J', 40)):
        k = min(cnt[r + s] for s in 'SHDC')
        pts += v * k
    runs = min(cnt[r + trump] for r in 'ATKQJ')
    pts += 150 * runs
    for s in 'SHDC':
        m = min(cnt['K' + s], cnt['Q' + s])
        if s == trump:
            m -= runs
            pts += 40 * m
        else:
            pts += 20 * m
    p = min(cnt['JD'], cnt['QS'])
    pts += 300 if p == 2 else 40 * p
    return pts
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['9D', '9S', 'AC', 'AC', 'AD', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'KD'], 'C'], 1000], [[['9C', '9D', '9S', 'AC', 'AH', 'JH', 'JS', 'KH', 'KH', 'KS', 'QH', 'TD'], 'C'], 20], [[['9D', 'JC', 'JD', 'JD', 'JH', 'KD', 'KS', 'QH', 'QS', 'QS', 'TC', 'TD'], 'H'], 320], [[['AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'JD', 'JD', 'QS', 'QS'], 'D'], 1300], [[['9S', 'AH', 'AS', 'JC', 'JS', 'KD', 'KS', 'KS', 'QD', 'QS', 'TC', 'TS'], 'S'], 170], [[['AH', 'AH', 'AS', 'AS', 'JH', 'KC', 'KH', 'QH', 'QS', 'TH', 'TH', 'TS'], 'C'], 20], [[['9S', '9S', 'AC', 'JD', 'JD', 'KD', 'KS', 'QD', 'QS', 'QS', 'QS', 'TD'], 'D'], 360], [[['AC', 'AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'KC', 'QC', 'TC'], 'D'], 1020]], [[[['AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'JD', 'JD', 'QS', 'QS'], 'D'], 1300], [[['9C', 'AC', 'AC', 'AD', 'AH', 'AH', 'JD', 'JH', 'QC', 'QD', 'QH', 'TS'], 'C'], 0], [[['9C', '9D', '9S', 'AD', 'JH', 'JS', 'KC', 'QD', 'QH', 'TC', 'TD', 'TH'], 'D'], 0], [[['AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'AS', 'QC', 'TC', 'TD'], 'H'], 1000], [[['9C', '9H', 'AC', 'AS', 'JC', 'KD', 'KH', 'QC', 'QH', 'TD', 'TH', 'TH'], 'S'], 20], [[['9D', '9S', 'AS', 'JC', 'JH', 'JS', 'KD', 'KH', 'KS', 'QC', 'QD', 'QS'], 'D'], 60], [[['9C', 'AS', 'AS', 'JD', 'JH', 'JS', 'KC', 'KS', 'QC', 'QS', 'TD', 'TS'], 'S'], 210], [[['AC', 'AC', 'AC', 'AD', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'JC', 'TD'], 'C'], 1000]], [[[['9C', 'AS', 'JC', 'JH', 'KD', 'KD', 'KH', 'KS', 'QS', 'QS', 'TD', 'TH'], 'S'], 40], [[['AH', 'AH', 'JC', 'JH', 'JH', 'KH', 'KH', 'QH', 'QH', 'QS', 'TH', 'TH'], 'C'], 40], [[['AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'JD', 'JD', 'QS', 'QS'], 'H'], 1300], [[['9C', '9D', 'AC', 'AD', 'AD', 'JD', 'JH', 'KD', 'KD', 'QD', 'QH', 'TD'], 'C'], 20], [[['9D', '9S', 'AD', 'JD', 'JD', 'KS', 'QD', 'QD', 'QH', 'QS', 'QS', 'TH'], 'S'], 340], [[['AC', 'AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'KC', 'QC', 'TC'], 'D'], 1020], [[['AD', 'AH', 'AS', 'JD', 'JH', 'JS', 'KC', 'KD', 'QC', 'QD', 'QD', 'TD'], 'D'], 170], [[['AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'AS', 'KS', 'QS', 'TS'], 'C'], 1020]], [[[['9C', '9D', 'AC', 'AH', 'AH', 'KC', 'KD', 'KS', 'QC', 'QD', 'QS', 'TH'], 'H'], 60], [[['9C', '9C', 'AC', 'JD', 'KD', 'KD', 'KH', 'KS', 'QC', 'QH', 'TC', 'TD'], 'H'], 40], [[['9H', 'AC', 'AD', 'AS', 'JH', 'JS', 'KC', 'KD', 'QD', 'QH', 'TC', 'TD'], 'D'], 40], [[['AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'JC', 'KS', 'QH', 'TS'], 'H'], 1000], [[['9C', '9D', '9D', '9H', 'AC', 'AH', 'JC', 'KC', 'KS', 'TC', 'TD', 'TH'], 'S'], 0], [[['AH', 'AH', 'JH', 'JH', 'JS', 'KH', 'KH', 'QH', 'QH', 'TD', 'TH', 'TH'], 'D'], 40], [[['AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'JD', 'JD', 'QS', 'QS'], 'S'], 1300], [[['9C', '9H', 'AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'KS', 'TH'], 'H'], 1000]], [[[['9D', '9S', 'AH', 'JH', 'KC', 'KD', 'KS', 'QD', 'QD', 'TC', 'TC', 'TS'], 'D'], 40], [[['9D', 'AC', 'AH', 'JC', 'JH', 'JS', 'KC', 'KH', 'QC', 'TC', 'TH', 'TS'], 'S'], 20], [[['AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'JD', 'JD', 'QS', 'QS'], 'S'], 1300], [[['AH', 'AH', 'JH', 'JH', 'KD', 'KD', 'KH', 'KH', 'QH', 'QH', 'TH', 'TH'], 'C'], 40], [[['9C', '9D', '9S', '9S', 'AD', 'AD', 'AH', 'AS', 'JC', 'JD', 'KH', 'QS'], 'C'], 40], [[['9C', '9H', 'AD', 'JC', 'JD', 'JS', 'JS', 'KC', 'KD', 'KH', 'TD', 'TH'], 'D'], 0], [[['AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'JD', 'JD', 'QS', 'QS'], 'C'], 1300], [[['9C', 'AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'KC', 'QD', 'TH'], 'H'], 1000]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("meld points case %d" % i, solve(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 fixtureActualExpectedOutcome
meld points case 02001000Failed
meld points case 12020Passed
meld points case 2320320Passed
meld points case 35001300Failed
meld points case 4170170Passed
meld points case 52020Passed
meld points case 6360360Passed
meld points case 72201020Failed

SHA-256 / 0abe528b2f97629cdb065cdf961860f1e1cf851a5a912bb7c18416737e6594db

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
from collections import Counter
N = 1
observations = []
def solve(x):
    hand, trump = x
    cnt = Counter(hand)
    pts = 0
    for r, v in (('A', 100), ('K', 80), ('Q', 60), ('J', 40)):
        k = min(cnt[r + s] for s in 'SHDC')
        if k > 2:
            pts += v * 10
        elif k == 1:
            pts += v
    runs = min(cnt[r + trump] for r in 'ATKQJ')
    pts += 150 * runs
    for s in 'SHDC':
        m = min(cnt['K' + s], cnt['Q' + s])
        if s == trump:
            m -= runs
            pts += 40 * m
        else:
            pts += 20 * m
    p = min(cnt['JD'], cnt['QS'])
    pts += 300 if p == 2 else 40 * p
    return pts
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['9D', '9S', 'AC', 'AC', 'AD', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'KD'], 'C'], 1000], [[['9C', '9D', '9S', 'AC', 'AH', 'JH', 'JS', 'KH', 'KH', 'KS', 'QH', 'TD'], 'C'], 20], [[['9D', 'JC', 'JD', 'JD', 'JH', 'KD', 'KS', 'QH', 'QS', 'QS', 'TC', 'TD'], 'H'], 320], [[['AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'JD', 'JD', 'QS', 'QS'], 'D'], 1300], [[['9S', 'AH', 'AS', 'JC', 'JS', 'KD', 'KS', 'KS', 'QD', 'QS', 'TC', 'TS'], 'S'], 170], [[['AH', 'AH', 'AS', 'AS', 'JH', 'KC', 'KH', 'QH', 'QS', 'TH', 'TH', 'TS'], 'C'], 20], [[['9S', '9S', 'AC', 'JD', 'JD', 'KD', 'KS', 'QD', 'QS', 'QS', 'QS', 'TD'], 'D'], 360], [[['AC', 'AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'KC', 'QC', 'TC'], 'D'], 1020]], [[[['AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'JD', 'JD', 'QS', 'QS'], 'D'], 1300], [[['9C', 'AC', 'AC', 'AD', 'AH', 'AH', 'JD', 'JH', 'QC', 'QD', 'QH', 'TS'], 'C'], 0], [[['9C', '9D', '9S', 'AD', 'JH', 'JS', 'KC', 'QD', 'QH', 'TC', 'TD', 'TH'], 'D'], 0], [[['AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'AS', 'QC', 'TC', 'TD'], 'H'], 1000], [[['9C', '9H', 'AC', 'AS', 'JC', 'KD', 'KH', 'QC', 'QH', 'TD', 'TH', 'TH'], 'S'], 20], [[['9D', '9S', 'AS', 'JC', 'JH', 'JS', 'KD', 'KH', 'KS', 'QC', 'QD', 'QS'], 'D'], 60], [[['9C', 'AS', 'AS', 'JD', 'JH', 'JS', 'KC', 'KS', 'QC', 'QS', 'TD', 'TS'], 'S'], 210], [[['AC', 'AC', 'AC', 'AD', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'JC', 'TD'], 'C'], 1000]], [[[['9C', 'AS', 'JC', 'JH', 'KD', 'KD', 'KH', 'KS', 'QS', 'QS', 'TD', 'TH'], 'S'], 40], [[['AH', 'AH', 'JC', 'JH', 'JH', 'KH', 'KH', 'QH', 'QH', 'QS', 'TH', 'TH'], 'C'], 40], [[['AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'JD', 'JD', 'QS', 'QS'], 'H'], 1300], [[['9C', '9D', 'AC', 'AD', 'AD', 'JD', 'JH', 'KD', 'KD', 'QD', 'QH', 'TD'], 'C'], 20], [[['9D', '9S', 'AD', 'JD', 'JD', 'KS', 'QD', 'QD', 'QH', 'QS', 'QS', 'TH'], 'S'], 340], [[['AC', 'AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'KC', 'QC', 'TC'], 'D'], 1020], [[['AD', 'AH', 'AS', 'JD', 'JH', 'JS', 'KC', 'KD', 'QC', 'QD', 'QD', 'TD'], 'D'], 170], [[['AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'AS', 'KS', 'QS', 'TS'], 'C'], 1020]], [[[['9C', '9D', 'AC', 'AH', 'AH', 'KC', 'KD', 'KS', 'QC', 'QD', 'QS', 'TH'], 'H'], 60], [[['9C', '9C', 'AC', 'JD', 'KD', 'KD', 'KH', 'KS', 'QC', 'QH', 'TC', 'TD'], 'H'], 40], [[['9H', 'AC', 'AD', 'AS', 'JH', 'JS', 'KC', 'KD', 'QD', 'QH', 'TC', 'TD'], 'D'], 40], [[['AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'JC', 'KS', 'QH', 'TS'], 'H'], 1000], [[['9C', '9D', '9D', '9H', 'AC', 'AH', 'JC', 'KC', 'KS', 'TC', 'TD', 'TH'], 'S'], 0], [[['AH', 'AH', 'JH', 'JH', 'JS', 'KH', 'KH', 'QH', 'QH', 'TD', 'TH', 'TH'], 'D'], 40], [[['AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'JD', 'JD', 'QS', 'QS'], 'S'], 1300], [[['9C', '9H', 'AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'KS', 'TH'], 'H'], 1000]], [[[['9D', '9S', 'AH', 'JH', 'KC', 'KD', 'KS', 'QD', 'QD', 'TC', 'TC', 'TS'], 'D'], 40], [[['9D', 'AC', 'AH', 'JC', 'JH', 'JS', 'KC', 'KH', 'QC', 'TC', 'TH', 'TS'], 'S'], 20], [[['AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'JD', 'JD', 'QS', 'QS'], 'S'], 1300], [[['AH', 'AH', 'JH', 'JH', 'KD', 'KD', 'KH', 'KH', 'QH', 'QH', 'TH', 'TH'], 'C'], 40], [[['9C', '9D', '9S', '9S', 'AD', 'AD', 'AH', 'AS', 'JC', 'JD', 'KH', 'QS'], 'C'], 40], [[['9C', '9H', 'AD', 'JC', 'JD', 'JS', 'JS', 'KC', 'KD', 'KH', 'TD', 'TH'], 'D'], 0], [[['AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'JD', 'JD', 'QS', 'QS'], 'C'], 1300], [[['9C', 'AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'KC', 'QD', 'TH'], 'H'], 1000]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("meld points case %d" % i, solve(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 fixtureActualExpectedOutcome
meld points case 001000Failed
meld points case 12020Passed
meld points case 2320320Passed
meld points case 33001300Failed
meld points case 4170170Passed
meld points case 52020Passed
meld points case 6360360Passed
meld points case 7201020Failed

SHA-256 / 57f4fa028f85e6e3b1ead1987cbd4f1176ad209ab1d38619f918115bd99bf955

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
from collections import Counter
N = 1
observations = []
def solve(x):
    hand, trump = x
    cnt = Counter(hand)
    pts = 0
    for r, v in (('A', 100), ('K', 80), ('Q', 60), ('J', 40)):
        k = min(cnt[r + s] for s in 'SHDC')
        if k >= 2:
            pts += v * 10
        elif k == 1:
            pts += v
    runs = min(cnt[r + trump] for r in 'ATKQJ')
    pts += 150 * runs
    for s in 'SHDC':
        m = min(cnt['K' + s], cnt['Q' + s])
        if s == trump:
            m -= runs
            pts += 40 * m
        else:
            pts += 20 * m
    p = min(cnt['JD'], cnt['QS'])
    pts += 300 if p == 2 else 40 * p
    return pts
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[['9D', '9S', 'AC', 'AC', 'AD', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'KD'], 'C'], 1000], [[['9C', '9D', '9S', 'AC', 'AH', 'JH', 'JS', 'KH', 'KH', 'KS', 'QH', 'TD'], 'C'], 20], [[['9D', 'JC', 'JD', 'JD', 'JH', 'KD', 'KS', 'QH', 'QS', 'QS', 'TC', 'TD'], 'H'], 320], [[['AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'JD', 'JD', 'QS', 'QS'], 'D'], 1300], [[['9S', 'AH', 'AS', 'JC', 'JS', 'KD', 'KS', 'KS', 'QD', 'QS', 'TC', 'TS'], 'S'], 170], [[['AH', 'AH', 'AS', 'AS', 'JH', 'KC', 'KH', 'QH', 'QS', 'TH', 'TH', 'TS'], 'C'], 20], [[['9S', '9S', 'AC', 'JD', 'JD', 'KD', 'KS', 'QD', 'QS', 'QS', 'QS', 'TD'], 'D'], 360], [[['AC', 'AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'KC', 'QC', 'TC'], 'D'], 1020]], [[[['AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'JD', 'JD', 'QS', 'QS'], 'D'], 1300], [[['9C', 'AC', 'AC', 'AD', 'AH', 'AH', 'JD', 'JH', 'QC', 'QD', 'QH', 'TS'], 'C'], 0], [[['9C', '9D', '9S', 'AD', 'JH', 'JS', 'KC', 'QD', 'QH', 'TC', 'TD', 'TH'], 'D'], 0], [[['AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'AS', 'QC', 'TC', 'TD'], 'H'], 1000], [[['9C', '9H', 'AC', 'AS', 'JC', 'KD', 'KH', 'QC', 'QH', 'TD', 'TH', 'TH'], 'S'], 20], [[['9D', '9S', 'AS', 'JC', 'JH', 'JS', 'KD', 'KH', 'KS', 'QC', 'QD', 'QS'], 'D'], 60], [[['9C', 'AS', 'AS', 'JD', 'JH', 'JS', 'KC', 'KS', 'QC', 'QS', 'TD', 'TS'], 'S'], 210], [[['AC', 'AC', 'AC', 'AD', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'JC', 'TD'], 'C'], 1000]], [[[['9C', 'AS', 'JC', 'JH', 'KD', 'KD', 'KH', 'KS', 'QS', 'QS', 'TD', 'TH'], 'S'], 40], [[['AH', 'AH', 'JC', 'JH', 'JH', 'KH', 'KH', 'QH', 'QH', 'QS', 'TH', 'TH'], 'C'], 40], [[['AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'JD', 'JD', 'QS', 'QS'], 'H'], 1300], [[['9C', '9D', 'AC', 'AD', 'AD', 'JD', 'JH', 'KD', 'KD', 'QD', 'QH', 'TD'], 'C'], 20], [[['9D', '9S', 'AD', 'JD', 'JD', 'KS', 'QD', 'QD', 'QH', 'QS', 'QS', 'TH'], 'S'], 340], [[['AC', 'AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'KC', 'QC', 'TC'], 'D'], 1020], [[['AD', 'AH', 'AS', 'JD', 'JH', 'JS', 'KC', 'KD', 'QC', 'QD', 'QD', 'TD'], 'D'], 170], [[['AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'AS', 'KS', 'QS', 'TS'], 'C'], 1020]], [[[['9C', '9D', 'AC', 'AH', 'AH', 'KC', 'KD', 'KS', 'QC', 'QD', 'QS', 'TH'], 'H'], 60], [[['9C', '9C', 'AC', 'JD', 'KD', 'KD', 'KH', 'KS', 'QC', 'QH', 'TC', 'TD'], 'H'], 40], [[['9H', 'AC', 'AD', 'AS', 'JH', 'JS', 'KC', 'KD', 'QD', 'QH', 'TC', 'TD'], 'D'], 40], [[['AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'JC', 'KS', 'QH', 'TS'], 'H'], 1000], [[['9C', '9D', '9D', '9H', 'AC', 'AH', 'JC', 'KC', 'KS', 'TC', 'TD', 'TH'], 'S'], 0], [[['AH', 'AH', 'JH', 'JH', 'JS', 'KH', 'KH', 'QH', 'QH', 'TD', 'TH', 'TH'], 'D'], 40], [[['AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'JD', 'JD', 'QS', 'QS'], 'S'], 1300], [[['9C', '9H', 'AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'KS', 'TH'], 'H'], 1000]], [[[['9D', '9S', 'AH', 'JH', 'KC', 'KD', 'KS', 'QD', 'QD', 'TC', 'TC', 'TS'], 'D'], 40], [[['9D', 'AC', 'AH', 'JC', 'JH', 'JS', 'KC', 'KH', 'QC', 'TC', 'TH', 'TS'], 'S'], 20], [[['AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'JD', 'JD', 'QS', 'QS'], 'S'], 1300], [[['AH', 'AH', 'JH', 'JH', 'KD', 'KD', 'KH', 'KH', 'QH', 'QH', 'TH', 'TH'], 'C'], 40], [[['9C', '9D', '9S', '9S', 'AD', 'AD', 'AH', 'AS', 'JC', 'JD', 'KH', 'QS'], 'C'], 40], [[['9C', '9H', 'AD', 'JC', 'JD', 'JS', 'JS', 'KC', 'KD', 'KH', 'TD', 'TH'], 'D'], 0], [[['AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'JD', 'JD', 'QS', 'QS'], 'C'], 1300], [[['9C', 'AC', 'AC', 'AD', 'AD', 'AH', 'AH', 'AS', 'AS', 'KC', 'QD', 'TH'], 'H'], 1000]]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("meld points case %d" % i, solve(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 fixtureActualExpectedOutcome
meld points case 010001000Passed
meld points case 12020Passed
meld points case 2320320Passed
meld points case 313001300Passed
meld points case 4170170Passed
meld points case 52020Passed
meld points case 6360360Passed
meld points case 710201020Passed

SHA-256 / 8533494f9586b1dde6ae55293e27b348e23e89455e178c878bccfef8d97fb138

Verification & scope

A bounded toy rule contract stated explicitly in the contract field; cards are two-character codes (rank, suit). Not a complete implementation of any published rulebook or casino table 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:24.624002+00:00.

Case digest / 1bc8a3fb100e53a4c1a523567ccbd3d5fa1ef497e561abf0eba87eec4ff1da84