broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    st = []
    ns = []
    for p in x['promos']:
        if p['kind'] == 'multiplier':
            e = x['base'] * (p['value'] - 100) // 100
        else:
            e = p['value']
        if p['cap'] > 0:
            e = min(e, p['cap'])
        (st if p['stackable'] else ns).append([e, p['id']])
    bonus = sum(e for e, _ in st)
    applied = [i for _, i in st]
    if ns:
        best = min(ns, key=lambda r: (-r[0], -r[1]))
        bonus += best[0]
        applied.append(best[1])
    return {'bonus': bonus, 'applied': sorted(applied)}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['mixed promos', {'base': 1001, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 200, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 300, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}]}, {'bonus': 1501, 'applied': [1, 3]}], ['caps', {'base': 2000, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 300, 'stackable': True, 'cap': 2501}, {'id': 2, 'kind': 'fixed', 'value': 900, 'stackable': True, 'cap': 500}]}, {'bonus': 3001, 'applied': [1, 2]}], ['tie on value', {'base': 400, 'promos': [{'id': 7, 'kind': 'fixed', 'value': 200, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}, {'id': 9, 'kind': 'fixed', 'value': 101, 'stackable': True, 'cap': 0}]}, {'bonus': 301, 'applied': [3, 9]}], ['no promos', {'base': 10, 'promos': []}, {'bonus': 0, 'applied': []}], ['only non stackable', {'base': 700, 'promos': [{'id': 4, 'kind': 'fixed', 'value': 50, 'stackable': False, 'cap': 0}, {'id': 5, 'kind': 'multiplier', 'value': 111, 'stackable': False, 'cap': 0}, {'id': 6, 'kind': 'fixed', 'value': 60, 'stackable': False, 'cap': 40}]}, {'bonus': 77, 'applied': [5]}], ['odd base', {'base': 334, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 125, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'multiplier', 'value': 175, 'stackable': True, 'cap': 0}]}, {'bonus': 333, 'applied': [1, 2]}], ['best beats stack', {'base': 100, 'promos': [{'id': 1, 'kind': 'fixed', 'value': 10, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 501, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'fixed', 'value': 20, 'stackable': True, 'cap': 0}]}, {'bonus': 531, 'applied': [1, 2, 3]}]], [['mixed promos', {'base': 1002, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 200, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 300, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}]}, {'bonus': 1503, 'applied': [1, 3]}], ['caps', {'base': 2000, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 300, 'stackable': True, 'cap': 2502}, {'id': 2, 'kind': 'fixed', 'value': 900, 'stackable': True, 'cap': 500}]}, {'bonus': 3002, 'applied': [1, 2]}], ['tie on value', {'base': 400, 'promos': [{'id': 7, 'kind': 'fixed', 'value': 200, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}, {'id': 9, 'kind': 'fixed', 'value': 102, 'stackable': True, 'cap': 0}]}, {'bonus': 302, 'applied': [3, 9]}], ['no promos', {'base': 20, 'promos': []}, {'bonus': 0, 'applied': []}], ['only non stackable', {'base': 700, 'promos': [{'id': 4, 'kind': 'fixed', 'value': 50, 'stackable': False, 'cap': 0}, {'id': 5, 'kind': 'multiplier', 'value': 112, 'stackable': False, 'cap': 0}, {'id': 6, 'kind': 'fixed', 'value': 60, 'stackable': False, 'cap': 40}]}, {'bonus': 84, 'applied': [5]}], ['odd base', {'base': 335, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 125, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'multiplier', 'value': 175, 'stackable': True, 'cap': 0}]}, {'bonus': 334, 'applied': [1, 2]}], ['best beats stack', {'base': 100, 'promos': [{'id': 1, 'kind': 'fixed', 'value': 10, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 502, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'fixed', 'value': 20, 'stackable': True, 'cap': 0}]}, {'bonus': 532, 'applied': [1, 2, 3]}]], [['mixed promos', {'base': 1003, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 200, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 300, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}]}, {'bonus': 1504, 'applied': [1, 3]}], ['caps', {'base': 2000, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 300, 'stackable': True, 'cap': 2503}, {'id': 2, 'kind': 'fixed', 'value': 900, 'stackable': True, 'cap': 500}]}, {'bonus': 3003, 'applied': [1, 2]}], ['tie on value', {'base': 400, 'promos': [{'id': 7, 'kind': 'fixed', 'value': 200, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}, {'id': 9, 'kind': 'fixed', 'value': 103, 'stackable': True, 'cap': 0}]}, {'bonus': 303, 'applied': [3, 9]}], ['no promos', {'base': 30, 'promos': []}, {'bonus': 0, 'applied': []}], ['only non stackable', {'base': 700, 'promos': [{'id': 4, 'kind': 'fixed', 'value': 50, 'stackable': False, 'cap': 0}, {'id': 5, 'kind': 'multiplier', 'value': 113, 'stackable': False, 'cap': 0}, {'id': 6, 'kind': 'fixed', 'value': 60, 'stackable': False, 'cap': 40}]}, {'bonus': 91, 'applied': [5]}], ['odd base', {'base': 336, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 125, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'multiplier', 'value': 175, 'stackable': True, 'cap': 0}]}, {'bonus': 336, 'applied': [1, 2]}], ['best beats stack', {'base': 100, 'promos': [{'id': 1, 'kind': 'fixed', 'value': 10, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 503, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'fixed', 'value': 20, 'stackable': True, 'cap': 0}]}, {'bonus': 533, 'applied': [1, 2, 3]}]], [['mixed promos', {'base': 1004, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 200, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 300, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}]}, {'bonus': 1506, 'applied': [1, 3]}], ['caps', {'base': 2000, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 300, 'stackable': True, 'cap': 2504}, {'id': 2, 'kind': 'fixed', 'value': 900, 'stackable': True, 'cap': 500}]}, {'bonus': 3004, 'applied': [1, 2]}], ['tie on value', {'base': 400, 'promos': [{'id': 7, 'kind': 'fixed', 'value': 200, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}, {'id': 9, 'kind': 'fixed', 'value': 104, 'stackable': True, 'cap': 0}]}, {'bonus': 304, 'applied': [3, 9]}], ['no promos', {'base': 40, 'promos': []}, {'bonus': 0, 'applied': []}], ['only non stackable', {'base': 700, 'promos': [{'id': 4, 'kind': 'fixed', 'value': 50, 'stackable': False, 'cap': 0}, {'id': 5, 'kind': 'multiplier', 'value': 114, 'stackable': False, 'cap': 0}, {'id': 6, 'kind': 'fixed', 'value': 60, 'stackable': False, 'cap': 40}]}, {'bonus': 98, 'applied': [5]}], ['odd base', {'base': 337, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 125, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'multiplier', 'value': 175, 'stackable': True, 'cap': 0}]}, {'bonus': 336, 'applied': [1, 2]}], ['best beats stack', {'base': 100, 'promos': [{'id': 1, 'kind': 'fixed', 'value': 10, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 504, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'fixed', 'value': 20, 'stackable': True, 'cap': 0}]}, {'bonus': 534, 'applied': [1, 2, 3]}]], [['mixed promos', {'base': 1005, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 200, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 300, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}]}, {'bonus': 1507, 'applied': [1, 3]}], ['caps', {'base': 2000, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 300, 'stackable': True, 'cap': 2505}, {'id': 2, 'kind': 'fixed', 'value': 900, 'stackable': True, 'cap': 500}]}, {'bonus': 3005, 'applied': [1, 2]}], ['tie on value', {'base': 400, 'promos': [{'id': 7, 'kind': 'fixed', 'value': 200, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}, {'id': 9, 'kind': 'fixed', 'value': 105, 'stackable': True, 'cap': 0}]}, {'bonus': 305, 'applied': [3, 9]}], ['no promos', {'base': 50, 'promos': []}, {'bonus': 0, 'applied': []}], ['only non stackable', {'base': 700, 'promos': [{'id': 4, 'kind': 'fixed', 'value': 50, 'stackable': False, 'cap': 0}, {'id': 5, 'kind': 'multiplier', 'value': 115, 'stackable': False, 'cap': 0}, {'id': 6, 'kind': 'fixed', 'value': 60, 'stackable': False, 'cap': 40}]}, {'bonus': 105, 'applied': [5]}], ['odd base', {'base': 338, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 125, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'multiplier', 'value': 175, 'stackable': True, 'cap': 0}]}, {'bonus': 337, 'applied': [1, 2]}], ['best beats stack', {'base': 100, 'promos': [{'id': 1, 'kind': 'fixed', 'value': 10, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 505, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'fixed', 'value': 20, 'stackable': True, 'cap': 0}]}, {'bonus': 535, 'applied': [1, 2, 3]}]]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    st = []
    ns = []
    for p in x['promos']:
        if p['kind'] == 'multiplier':
            e = x['base'] * (p['value'] - 100) // 100
        else:
            e = p['value']
        if p['cap'] > 0:
            e = min(e, p['cap'])
        (st if p['stackable'] else ns).append([e, p['id']])
    bonus = sum(e for e, _ in st)
    applied = [i for _, i in st]
    if ns:
        best = max(ns, key=lambda r: r[0])
        bonus += best[0]
        applied.append(best[1])
    return {'bonus': bonus, 'applied': sorted(applied)}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['mixed promos', {'base': 1001, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 200, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 300, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}]}, {'bonus': 1501, 'applied': [1, 3]}], ['caps', {'base': 2000, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 300, 'stackable': True, 'cap': 2501}, {'id': 2, 'kind': 'fixed', 'value': 900, 'stackable': True, 'cap': 500}]}, {'bonus': 3001, 'applied': [1, 2]}], ['tie on value', {'base': 400, 'promos': [{'id': 7, 'kind': 'fixed', 'value': 200, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}, {'id': 9, 'kind': 'fixed', 'value': 101, 'stackable': True, 'cap': 0}]}, {'bonus': 301, 'applied': [3, 9]}], ['no promos', {'base': 10, 'promos': []}, {'bonus': 0, 'applied': []}], ['only non stackable', {'base': 700, 'promos': [{'id': 4, 'kind': 'fixed', 'value': 50, 'stackable': False, 'cap': 0}, {'id': 5, 'kind': 'multiplier', 'value': 111, 'stackable': False, 'cap': 0}, {'id': 6, 'kind': 'fixed', 'value': 60, 'stackable': False, 'cap': 40}]}, {'bonus': 77, 'applied': [5]}], ['odd base', {'base': 334, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 125, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'multiplier', 'value': 175, 'stackable': True, 'cap': 0}]}, {'bonus': 333, 'applied': [1, 2]}], ['best beats stack', {'base': 100, 'promos': [{'id': 1, 'kind': 'fixed', 'value': 10, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 501, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'fixed', 'value': 20, 'stackable': True, 'cap': 0}]}, {'bonus': 531, 'applied': [1, 2, 3]}]], [['mixed promos', {'base': 1002, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 200, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 300, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}]}, {'bonus': 1503, 'applied': [1, 3]}], ['caps', {'base': 2000, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 300, 'stackable': True, 'cap': 2502}, {'id': 2, 'kind': 'fixed', 'value': 900, 'stackable': True, 'cap': 500}]}, {'bonus': 3002, 'applied': [1, 2]}], ['tie on value', {'base': 400, 'promos': [{'id': 7, 'kind': 'fixed', 'value': 200, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}, {'id': 9, 'kind': 'fixed', 'value': 102, 'stackable': True, 'cap': 0}]}, {'bonus': 302, 'applied': [3, 9]}], ['no promos', {'base': 20, 'promos': []}, {'bonus': 0, 'applied': []}], ['only non stackable', {'base': 700, 'promos': [{'id': 4, 'kind': 'fixed', 'value': 50, 'stackable': False, 'cap': 0}, {'id': 5, 'kind': 'multiplier', 'value': 112, 'stackable': False, 'cap': 0}, {'id': 6, 'kind': 'fixed', 'value': 60, 'stackable': False, 'cap': 40}]}, {'bonus': 84, 'applied': [5]}], ['odd base', {'base': 335, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 125, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'multiplier', 'value': 175, 'stackable': True, 'cap': 0}]}, {'bonus': 334, 'applied': [1, 2]}], ['best beats stack', {'base': 100, 'promos': [{'id': 1, 'kind': 'fixed', 'value': 10, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 502, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'fixed', 'value': 20, 'stackable': True, 'cap': 0}]}, {'bonus': 532, 'applied': [1, 2, 3]}]], [['mixed promos', {'base': 1003, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 200, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 300, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}]}, {'bonus': 1504, 'applied': [1, 3]}], ['caps', {'base': 2000, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 300, 'stackable': True, 'cap': 2503}, {'id': 2, 'kind': 'fixed', 'value': 900, 'stackable': True, 'cap': 500}]}, {'bonus': 3003, 'applied': [1, 2]}], ['tie on value', {'base': 400, 'promos': [{'id': 7, 'kind': 'fixed', 'value': 200, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}, {'id': 9, 'kind': 'fixed', 'value': 103, 'stackable': True, 'cap': 0}]}, {'bonus': 303, 'applied': [3, 9]}], ['no promos', {'base': 30, 'promos': []}, {'bonus': 0, 'applied': []}], ['only non stackable', {'base': 700, 'promos': [{'id': 4, 'kind': 'fixed', 'value': 50, 'stackable': False, 'cap': 0}, {'id': 5, 'kind': 'multiplier', 'value': 113, 'stackable': False, 'cap': 0}, {'id': 6, 'kind': 'fixed', 'value': 60, 'stackable': False, 'cap': 40}]}, {'bonus': 91, 'applied': [5]}], ['odd base', {'base': 336, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 125, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'multiplier', 'value': 175, 'stackable': True, 'cap': 0}]}, {'bonus': 336, 'applied': [1, 2]}], ['best beats stack', {'base': 100, 'promos': [{'id': 1, 'kind': 'fixed', 'value': 10, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 503, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'fixed', 'value': 20, 'stackable': True, 'cap': 0}]}, {'bonus': 533, 'applied': [1, 2, 3]}]], [['mixed promos', {'base': 1004, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 200, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 300, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}]}, {'bonus': 1506, 'applied': [1, 3]}], ['caps', {'base': 2000, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 300, 'stackable': True, 'cap': 2504}, {'id': 2, 'kind': 'fixed', 'value': 900, 'stackable': True, 'cap': 500}]}, {'bonus': 3004, 'applied': [1, 2]}], ['tie on value', {'base': 400, 'promos': [{'id': 7, 'kind': 'fixed', 'value': 200, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}, {'id': 9, 'kind': 'fixed', 'value': 104, 'stackable': True, 'cap': 0}]}, {'bonus': 304, 'applied': [3, 9]}], ['no promos', {'base': 40, 'promos': []}, {'bonus': 0, 'applied': []}], ['only non stackable', {'base': 700, 'promos': [{'id': 4, 'kind': 'fixed', 'value': 50, 'stackable': False, 'cap': 0}, {'id': 5, 'kind': 'multiplier', 'value': 114, 'stackable': False, 'cap': 0}, {'id': 6, 'kind': 'fixed', 'value': 60, 'stackable': False, 'cap': 40}]}, {'bonus': 98, 'applied': [5]}], ['odd base', {'base': 337, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 125, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'multiplier', 'value': 175, 'stackable': True, 'cap': 0}]}, {'bonus': 336, 'applied': [1, 2]}], ['best beats stack', {'base': 100, 'promos': [{'id': 1, 'kind': 'fixed', 'value': 10, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 504, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'fixed', 'value': 20, 'stackable': True, 'cap': 0}]}, {'bonus': 534, 'applied': [1, 2, 3]}]], [['mixed promos', {'base': 1005, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 200, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 300, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}]}, {'bonus': 1507, 'applied': [1, 3]}], ['caps', {'base': 2000, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 300, 'stackable': True, 'cap': 2505}, {'id': 2, 'kind': 'fixed', 'value': 900, 'stackable': True, 'cap': 500}]}, {'bonus': 3005, 'applied': [1, 2]}], ['tie on value', {'base': 400, 'promos': [{'id': 7, 'kind': 'fixed', 'value': 200, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}, {'id': 9, 'kind': 'fixed', 'value': 105, 'stackable': True, 'cap': 0}]}, {'bonus': 305, 'applied': [3, 9]}], ['no promos', {'base': 50, 'promos': []}, {'bonus': 0, 'applied': []}], ['only non stackable', {'base': 700, 'promos': [{'id': 4, 'kind': 'fixed', 'value': 50, 'stackable': False, 'cap': 0}, {'id': 5, 'kind': 'multiplier', 'value': 115, 'stackable': False, 'cap': 0}, {'id': 6, 'kind': 'fixed', 'value': 60, 'stackable': False, 'cap': 40}]}, {'bonus': 105, 'applied': [5]}], ['odd base', {'base': 338, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 125, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'multiplier', 'value': 175, 'stackable': True, 'cap': 0}]}, {'bonus': 337, 'applied': [1, 2]}], ['best beats stack', {'base': 100, 'promos': [{'id': 1, 'kind': 'fixed', 'value': 10, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 505, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'fixed', 'value': 20, 'stackable': True, 'cap': 0}]}, {'bonus': 535, 'applied': [1, 2, 3]}]]]
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)

prompt:
When two exclusive promos tie, the promo with the higher id is recorded as applied.

Input {base, promos:[{id,kind,value,stackable,cap}]}. A multiplier promo (value in percent) gives floor(base*(value-100)/100) extra; a fixed promo gives value. Each extra is capped at cap when cap > 0. All stackable extras apply; of the non-stackable promos only the single best capped extra applies (ties to the lower id), in addition to the stackable ones. Return {bonus, applied ids sorted}.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    st = []
    ns = []
    for p in x['promos']:
        if p['kind'] == 'multiplier':
            e = x['base'] * (p['value'] - 100) // 100
        else:
            e = p['value']
        if p['cap'] > 0:
            e = min(e, p['cap'])
        (st if p['stackable'] else ns).append([e, p['id']])
    bonus = sum(e for e, _ in st)
    applied = [i for _, i in st]
    for e, i in ns:
        bonus += e
        applied.append(i)
    return {'bonus': bonus, 'applied': sorted(applied)}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['mixed promos', {'base': 1001, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 200, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 300, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}]}, {'bonus': 1501, 'applied': [1, 3]}], ['caps', {'base': 2000, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 300, 'stackable': True, 'cap': 2501}, {'id': 2, 'kind': 'fixed', 'value': 900, 'stackable': True, 'cap': 500}]}, {'bonus': 3001, 'applied': [1, 2]}], ['tie on value', {'base': 400, 'promos': [{'id': 7, 'kind': 'fixed', 'value': 200, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}, {'id': 9, 'kind': 'fixed', 'value': 101, 'stackable': True, 'cap': 0}]}, {'bonus': 301, 'applied': [3, 9]}], ['no promos', {'base': 10, 'promos': []}, {'bonus': 0, 'applied': []}], ['only non stackable', {'base': 700, 'promos': [{'id': 4, 'kind': 'fixed', 'value': 50, 'stackable': False, 'cap': 0}, {'id': 5, 'kind': 'multiplier', 'value': 111, 'stackable': False, 'cap': 0}, {'id': 6, 'kind': 'fixed', 'value': 60, 'stackable': False, 'cap': 40}]}, {'bonus': 77, 'applied': [5]}], ['odd base', {'base': 334, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 125, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'multiplier', 'value': 175, 'stackable': True, 'cap': 0}]}, {'bonus': 333, 'applied': [1, 2]}], ['best beats stack', {'base': 100, 'promos': [{'id': 1, 'kind': 'fixed', 'value': 10, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 501, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'fixed', 'value': 20, 'stackable': True, 'cap': 0}]}, {'bonus': 531, 'applied': [1, 2, 3]}]], [['mixed promos', {'base': 1002, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 200, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 300, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}]}, {'bonus': 1503, 'applied': [1, 3]}], ['caps', {'base': 2000, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 300, 'stackable': True, 'cap': 2502}, {'id': 2, 'kind': 'fixed', 'value': 900, 'stackable': True, 'cap': 500}]}, {'bonus': 3002, 'applied': [1, 2]}], ['tie on value', {'base': 400, 'promos': [{'id': 7, 'kind': 'fixed', 'value': 200, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}, {'id': 9, 'kind': 'fixed', 'value': 102, 'stackable': True, 'cap': 0}]}, {'bonus': 302, 'applied': [3, 9]}], ['no promos', {'base': 20, 'promos': []}, {'bonus': 0, 'applied': []}], ['only non stackable', {'base': 700, 'promos': [{'id': 4, 'kind': 'fixed', 'value': 50, 'stackable': False, 'cap': 0}, {'id': 5, 'kind': 'multiplier', 'value': 112, 'stackable': False, 'cap': 0}, {'id': 6, 'kind': 'fixed', 'value': 60, 'stackable': False, 'cap': 40}]}, {'bonus': 84, 'applied': [5]}], ['odd base', {'base': 335, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 125, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'multiplier', 'value': 175, 'stackable': True, 'cap': 0}]}, {'bonus': 334, 'applied': [1, 2]}], ['best beats stack', {'base': 100, 'promos': [{'id': 1, 'kind': 'fixed', 'value': 10, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 502, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'fixed', 'value': 20, 'stackable': True, 'cap': 0}]}, {'bonus': 532, 'applied': [1, 2, 3]}]], [['mixed promos', {'base': 1003, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 200, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 300, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}]}, {'bonus': 1504, 'applied': [1, 3]}], ['caps', {'base': 2000, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 300, 'stackable': True, 'cap': 2503}, {'id': 2, 'kind': 'fixed', 'value': 900, 'stackable': True, 'cap': 500}]}, {'bonus': 3003, 'applied': [1, 2]}], ['tie on value', {'base': 400, 'promos': [{'id': 7, 'kind': 'fixed', 'value': 200, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}, {'id': 9, 'kind': 'fixed', 'value': 103, 'stackable': True, 'cap': 0}]}, {'bonus': 303, 'applied': [3, 9]}], ['no promos', {'base': 30, 'promos': []}, {'bonus': 0, 'applied': []}], ['only non stackable', {'base': 700, 'promos': [{'id': 4, 'kind': 'fixed', 'value': 50, 'stackable': False, 'cap': 0}, {'id': 5, 'kind': 'multiplier', 'value': 113, 'stackable': False, 'cap': 0}, {'id': 6, 'kind': 'fixed', 'value': 60, 'stackable': False, 'cap': 40}]}, {'bonus': 91, 'applied': [5]}], ['odd base', {'base': 336, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 125, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'multiplier', 'value': 175, 'stackable': True, 'cap': 0}]}, {'bonus': 336, 'applied': [1, 2]}], ['best beats stack', {'base': 100, 'promos': [{'id': 1, 'kind': 'fixed', 'value': 10, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 503, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'fixed', 'value': 20, 'stackable': True, 'cap': 0}]}, {'bonus': 533, 'applied': [1, 2, 3]}]], [['mixed promos', {'base': 1004, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 200, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 300, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}]}, {'bonus': 1506, 'applied': [1, 3]}], ['caps', {'base': 2000, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 300, 'stackable': True, 'cap': 2504}, {'id': 2, 'kind': 'fixed', 'value': 900, 'stackable': True, 'cap': 500}]}, {'bonus': 3004, 'applied': [1, 2]}], ['tie on value', {'base': 400, 'promos': [{'id': 7, 'kind': 'fixed', 'value': 200, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}, {'id': 9, 'kind': 'fixed', 'value': 104, 'stackable': True, 'cap': 0}]}, {'bonus': 304, 'applied': [3, 9]}], ['no promos', {'base': 40, 'promos': []}, {'bonus': 0, 'applied': []}], ['only non stackable', {'base': 700, 'promos': [{'id': 4, 'kind': 'fixed', 'value': 50, 'stackable': False, 'cap': 0}, {'id': 5, 'kind': 'multiplier', 'value': 114, 'stackable': False, 'cap': 0}, {'id': 6, 'kind': 'fixed', 'value': 60, 'stackable': False, 'cap': 40}]}, {'bonus': 98, 'applied': [5]}], ['odd base', {'base': 337, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 125, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'multiplier', 'value': 175, 'stackable': True, 'cap': 0}]}, {'bonus': 336, 'applied': [1, 2]}], ['best beats stack', {'base': 100, 'promos': [{'id': 1, 'kind': 'fixed', 'value': 10, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 504, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'fixed', 'value': 20, 'stackable': True, 'cap': 0}]}, {'bonus': 534, 'applied': [1, 2, 3]}]], [['mixed promos', {'base': 1005, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 200, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 300, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}]}, {'bonus': 1507, 'applied': [1, 3]}], ['caps', {'base': 2000, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 300, 'stackable': True, 'cap': 2505}, {'id': 2, 'kind': 'fixed', 'value': 900, 'stackable': True, 'cap': 500}]}, {'bonus': 3005, 'applied': [1, 2]}], ['tie on value', {'base': 400, 'promos': [{'id': 7, 'kind': 'fixed', 'value': 200, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}, {'id': 9, 'kind': 'fixed', 'value': 105, 'stackable': True, 'cap': 0}]}, {'bonus': 305, 'applied': [3, 9]}], ['no promos', {'base': 50, 'promos': []}, {'bonus': 0, 'applied': []}], ['only non stackable', {'base': 700, 'promos': [{'id': 4, 'kind': 'fixed', 'value': 50, 'stackable': False, 'cap': 0}, {'id': 5, 'kind': 'multiplier', 'value': 115, 'stackable': False, 'cap': 0}, {'id': 6, 'kind': 'fixed', 'value': 60, 'stackable': False, 'cap': 40}]}, {'bonus': 105, 'applied': [5]}], ['odd base', {'base': 338, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 125, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'multiplier', 'value': 175, 'stackable': True, 'cap': 0}]}, {'bonus': 337, 'applied': [1, 2]}], ['best beats stack', {'base': 100, 'promos': [{'id': 1, 'kind': 'fixed', 'value': 10, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 505, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'fixed', 'value': 20, 'stackable': True, 'cap': 0}]}, {'bonus': 535, 'applied': [1, 2, 3]}]]]
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)

meaning: Fixture-count band, not measured model difficulty

deps: stdlib

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    st = []
    ns = []
    for p in x['promos']:
        if p['kind'] == 'multiplier':
            e = x['base'] * (p['value'] - 100) // 100
        else:
            e = p['value']
        if p['cap'] > 0:
            e = min(e, p['cap'])
        (st if p['stackable'] else ns).append([e, p['id']])
    bonus = sum(e for e, _ in st)
    applied = [i for _, i in st]
    best = min(ns, key=lambda r: (-r[0], r[1])) if ns else None
    if best and best[0] > bonus:
        bonus = best[0]
        applied = [best[1]]
    return {'bonus': bonus, 'applied': sorted(applied)}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['mixed promos', {'base': 1001, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 200, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 300, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}]}, {'bonus': 1501, 'applied': [1, 3]}], ['caps', {'base': 2000, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 300, 'stackable': True, 'cap': 2501}, {'id': 2, 'kind': 'fixed', 'value': 900, 'stackable': True, 'cap': 500}]}, {'bonus': 3001, 'applied': [1, 2]}], ['tie on value', {'base': 400, 'promos': [{'id': 7, 'kind': 'fixed', 'value': 200, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}, {'id': 9, 'kind': 'fixed', 'value': 101, 'stackable': True, 'cap': 0}]}, {'bonus': 301, 'applied': [3, 9]}], ['no promos', {'base': 10, 'promos': []}, {'bonus': 0, 'applied': []}], ['only non stackable', {'base': 700, 'promos': [{'id': 4, 'kind': 'fixed', 'value': 50, 'stackable': False, 'cap': 0}, {'id': 5, 'kind': 'multiplier', 'value': 111, 'stackable': False, 'cap': 0}, {'id': 6, 'kind': 'fixed', 'value': 60, 'stackable': False, 'cap': 40}]}, {'bonus': 77, 'applied': [5]}], ['odd base', {'base': 334, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 125, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'multiplier', 'value': 175, 'stackable': True, 'cap': 0}]}, {'bonus': 333, 'applied': [1, 2]}], ['best beats stack', {'base': 100, 'promos': [{'id': 1, 'kind': 'fixed', 'value': 10, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 501, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'fixed', 'value': 20, 'stackable': True, 'cap': 0}]}, {'bonus': 531, 'applied': [1, 2, 3]}]], [['mixed promos', {'base': 1002, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 200, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 300, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}]}, {'bonus': 1503, 'applied': [1, 3]}], ['caps', {'base': 2000, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 300, 'stackable': True, 'cap': 2502}, {'id': 2, 'kind': 'fixed', 'value': 900, 'stackable': True, 'cap': 500}]}, {'bonus': 3002, 'applied': [1, 2]}], ['tie on value', {'base': 400, 'promos': [{'id': 7, 'kind': 'fixed', 'value': 200, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}, {'id': 9, 'kind': 'fixed', 'value': 102, 'stackable': True, 'cap': 0}]}, {'bonus': 302, 'applied': [3, 9]}], ['no promos', {'base': 20, 'promos': []}, {'bonus': 0, 'applied': []}], ['only non stackable', {'base': 700, 'promos': [{'id': 4, 'kind': 'fixed', 'value': 50, 'stackable': False, 'cap': 0}, {'id': 5, 'kind': 'multiplier', 'value': 112, 'stackable': False, 'cap': 0}, {'id': 6, 'kind': 'fixed', 'value': 60, 'stackable': False, 'cap': 40}]}, {'bonus': 84, 'applied': [5]}], ['odd base', {'base': 335, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 125, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'multiplier', 'value': 175, 'stackable': True, 'cap': 0}]}, {'bonus': 334, 'applied': [1, 2]}], ['best beats stack', {'base': 100, 'promos': [{'id': 1, 'kind': 'fixed', 'value': 10, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 502, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'fixed', 'value': 20, 'stackable': True, 'cap': 0}]}, {'bonus': 532, 'applied': [1, 2, 3]}]], [['mixed promos', {'base': 1003, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 200, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 300, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}]}, {'bonus': 1504, 'applied': [1, 3]}], ['caps', {'base': 2000, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 300, 'stackable': True, 'cap': 2503}, {'id': 2, 'kind': 'fixed', 'value': 900, 'stackable': True, 'cap': 500}]}, {'bonus': 3003, 'applied': [1, 2]}], ['tie on value', {'base': 400, 'promos': [{'id': 7, 'kind': 'fixed', 'value': 200, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}, {'id': 9, 'kind': 'fixed', 'value': 103, 'stackable': True, 'cap': 0}]}, {'bonus': 303, 'applied': [3, 9]}], ['no promos', {'base': 30, 'promos': []}, {'bonus': 0, 'applied': []}], ['only non stackable', {'base': 700, 'promos': [{'id': 4, 'kind': 'fixed', 'value': 50, 'stackable': False, 'cap': 0}, {'id': 5, 'kind': 'multiplier', 'value': 113, 'stackable': False, 'cap': 0}, {'id': 6, 'kind': 'fixed', 'value': 60, 'stackable': False, 'cap': 40}]}, {'bonus': 91, 'applied': [5]}], ['odd base', {'base': 336, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 125, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'multiplier', 'value': 175, 'stackable': True, 'cap': 0}]}, {'bonus': 336, 'applied': [1, 2]}], ['best beats stack', {'base': 100, 'promos': [{'id': 1, 'kind': 'fixed', 'value': 10, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 503, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'fixed', 'value': 20, 'stackable': True, 'cap': 0}]}, {'bonus': 533, 'applied': [1, 2, 3]}]], [['mixed promos', {'base': 1004, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 200, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 300, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}]}, {'bonus': 1506, 'applied': [1, 3]}], ['caps', {'base': 2000, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 300, 'stackable': True, 'cap': 2504}, {'id': 2, 'kind': 'fixed', 'value': 900, 'stackable': True, 'cap': 500}]}, {'bonus': 3004, 'applied': [1, 2]}], ['tie on value', {'base': 400, 'promos': [{'id': 7, 'kind': 'fixed', 'value': 200, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}, {'id': 9, 'kind': 'fixed', 'value': 104, 'stackable': True, 'cap': 0}]}, {'bonus': 304, 'applied': [3, 9]}], ['no promos', {'base': 40, 'promos': []}, {'bonus': 0, 'applied': []}], ['only non stackable', {'base': 700, 'promos': [{'id': 4, 'kind': 'fixed', 'value': 50, 'stackable': False, 'cap': 0}, {'id': 5, 'kind': 'multiplier', 'value': 114, 'stackable': False, 'cap': 0}, {'id': 6, 'kind': 'fixed', 'value': 60, 'stackable': False, 'cap': 40}]}, {'bonus': 98, 'applied': [5]}], ['odd base', {'base': 337, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 125, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'multiplier', 'value': 175, 'stackable': True, 'cap': 0}]}, {'bonus': 336, 'applied': [1, 2]}], ['best beats stack', {'base': 100, 'promos': [{'id': 1, 'kind': 'fixed', 'value': 10, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 504, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'fixed', 'value': 20, 'stackable': True, 'cap': 0}]}, {'bonus': 534, 'applied': [1, 2, 3]}]], [['mixed promos', {'base': 1005, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 200, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 300, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}]}, {'bonus': 1507, 'applied': [1, 3]}], ['caps', {'base': 2000, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 300, 'stackable': True, 'cap': 2505}, {'id': 2, 'kind': 'fixed', 'value': 900, 'stackable': True, 'cap': 500}]}, {'bonus': 3005, 'applied': [1, 2]}], ['tie on value', {'base': 400, 'promos': [{'id': 7, 'kind': 'fixed', 'value': 200, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'multiplier', 'value': 150, 'stackable': False, 'cap': 0}, {'id': 9, 'kind': 'fixed', 'value': 105, 'stackable': True, 'cap': 0}]}, {'bonus': 305, 'applied': [3, 9]}], ['no promos', {'base': 50, 'promos': []}, {'bonus': 0, 'applied': []}], ['only non stackable', {'base': 700, 'promos': [{'id': 4, 'kind': 'fixed', 'value': 50, 'stackable': False, 'cap': 0}, {'id': 5, 'kind': 'multiplier', 'value': 115, 'stackable': False, 'cap': 0}, {'id': 6, 'kind': 'fixed', 'value': 60, 'stackable': False, 'cap': 40}]}, {'bonus': 105, 'applied': [5]}], ['odd base', {'base': 338, 'promos': [{'id': 1, 'kind': 'multiplier', 'value': 125, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'multiplier', 'value': 175, 'stackable': True, 'cap': 0}]}, {'bonus': 337, 'applied': [1, 2]}], ['best beats stack', {'base': 100, 'promos': [{'id': 1, 'kind': 'fixed', 'value': 10, 'stackable': True, 'cap': 0}, {'id': 2, 'kind': 'fixed', 'value': 505, 'stackable': False, 'cap': 0}, {'id': 3, 'kind': 'fixed', 'value': 20, 'stackable': True, 'cap': 0}]}, {'bonus': 535, 'applied': [1, 2, 3]}]]]
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)

prompt:
Exclusive promotions are all applied together.

Input {base, promos:[{id,kind,value,stackable,cap}]}. A multiplier promo (value in percent) gives floor(base*(value-100)/100) extra; a fixed promo gives value. Each extra is capped at cap when cap > 0. All stackable extras apply; of the non-stackable promos only the single best capped extra applies (ties to the lower id), in addition to the stackable ones. Return {bonus, applied ids sorted}.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    acts = [a for a in x['activity'] if a[0] <= x['today']]
    qual = [d for d, k, p in acts ]
    bal = sum(p for d, k, p in acts)
    if qual:
        ref = max(qual)
    else:
        ref = min([d for d, k, p in acts] or [x['today']])
    inactive = x['today'] - ref > x['window']
    if inactive and bal > 0:
        return {'expired': bal, 'balance': 0, 'last_activity': ref}
    return {'expired': 0, 'balance': bal, 'last_activity': ref}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 51]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 351, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 301]], 'today': 700, 'window': 540}, {'expired': 801, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 101]], 'today': 600, 'window': 540}, {'expired': 501, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 251]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 251, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -101]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 799, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 101]], 'today': 600, 'window': 540}, {'expired': 101, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -151]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -51, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 71]], 'today': 950, 'window': 540}, {'expired': 76, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 21]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}]], [['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 52]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 352, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 302]], 'today': 700, 'window': 540}, {'expired': 802, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 102]], 'today': 600, 'window': 540}, {'expired': 502, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 252]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 252, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -102]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 798, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 102]], 'today': 600, 'window': 540}, {'expired': 102, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -152]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -52, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 72]], 'today': 950, 'window': 540}, {'expired': 77, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 22]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}]], [['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 53]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 353, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 303]], 'today': 700, 'window': 540}, {'expired': 803, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 103]], 'today': 600, 'window': 540}, {'expired': 503, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 253]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 253, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -103]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 797, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 103]], 'today': 600, 'window': 540}, {'expired': 103, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -153]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -53, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 73]], 'today': 950, 'window': 540}, {'expired': 78, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 23]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}]], [['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 54]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 354, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 304]], 'today': 700, 'window': 540}, {'expired': 804, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 104]], 'today': 600, 'window': 540}, {'expired': 504, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 254]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 254, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -104]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 796, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 104]], 'today': 600, 'window': 540}, {'expired': 104, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -154]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -54, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 74]], 'today': 950, 'window': 540}, {'expired': 79, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 24]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}]], [['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 55]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 355, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 305]], 'today': 700, 'window': 540}, {'expired': 805, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 105]], 'today': 600, 'window': 540}, {'expired': 505, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 255]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 255, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -105]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 795, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 105]], 'today': 600, 'window': 540}, {'expired': 105, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -155]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -55, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 75]], 'today': 950, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 25]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}]]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    acts = [a for a in x['activity'] if a[0] <= x['today']]
    qual = [d for d, k, p in acts if k in ('earn', 'redeem')]
    bal = sum(p for d, k, p in acts)
    if qual:
        ref = max(qual)
    else:
        ref = min([d for d, k, p in acts] or [x['today']])
    inactive = x['today'] - ref > x['window']
    if inactive and bal > 0:
        return {'expired': bal, 'balance': 0, 'last_activity': ref}
    return {'expired': 0, 'balance': bal, 'last_activity': ref}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 51]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 351, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 301]], 'today': 700, 'window': 540}, {'expired': 801, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 101]], 'today': 600, 'window': 540}, {'expired': 501, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 251]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 251, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -101]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 799, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 101]], 'today': 600, 'window': 540}, {'expired': 101, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -151]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -51, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 71]], 'today': 950, 'window': 540}, {'expired': 76, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 21]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}]], [['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 52]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 352, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 302]], 'today': 700, 'window': 540}, {'expired': 802, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 102]], 'today': 600, 'window': 540}, {'expired': 502, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 252]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 252, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -102]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 798, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 102]], 'today': 600, 'window': 540}, {'expired': 102, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -152]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -52, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 72]], 'today': 950, 'window': 540}, {'expired': 77, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 22]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}]], [['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 53]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 353, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 303]], 'today': 700, 'window': 540}, {'expired': 803, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 103]], 'today': 600, 'window': 540}, {'expired': 503, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 253]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 253, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -103]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 797, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 103]], 'today': 600, 'window': 540}, {'expired': 103, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -153]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -53, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 73]], 'today': 950, 'window': 540}, {'expired': 78, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 23]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}]], [['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 54]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 354, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 304]], 'today': 700, 'window': 540}, {'expired': 804, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 104]], 'today': 600, 'window': 540}, {'expired': 504, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 254]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 254, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -104]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 796, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 104]], 'today': 600, 'window': 540}, {'expired': 104, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -154]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -54, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 74]], 'today': 950, 'window': 540}, {'expired': 79, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 24]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}]], [['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 55]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 355, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 305]], 'today': 700, 'window': 540}, {'expired': 805, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 105]], 'today': 600, 'window': 540}, {'expired': 505, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 255]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 255, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -105]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 795, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 105]], 'today': 600, 'window': 540}, {'expired': 105, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -155]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -55, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 75]], 'today': 950, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 25]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}]]]
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)

prompt:
Goodwill bonus credits keep dormant accounts alive indefinitely.

Input {activity:[[day,kind,signed pts]], today, window}. Only activity dated <= today counts. Qualifying kinds are earn, redeem and transfer_out; the reference day is the latest qualifying day, or the earliest activity day if none qualifies (today if no activity). The account is inactive when today - reference > window; an inactive account with a positive balance forfeits it all. Return {expired, balance, last_activity}.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    acts = [a for a in x['activity'] if a[0] <= x['today']]
    qual = [d for d, k, p in acts if k in ('earn', 'redeem', 'transfer_out')]
    bal = sum(p for d, k, p in acts)
    if qual:
        ref = min(qual)
    else:
        ref = min([d for d, k, p in acts] or [x['today']])
    inactive = x['today'] - ref > x['window']
    if inactive and bal > 0:
        return {'expired': bal, 'balance': 0, 'last_activity': ref}
    return {'expired': 0, 'balance': bal, 'last_activity': ref}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 51]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 351, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 301]], 'today': 700, 'window': 540}, {'expired': 801, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 101]], 'today': 600, 'window': 540}, {'expired': 501, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 251]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 251, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -101]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 799, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 101]], 'today': 600, 'window': 540}, {'expired': 101, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -151]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -51, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 71]], 'today': 950, 'window': 540}, {'expired': 76, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 21]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}]], [['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 52]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 352, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 302]], 'today': 700, 'window': 540}, {'expired': 802, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 102]], 'today': 600, 'window': 540}, {'expired': 502, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 252]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 252, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -102]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 798, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 102]], 'today': 600, 'window': 540}, {'expired': 102, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -152]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -52, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 72]], 'today': 950, 'window': 540}, {'expired': 77, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 22]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}]], [['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 53]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 353, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 303]], 'today': 700, 'window': 540}, {'expired': 803, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 103]], 'today': 600, 'window': 540}, {'expired': 503, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 253]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 253, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -103]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 797, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 103]], 'today': 600, 'window': 540}, {'expired': 103, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -153]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -53, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 73]], 'today': 950, 'window': 540}, {'expired': 78, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 23]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}]], [['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 54]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 354, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 304]], 'today': 700, 'window': 540}, {'expired': 804, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 104]], 'today': 600, 'window': 540}, {'expired': 504, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 254]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 254, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -104]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 796, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 104]], 'today': 600, 'window': 540}, {'expired': 104, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -154]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -54, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 74]], 'today': 950, 'window': 540}, {'expired': 79, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 24]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}]], [['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 55]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 355, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 305]], 'today': 700, 'window': 540}, {'expired': 805, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 105]], 'today': 600, 'window': 540}, {'expired': 505, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 255]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 255, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -105]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 795, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 105]], 'today': 600, 'window': 540}, {'expired': 105, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -155]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -55, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 75]], 'today': 950, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 25]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}]]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    acts = [a for a in x['activity'] if a[0] <= x['today']]
    qual = [d for d, k, p in acts if k in ('earn', 'redeem', 'transfer_out')]
    bal = sum(p for d, k, p in acts)
    if qual:
        ref = qual[-1]
    else:
        ref = min([d for d, k, p in acts] or [x['today']])
    inactive = x['today'] - ref > x['window']
    if inactive and bal > 0:
        return {'expired': bal, 'balance': 0, 'last_activity': ref}
    return {'expired': 0, 'balance': bal, 'last_activity': ref}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 51]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 351, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 301]], 'today': 700, 'window': 540}, {'expired': 801, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 101]], 'today': 600, 'window': 540}, {'expired': 501, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 251]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 251, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -101]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 799, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 101]], 'today': 600, 'window': 540}, {'expired': 101, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -151]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -51, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 71]], 'today': 950, 'window': 540}, {'expired': 76, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 21]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}]], [['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 52]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 352, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 302]], 'today': 700, 'window': 540}, {'expired': 802, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 102]], 'today': 600, 'window': 540}, {'expired': 502, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 252]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 252, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -102]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 798, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 102]], 'today': 600, 'window': 540}, {'expired': 102, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -152]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -52, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 72]], 'today': 950, 'window': 540}, {'expired': 77, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 22]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}]], [['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 53]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 353, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 303]], 'today': 700, 'window': 540}, {'expired': 803, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 103]], 'today': 600, 'window': 540}, {'expired': 503, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 253]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 253, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -103]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 797, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 103]], 'today': 600, 'window': 540}, {'expired': 103, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -153]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -53, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 73]], 'today': 950, 'window': 540}, {'expired': 78, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 23]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}]], [['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 54]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 354, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 304]], 'today': 700, 'window': 540}, {'expired': 804, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 104]], 'today': 600, 'window': 540}, {'expired': 504, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 254]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 254, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -104]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 796, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 104]], 'today': 600, 'window': 540}, {'expired': 104, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -154]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -54, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 74]], 'today': 950, 'window': 540}, {'expired': 79, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 24]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}]], [['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 55]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 355, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 305]], 'today': 700, 'window': 540}, {'expired': 805, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 105]], 'today': 600, 'window': 540}, {'expired': 505, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 255]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 255, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -105]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 795, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 105]], 'today': 600, 'window': 540}, {'expired': 105, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -155]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -55, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 75]], 'today': 950, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 25]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}]]]
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)

prompt:
Accounts with recent activity are expired because the clock runs from their first earn.

Input {activity:[[day,kind,signed pts]], today, window}. Only activity dated <= today counts. Qualifying kinds are earn, redeem and transfer_out; the reference day is the latest qualifying day, or the earliest activity day if none qualifies (today if no activity). The account is inactive when today - reference > window; an inactive account with a positive balance forfeits it all. Return {expired, balance, last_activity}.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    acts = [a for a in x['activity'] if a[0] <= x['today']]
    qual = [d for d, k, p in acts if k in ('earn', 'redeem', 'transfer_out')]
    bal = sum(p for d, k, p in acts)
    if qual:
        ref = max(qual)
    else:
        ref = min([d for d, k, p in acts] or [x['today']])
    inactive = x['today'] - ref >= x['window']
    if inactive and bal > 0:
        return {'expired': bal, 'balance': 0, 'last_activity': ref}
    return {'expired': 0, 'balance': bal, 'last_activity': ref}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 51]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 351, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 301]], 'today': 700, 'window': 540}, {'expired': 801, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 101]], 'today': 600, 'window': 540}, {'expired': 501, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 251]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 251, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -101]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 799, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 101]], 'today': 600, 'window': 540}, {'expired': 101, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -151]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -51, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 71]], 'today': 950, 'window': 540}, {'expired': 76, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 21]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}], ['one day past window', {'activity': [[1, 'earn', 99]], 'today': 542, 'window': 540}, {'expired': 99, 'balance': 0, 'last_activity': 1}]], [['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 52]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 352, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 302]], 'today': 700, 'window': 540}, {'expired': 802, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 102]], 'today': 600, 'window': 540}, {'expired': 502, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 252]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 252, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -102]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 798, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 102]], 'today': 600, 'window': 540}, {'expired': 102, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -152]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -52, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 72]], 'today': 950, 'window': 540}, {'expired': 77, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 22]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}], ['one day past window', {'activity': [[2, 'earn', 99]], 'today': 543, 'window': 540}, {'expired': 99, 'balance': 0, 'last_activity': 2}]], [['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 53]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 353, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 303]], 'today': 700, 'window': 540}, {'expired': 803, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 103]], 'today': 600, 'window': 540}, {'expired': 503, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 253]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 253, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -103]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 797, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 103]], 'today': 600, 'window': 540}, {'expired': 103, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -153]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -53, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 73]], 'today': 950, 'window': 540}, {'expired': 78, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 23]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}], ['one day past window', {'activity': [[3, 'earn', 99]], 'today': 544, 'window': 540}, {'expired': 99, 'balance': 0, 'last_activity': 3}]], [['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 54]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 354, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 304]], 'today': 700, 'window': 540}, {'expired': 804, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 104]], 'today': 600, 'window': 540}, {'expired': 504, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 254]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 254, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -104]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 796, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 104]], 'today': 600, 'window': 540}, {'expired': 104, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -154]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -54, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 74]], 'today': 950, 'window': 540}, {'expired': 79, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 24]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}], ['one day past window', {'activity': [[4, 'earn', 99]], 'today': 545, 'window': 540}, {'expired': 99, 'balance': 0, 'last_activity': 4}]], [['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 55]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 355, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 305]], 'today': 700, 'window': 540}, {'expired': 805, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 105]], 'today': 600, 'window': 540}, {'expired': 505, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 255]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 255, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -105]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 795, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 105]], 'today': 600, 'window': 540}, {'expired': 105, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -155]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -55, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 75]], 'today': 950, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 25]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}], ['one day past window', {'activity': [[5, 'earn', 99]], 'today': 546, 'window': 540}, {'expired': 99, 'balance': 0, 'last_activity': 5}]]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    acts = [a for a in x['activity'] if a[0] <= x['today']]
    qual = [d for d, k, p in acts if k in ('earn', 'redeem', 'transfer_out')]
    bal = sum(p for d, k, p in acts)
    if qual:
        ref = max(qual)
    else:
        ref = min([d for d, k, p in acts] or [x['today']])
    inactive = x['today'] - ref > x['window'] + 1
    if inactive and bal > 0:
        return {'expired': bal, 'balance': 0, 'last_activity': ref}
    return {'expired': 0, 'balance': bal, 'last_activity': ref}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 51]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 351, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 301]], 'today': 700, 'window': 540}, {'expired': 801, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 101]], 'today': 600, 'window': 540}, {'expired': 501, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 251]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 251, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -101]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 799, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 101]], 'today': 600, 'window': 540}, {'expired': 101, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -151]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -51, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 71]], 'today': 950, 'window': 540}, {'expired': 76, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 21]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}], ['one day past window', {'activity': [[1, 'earn', 99]], 'today': 542, 'window': 540}, {'expired': 99, 'balance': 0, 'last_activity': 1}]], [['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 52]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 352, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 302]], 'today': 700, 'window': 540}, {'expired': 802, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 102]], 'today': 600, 'window': 540}, {'expired': 502, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 252]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 252, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -102]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 798, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 102]], 'today': 600, 'window': 540}, {'expired': 102, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -152]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -52, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 72]], 'today': 950, 'window': 540}, {'expired': 77, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 22]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}], ['one day past window', {'activity': [[2, 'earn', 99]], 'today': 543, 'window': 540}, {'expired': 99, 'balance': 0, 'last_activity': 2}]], [['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 53]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 353, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 303]], 'today': 700, 'window': 540}, {'expired': 803, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 103]], 'today': 600, 'window': 540}, {'expired': 503, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 253]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 253, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -103]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 797, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 103]], 'today': 600, 'window': 540}, {'expired': 103, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -153]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -53, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 73]], 'today': 950, 'window': 540}, {'expired': 78, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 23]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}], ['one day past window', {'activity': [[3, 'earn', 99]], 'today': 544, 'window': 540}, {'expired': 99, 'balance': 0, 'last_activity': 3}]], [['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 54]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 354, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 304]], 'today': 700, 'window': 540}, {'expired': 804, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 104]], 'today': 600, 'window': 540}, {'expired': 504, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 254]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 254, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -104]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 796, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 104]], 'today': 600, 'window': 540}, {'expired': 104, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -154]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -54, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 74]], 'today': 950, 'window': 540}, {'expired': 79, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 24]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}], ['one day past window', {'activity': [[4, 'earn', 99]], 'today': 545, 'window': 540}, {'expired': 99, 'balance': 0, 'last_activity': 4}]], [['active member', {'activity': [[10, 'earn', 500], [200, 'redeem', -200], [500, 'earn', 55]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': 355, 'last_activity': 500}], ['inactive', {'activity': [[10, 'earn', 500], [100, 'earn', 305]], 'today': 700, 'window': 540}, {'expired': 805, 'balance': 0, 'last_activity': 100}], ['bonus does not count', {'activity': [[0, 'earn', 400], [500, 'bonus_credit', 105]], 'today': 600, 'window': 540}, {'expired': 505, 'balance': 0, 'last_activity': 0}], ['window edge', {'activity': [[60, 'earn', 255]], 'today': 600, 'window': 540}, {'expired': 0, 'balance': 255, 'last_activity': 60}], ['transfer out counts', {'activity': [[0, 'earn', 900], [300, 'transfer_out', -105]], 'today': 800, 'window': 540}, {'expired': 0, 'balance': 795, 'last_activity': 300}], ['never qualified', {'activity': [[5, 'adjust', 105]], 'today': 600, 'window': 540}, {'expired': 105, 'balance': 0, 'last_activity': 5}], ['negative balance', {'activity': [[0, 'earn', 100], [10, 'adjust', -155]], 'today': 900, 'window': 540}, {'expired': 0, 'balance': -55, 'last_activity': 0}], ['unsorted list', {'activity': [[400, 'earn', 10], [20, 'redeem', -5], [30, 'earn', 75]], 'today': 950, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 400}], ['future dated', {'activity': [[10, 'earn', 80], [1000, 'earn', 25]], 'today': 900, 'window': 540}, {'expired': 80, 'balance': 0, 'last_activity': 10}], ['one day past window', {'activity': [[5, 'earn', 99]], 'today': 546, 'window': 540}, {'expired': 99, 'balance': 0, 'last_activity': 5}]]]
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)

prompt:
Points expire on the last day of the allowed inactivity window.

Input {activity:[[day,kind,signed pts]], today, window}. Only activity dated <= today counts. Qualifying kinds are earn, redeem and transfer_out; the reference day is the latest qualifying day, or the earliest activity day if none qualifies (today if no activity). The account is inactive when today - reference > window; an inactive account with a positive balance forfeits it all. Return {expired, balance, last_activity}.

split: open-access