FA-60811 / Loyalty points ledgers / Open access
Purchased points with volume bonus: price basis · case 01
Members are charged for the bonus points they receive free.
ROOT CAUSE
Price is computed on base plus bonus points.
VERIFIED REPAIR
Price only the purchased base thousands.
Unsuccessful approach: Pricing the unfloored request still charges for points that are not delivered.
Case contract
Input {requests:[pts], price_per_1000, tiers:[[min_base, bonus_bp]] ascending, annual_limit, bought_ytd}. Each request is floored to whole thousands ("too small" when that is 0). A request whose base would push purchased base points above annual_limit is rejected whole ("limit"); bonus points never count toward the limit. Bonus = floor(base*bp/10000) with bp from the highest tier whose min_base <= this request base. Price = base/1000*price_per_1000. Return {results:[[base,bonus,price]|reason], bought_ytd}.
Why this case matters
Member point balances, statements and the program liability depend on this ledger rule.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
bought = x['bought_ytd']
out = []
for req in x['requests']:
base = req // 1000 * 1000
if base == 0:
out.append('too small')
continue
if bought + base > x['annual_limit']:
out.append('limit')
continue
bp = 0
for mn, b in x['tiers']:
if base >= mn:
bp = b
bonus = base * bp // 10000
price = (base + bonus) // 1000 * x['price_per_1000']
bought += base
out.append([base, bonus, price])
return {'results': out, 'bought_ytd': bought}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['small buy', {'requests': [3501], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[3000, 0, 3750]], 'bought_ytd': 3000}], ['tier edge', {'requests': [5000], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 1000000, 'bought_ytd': 20000}, {'results': [[5000, 500, 6250]], 'bought_ytd': 25000}], ['big buy', {'requests': [21000], 'price_per_1000': 1100, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[21000, 5250, 23100]], 'bought_ytd': 21000}], ['too small', {'requests': [999, 1001], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': ['too small', [1000, 0, 1000]], 'bought_ytd': 1000}], ['limit hit', {'requests': [30000, 30000, 11000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 70000, 'bought_ytd': 5000}, {'results': [[30000, 7500, 30000], [30000, 7500, 30000], 'limit'], 'bought_ytd': 65000}], ['bonus not limited', {'requests': [20000, 20001], 'price_per_1000': 900, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 40000, 'bought_ytd': 0}, {'results': [[20000, 5000, 18000], [20000, 5000, 18000]], 'bought_ytd': 40000}], ['near limit', {'requests': [7000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 10000, 'bought_ytd': 4001}, {'results': ['limit'], 'bought_ytd': 4001}]], [['small buy', {'requests': [3502], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[3000, 0, 3750]], 'bought_ytd': 3000}], ['tier edge', {'requests': [5000], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 1000000, 'bought_ytd': 40000}, {'results': [[5000, 500, 6250]], 'bought_ytd': 45000}], ['big buy', {'requests': [21001], 'price_per_1000': 1100, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[21000, 5250, 23100]], 'bought_ytd': 21000}], ['too small', {'requests': [999, 1002], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': ['too small', [1000, 0, 1000]], 'bought_ytd': 1000}], ['limit hit', {'requests': [30000, 30000, 12000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 70000, 'bought_ytd': 5000}, {'results': [[30000, 7500, 30000], [30000, 7500, 30000], 'limit'], 'bought_ytd': 65000}], ['bonus not limited', {'requests': [20000, 20002], 'price_per_1000': 900, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 40000, 'bought_ytd': 0}, {'results': [[20000, 5000, 18000], [20000, 5000, 18000]], 'bought_ytd': 40000}], ['near limit', {'requests': [7000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 10000, 'bought_ytd': 4002}, {'results': ['limit'], 'bought_ytd': 4002}]], [['small buy', {'requests': [3503], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[3000, 0, 3750]], 'bought_ytd': 3000}], ['tier edge', {'requests': [5000], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 1000000, 'bought_ytd': 60000}, {'results': [[5000, 500, 6250]], 'bought_ytd': 65000}], ['big buy', {'requests': [21002], 'price_per_1000': 1100, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[21000, 5250, 23100]], 'bought_ytd': 21000}], ['too small', {'requests': [999, 1003], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': ['too small', [1000, 0, 1000]], 'bought_ytd': 1000}], ['limit hit', {'requests': [30000, 30000, 13000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 70000, 'bought_ytd': 5000}, {'results': [[30000, 7500, 30000], [30000, 7500, 30000], 'limit'], 'bought_ytd': 65000}], ['bonus not limited', {'requests': [20000, 20003], 'price_per_1000': 900, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 40000, 'bought_ytd': 0}, {'results': [[20000, 5000, 18000], [20000, 5000, 18000]], 'bought_ytd': 40000}], ['near limit', {'requests': [7000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 10000, 'bought_ytd': 4003}, {'results': ['limit'], 'bought_ytd': 4003}]], [['small buy', {'requests': [3504], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[3000, 0, 3750]], 'bought_ytd': 3000}], ['tier edge', {'requests': [5000], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 1000000, 'bought_ytd': 80000}, {'results': [[5000, 500, 6250]], 'bought_ytd': 85000}], ['big buy', {'requests': [21003], 'price_per_1000': 1100, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[21000, 5250, 23100]], 'bought_ytd': 21000}], ['too small', {'requests': [999, 1004], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': ['too small', [1000, 0, 1000]], 'bought_ytd': 1000}], ['limit hit', {'requests': [30000, 30000, 14000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 70000, 'bought_ytd': 5000}, {'results': [[30000, 7500, 30000], [30000, 7500, 30000], 'limit'], 'bought_ytd': 65000}], ['bonus not limited', {'requests': [20000, 20004], 'price_per_1000': 900, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 40000, 'bought_ytd': 0}, {'results': [[20000, 5000, 18000], [20000, 5000, 18000]], 'bought_ytd': 40000}], ['near limit', {'requests': [7000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 10000, 'bought_ytd': 4004}, {'results': ['limit'], 'bought_ytd': 4004}]], [['small buy', {'requests': [3505], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[3000, 0, 3750]], 'bought_ytd': 3000}], ['tier edge', {'requests': [5000], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 1000000, 'bought_ytd': 100000}, {'results': [[5000, 500, 6250]], 'bought_ytd': 105000}], ['big buy', {'requests': [21004], 'price_per_1000': 1100, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[21000, 5250, 23100]], 'bought_ytd': 21000}], ['too small', {'requests': [999, 1005], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': ['too small', [1000, 0, 1000]], 'bought_ytd': 1000}], ['limit hit', {'requests': [30000, 30000, 15000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 70000, 'bought_ytd': 5000}, {'results': [[30000, 7500, 30000], [30000, 7500, 30000], 'limit'], 'bought_ytd': 65000}], ['bonus not limited', {'requests': [20000, 20005], 'price_per_1000': 900, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 40000, 'bought_ytd': 0}, {'results': [[20000, 5000, 18000], [20000, 5000, 18000]], 'bought_ytd': 40000}], ['near limit', {'requests': [7000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 10000, 'bought_ytd': 4005}, {'results': ['limit'], 'bought_ytd': 4005}]]]
for label, args, expected in fixtures[N-1]:
check(label, 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| small buy | {'bought_ytd': 3000, 'results': [[3000, 0, 3750]]} | {'bought_ytd': 3000, 'results': [[3000, 0, 3750]]} | Passed |
| tier edge | {'bought_ytd': 25000, 'results': [[5000, 500, 6250]]} | {'bought_ytd': 25000, 'results': [[5000, 500, 6250]]} | Passed |
| big buy | {'bought_ytd': 21000, 'results': [[21000, 5250, 28600]]} | {'bought_ytd': 21000, 'results': [[21000, 5250, 23100]]} | Failed |
| too small | {'bought_ytd': 1000, 'results': ['too small', [1000, 0, 1000]]} | {'bought_ytd': 1000, 'results': ['too small', [1000, 0, 1000]]} | Passed |
| limit hit | {'bought_ytd': 65000, 'results': [[30000, 7500, 37000], [30000, 7500, 37000], 'limit']} | {'bought_ytd': 65000, 'results': [[30000, 7500, 30000], [30000, 7500, 30000], 'limit']} | Failed |
| bonus not limited | {'bought_ytd': 40000, 'results': [[20000, 5000, 22500], [20000, 5000, 22500]]} | {'bought_ytd': 40000, 'results': [[20000, 5000, 18000], [20000, 5000, 18000]]} | Failed |
| near limit | {'bought_ytd': 4001, 'results': ['limit']} | {'bought_ytd': 4001, 'results': ['limit']} | Passed |
SHA-256 / f3118e38741912c7234fa26177f0b403193d242aaf2cd0c9171ac79d89fe0d33
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
bought = x['bought_ytd']
out = []
for req in x['requests']:
base = req // 1000 * 1000
if base == 0:
out.append('too small')
continue
if bought + base > x['annual_limit']:
out.append('limit')
continue
bp = 0
for mn, b in x['tiers']:
if base >= mn:
bp = b
bonus = base * bp // 10000
price = req * x['price_per_1000'] // 1000
bought += base
out.append([base, bonus, price])
return {'results': out, 'bought_ytd': bought}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['small buy', {'requests': [3501], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[3000, 0, 3750]], 'bought_ytd': 3000}], ['tier edge', {'requests': [5000], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 1000000, 'bought_ytd': 20000}, {'results': [[5000, 500, 6250]], 'bought_ytd': 25000}], ['big buy', {'requests': [21000], 'price_per_1000': 1100, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[21000, 5250, 23100]], 'bought_ytd': 21000}], ['too small', {'requests': [999, 1001], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': ['too small', [1000, 0, 1000]], 'bought_ytd': 1000}], ['limit hit', {'requests': [30000, 30000, 11000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 70000, 'bought_ytd': 5000}, {'results': [[30000, 7500, 30000], [30000, 7500, 30000], 'limit'], 'bought_ytd': 65000}], ['bonus not limited', {'requests': [20000, 20001], 'price_per_1000': 900, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 40000, 'bought_ytd': 0}, {'results': [[20000, 5000, 18000], [20000, 5000, 18000]], 'bought_ytd': 40000}], ['near limit', {'requests': [7000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 10000, 'bought_ytd': 4001}, {'results': ['limit'], 'bought_ytd': 4001}]], [['small buy', {'requests': [3502], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[3000, 0, 3750]], 'bought_ytd': 3000}], ['tier edge', {'requests': [5000], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 1000000, 'bought_ytd': 40000}, {'results': [[5000, 500, 6250]], 'bought_ytd': 45000}], ['big buy', {'requests': [21001], 'price_per_1000': 1100, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[21000, 5250, 23100]], 'bought_ytd': 21000}], ['too small', {'requests': [999, 1002], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': ['too small', [1000, 0, 1000]], 'bought_ytd': 1000}], ['limit hit', {'requests': [30000, 30000, 12000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 70000, 'bought_ytd': 5000}, {'results': [[30000, 7500, 30000], [30000, 7500, 30000], 'limit'], 'bought_ytd': 65000}], ['bonus not limited', {'requests': [20000, 20002], 'price_per_1000': 900, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 40000, 'bought_ytd': 0}, {'results': [[20000, 5000, 18000], [20000, 5000, 18000]], 'bought_ytd': 40000}], ['near limit', {'requests': [7000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 10000, 'bought_ytd': 4002}, {'results': ['limit'], 'bought_ytd': 4002}]], [['small buy', {'requests': [3503], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[3000, 0, 3750]], 'bought_ytd': 3000}], ['tier edge', {'requests': [5000], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 1000000, 'bought_ytd': 60000}, {'results': [[5000, 500, 6250]], 'bought_ytd': 65000}], ['big buy', {'requests': [21002], 'price_per_1000': 1100, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[21000, 5250, 23100]], 'bought_ytd': 21000}], ['too small', {'requests': [999, 1003], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': ['too small', [1000, 0, 1000]], 'bought_ytd': 1000}], ['limit hit', {'requests': [30000, 30000, 13000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 70000, 'bought_ytd': 5000}, {'results': [[30000, 7500, 30000], [30000, 7500, 30000], 'limit'], 'bought_ytd': 65000}], ['bonus not limited', {'requests': [20000, 20003], 'price_per_1000': 900, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 40000, 'bought_ytd': 0}, {'results': [[20000, 5000, 18000], [20000, 5000, 18000]], 'bought_ytd': 40000}], ['near limit', {'requests': [7000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 10000, 'bought_ytd': 4003}, {'results': ['limit'], 'bought_ytd': 4003}]], [['small buy', {'requests': [3504], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[3000, 0, 3750]], 'bought_ytd': 3000}], ['tier edge', {'requests': [5000], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 1000000, 'bought_ytd': 80000}, {'results': [[5000, 500, 6250]], 'bought_ytd': 85000}], ['big buy', {'requests': [21003], 'price_per_1000': 1100, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[21000, 5250, 23100]], 'bought_ytd': 21000}], ['too small', {'requests': [999, 1004], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': ['too small', [1000, 0, 1000]], 'bought_ytd': 1000}], ['limit hit', {'requests': [30000, 30000, 14000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 70000, 'bought_ytd': 5000}, {'results': [[30000, 7500, 30000], [30000, 7500, 30000], 'limit'], 'bought_ytd': 65000}], ['bonus not limited', {'requests': [20000, 20004], 'price_per_1000': 900, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 40000, 'bought_ytd': 0}, {'results': [[20000, 5000, 18000], [20000, 5000, 18000]], 'bought_ytd': 40000}], ['near limit', {'requests': [7000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 10000, 'bought_ytd': 4004}, {'results': ['limit'], 'bought_ytd': 4004}]], [['small buy', {'requests': [3505], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[3000, 0, 3750]], 'bought_ytd': 3000}], ['tier edge', {'requests': [5000], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 1000000, 'bought_ytd': 100000}, {'results': [[5000, 500, 6250]], 'bought_ytd': 105000}], ['big buy', {'requests': [21004], 'price_per_1000': 1100, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[21000, 5250, 23100]], 'bought_ytd': 21000}], ['too small', {'requests': [999, 1005], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': ['too small', [1000, 0, 1000]], 'bought_ytd': 1000}], ['limit hit', {'requests': [30000, 30000, 15000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 70000, 'bought_ytd': 5000}, {'results': [[30000, 7500, 30000], [30000, 7500, 30000], 'limit'], 'bought_ytd': 65000}], ['bonus not limited', {'requests': [20000, 20005], 'price_per_1000': 900, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 40000, 'bought_ytd': 0}, {'results': [[20000, 5000, 18000], [20000, 5000, 18000]], 'bought_ytd': 40000}], ['near limit', {'requests': [7000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 10000, 'bought_ytd': 4005}, {'results': ['limit'], 'bought_ytd': 4005}]]]
for label, args, expected in fixtures[N-1]:
check(label, 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| small buy | {'bought_ytd': 3000, 'results': [[3000, 0, 4376]]} | {'bought_ytd': 3000, 'results': [[3000, 0, 3750]]} | Failed |
| tier edge | {'bought_ytd': 25000, 'results': [[5000, 500, 6250]]} | {'bought_ytd': 25000, 'results': [[5000, 500, 6250]]} | Passed |
| big buy | {'bought_ytd': 21000, 'results': [[21000, 5250, 23100]]} | {'bought_ytd': 21000, 'results': [[21000, 5250, 23100]]} | Passed |
| too small | {'bought_ytd': 1000, 'results': ['too small', [1000, 0, 1001]]} | {'bought_ytd': 1000, 'results': ['too small', [1000, 0, 1000]]} | Failed |
| limit hit | {'bought_ytd': 65000, 'results': [[30000, 7500, 30000], [30000, 7500, 30000], 'limit']} | {'bought_ytd': 65000, 'results': [[30000, 7500, 30000], [30000, 7500, 30000], 'limit']} | Passed |
| bonus not limited | {'bought_ytd': 40000, 'results': [[20000, 5000, 18000], [20000, 5000, 18000]]} | {'bought_ytd': 40000, 'results': [[20000, 5000, 18000], [20000, 5000, 18000]]} | Passed |
| near limit | {'bought_ytd': 4001, 'results': ['limit']} | {'bought_ytd': 4001, 'results': ['limit']} | Passed |
SHA-256 / d6779b81ae726d74604b0ece98fc999682c19a6438cb09f56e36bfac48abcc3d
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
bought = x['bought_ytd']
out = []
for req in x['requests']:
base = req // 1000 * 1000
if base == 0:
out.append('too small')
continue
if bought + base > x['annual_limit']:
out.append('limit')
continue
bp = 0
for mn, b in x['tiers']:
if base >= mn:
bp = b
bonus = base * bp // 10000
price = base // 1000 * x['price_per_1000']
bought += base
out.append([base, bonus, price])
return {'results': out, 'bought_ytd': bought}
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['small buy', {'requests': [3501], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[3000, 0, 3750]], 'bought_ytd': 3000}], ['tier edge', {'requests': [5000], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 1000000, 'bought_ytd': 20000}, {'results': [[5000, 500, 6250]], 'bought_ytd': 25000}], ['big buy', {'requests': [21000], 'price_per_1000': 1100, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[21000, 5250, 23100]], 'bought_ytd': 21000}], ['too small', {'requests': [999, 1001], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': ['too small', [1000, 0, 1000]], 'bought_ytd': 1000}], ['limit hit', {'requests': [30000, 30000, 11000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 70000, 'bought_ytd': 5000}, {'results': [[30000, 7500, 30000], [30000, 7500, 30000], 'limit'], 'bought_ytd': 65000}], ['bonus not limited', {'requests': [20000, 20001], 'price_per_1000': 900, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 40000, 'bought_ytd': 0}, {'results': [[20000, 5000, 18000], [20000, 5000, 18000]], 'bought_ytd': 40000}], ['near limit', {'requests': [7000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 10000, 'bought_ytd': 4001}, {'results': ['limit'], 'bought_ytd': 4001}]], [['small buy', {'requests': [3502], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[3000, 0, 3750]], 'bought_ytd': 3000}], ['tier edge', {'requests': [5000], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 1000000, 'bought_ytd': 40000}, {'results': [[5000, 500, 6250]], 'bought_ytd': 45000}], ['big buy', {'requests': [21001], 'price_per_1000': 1100, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[21000, 5250, 23100]], 'bought_ytd': 21000}], ['too small', {'requests': [999, 1002], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': ['too small', [1000, 0, 1000]], 'bought_ytd': 1000}], ['limit hit', {'requests': [30000, 30000, 12000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 70000, 'bought_ytd': 5000}, {'results': [[30000, 7500, 30000], [30000, 7500, 30000], 'limit'], 'bought_ytd': 65000}], ['bonus not limited', {'requests': [20000, 20002], 'price_per_1000': 900, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 40000, 'bought_ytd': 0}, {'results': [[20000, 5000, 18000], [20000, 5000, 18000]], 'bought_ytd': 40000}], ['near limit', {'requests': [7000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 10000, 'bought_ytd': 4002}, {'results': ['limit'], 'bought_ytd': 4002}]], [['small buy', {'requests': [3503], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[3000, 0, 3750]], 'bought_ytd': 3000}], ['tier edge', {'requests': [5000], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 1000000, 'bought_ytd': 60000}, {'results': [[5000, 500, 6250]], 'bought_ytd': 65000}], ['big buy', {'requests': [21002], 'price_per_1000': 1100, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[21000, 5250, 23100]], 'bought_ytd': 21000}], ['too small', {'requests': [999, 1003], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': ['too small', [1000, 0, 1000]], 'bought_ytd': 1000}], ['limit hit', {'requests': [30000, 30000, 13000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 70000, 'bought_ytd': 5000}, {'results': [[30000, 7500, 30000], [30000, 7500, 30000], 'limit'], 'bought_ytd': 65000}], ['bonus not limited', {'requests': [20000, 20003], 'price_per_1000': 900, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 40000, 'bought_ytd': 0}, {'results': [[20000, 5000, 18000], [20000, 5000, 18000]], 'bought_ytd': 40000}], ['near limit', {'requests': [7000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 10000, 'bought_ytd': 4003}, {'results': ['limit'], 'bought_ytd': 4003}]], [['small buy', {'requests': [3504], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[3000, 0, 3750]], 'bought_ytd': 3000}], ['tier edge', {'requests': [5000], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 1000000, 'bought_ytd': 80000}, {'results': [[5000, 500, 6250]], 'bought_ytd': 85000}], ['big buy', {'requests': [21003], 'price_per_1000': 1100, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[21000, 5250, 23100]], 'bought_ytd': 21000}], ['too small', {'requests': [999, 1004], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': ['too small', [1000, 0, 1000]], 'bought_ytd': 1000}], ['limit hit', {'requests': [30000, 30000, 14000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 70000, 'bought_ytd': 5000}, {'results': [[30000, 7500, 30000], [30000, 7500, 30000], 'limit'], 'bought_ytd': 65000}], ['bonus not limited', {'requests': [20000, 20004], 'price_per_1000': 900, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 40000, 'bought_ytd': 0}, {'results': [[20000, 5000, 18000], [20000, 5000, 18000]], 'bought_ytd': 40000}], ['near limit', {'requests': [7000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 10000, 'bought_ytd': 4004}, {'results': ['limit'], 'bought_ytd': 4004}]], [['small buy', {'requests': [3505], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[3000, 0, 3750]], 'bought_ytd': 3000}], ['tier edge', {'requests': [5000], 'price_per_1000': 1250, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 1000000, 'bought_ytd': 100000}, {'results': [[5000, 500, 6250]], 'bought_ytd': 105000}], ['big buy', {'requests': [21004], 'price_per_1000': 1100, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': [[21000, 5250, 23100]], 'bought_ytd': 21000}], ['too small', {'requests': [999, 1005], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 100000, 'bought_ytd': 0}, {'results': ['too small', [1000, 0, 1000]], 'bought_ytd': 1000}], ['limit hit', {'requests': [30000, 30000, 15000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 70000, 'bought_ytd': 5000}, {'results': [[30000, 7500, 30000], [30000, 7500, 30000], 'limit'], 'bought_ytd': 65000}], ['bonus not limited', {'requests': [20000, 20005], 'price_per_1000': 900, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 40000, 'bought_ytd': 0}, {'results': [[20000, 5000, 18000], [20000, 5000, 18000]], 'bought_ytd': 40000}], ['near limit', {'requests': [7000], 'price_per_1000': 1000, 'tiers': [[0, 0], [5000, 1000], [20000, 2500]], 'annual_limit': 10000, 'bought_ytd': 4005}, {'results': ['limit'], 'bought_ytd': 4005}]]]
for label, args, expected in fixtures[N-1]:
check(label, 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| small buy | {'bought_ytd': 3000, 'results': [[3000, 0, 3750]]} | {'bought_ytd': 3000, 'results': [[3000, 0, 3750]]} | Passed |
| tier edge | {'bought_ytd': 25000, 'results': [[5000, 500, 6250]]} | {'bought_ytd': 25000, 'results': [[5000, 500, 6250]]} | Passed |
| big buy | {'bought_ytd': 21000, 'results': [[21000, 5250, 23100]]} | {'bought_ytd': 21000, 'results': [[21000, 5250, 23100]]} | Passed |
| too small | {'bought_ytd': 1000, 'results': ['too small', [1000, 0, 1000]]} | {'bought_ytd': 1000, 'results': ['too small', [1000, 0, 1000]]} | Passed |
| limit hit | {'bought_ytd': 65000, 'results': [[30000, 7500, 30000], [30000, 7500, 30000], 'limit']} | {'bought_ytd': 65000, 'results': [[30000, 7500, 30000], [30000, 7500, 30000], 'limit']} | Passed |
| bonus not limited | {'bought_ytd': 40000, 'results': [[20000, 5000, 18000], [20000, 5000, 18000]]} | {'bought_ytd': 40000, 'results': [[20000, 5000, 18000], [20000, 5000, 18000]]} | Passed |
| near limit | {'bought_ytd': 4001, 'results': ['limit']} | {'bought_ytd': 4001, 'results': ['limit']} | Passed |
SHA-256 / 81a17f22fd26ace258d124ec03de8e821856178616e6689b9802a183e81c27c5
Verification & scope
Stipulated bounded loyalty-program model with explicit toy rules; not any real program terms. 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:46:49.176933+00:00.
Case digest / 20139068b80c880f01de81ba9148a7115c6b329aca57a3f9804b61e105d2c20e