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

N = 1
observations = []
def solve(x):
    layers = []
    cogs = revenue = 0
    short = []
    for i, ev in enumerate(x):
        if ev[0] == 'buy':
            if layers and layers[-1][1] == ev[2]:
                layers[-1][0] += ev[1]
            else:
                layers.append([ev[1], ev[2]])
        elif ev[0] == 'sell':
            qty = ev[1]
            if qty > sum(l[0] for l in layers):
                short.append(i)
                continue
            revenue += qty * ev[2]
            while qty:
                head = layers[0]
                take = min(qty, head[0])
                cogs += take * head[1]
                head[0] -= take
                qty -= take
                if head[0] == 0:
                    layers.pop(0)
        elif ev[0] == 'purchase_return':
            match = [l for l in layers if l[1] == ev[2] and l[0] >= ev[1]]
            if not match:
                short.append(i)
                continue
            match[0][0] -= ev[1]
            if match[0][0] == 0:
                layers.remove(match[0])
    inventory = sum(q * c for q, c in layers)
    return {'cogs': cogs, 'revenue': revenue, 'inventory': inventory, 'layers': layers, 'rejected': short}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: return layer selection', [['buy', 5, 100], ['buy', 10, 100], ['sell', 12, 200], ['buy', 10, 120], ['sell', 1, 250], ['buy', 1, 120], ['buy', 1, 100], ['buy', 2, 100], ['purchase_return', 1, 100], ['buy', 10, 150]], {'cogs': 1300, 'revenue': 2650, 'inventory': 3220, 'layers': [[2, 100], [11, 120], [2, 100], [10, 150]], 'rejected': []}], ['control 1', [['sell', 3, 250], ['buy', 2, 120], ['purchase_return', 1, 100], ['buy', 5, 100], ['buy', 2, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 980, 'layers': [[2, 120], [5, 100], [2, 120]], 'rejected': [0, 2]}], ['control 2', [['buy', 5, 150], ['sell', 3, 250], ['sell', 2, 250], ['buy', 10, 100], ['buy', 10, 120], ['purchase_return', 2, 100], ['purchase_return', 5, 100], ['buy', 10, 150], ['buy', 2, 120], ['purchase_return', 5, 100]], {'cogs': 750, 'revenue': 1250, 'inventory': 3240, 'layers': [[3, 100], [10, 120], [10, 150], [2, 120]], 'rejected': [9]}], ['control 3', [['buy', 1, 120], ['sell', 12, 200], ['sell', 2, 250], ['sell', 2, 250]], {'cogs': 0, 'revenue': 0, 'inventory': 120, 'layers': [[1, 120]], 'rejected': [1, 2, 3]}], ['control 4', [['buy', 5, 100], ['sell', 3, 250], ['sell', 12, 200]], {'cogs': 300, 'revenue': 750, 'inventory': 200, 'layers': [[2, 100]], 'rejected': [2]}], ['control 5', [['buy', 10, 120], ['purchase_return', 1, 100], ['sell', 1, 200], ['purchase_return', 2, 100], ['sell', 2, 200], ['purchase_return', 1, 120], ['buy', 10, 120], ['buy', 5, 120]], {'cogs': 360, 'revenue': 600, 'inventory': 2520, 'layers': [[21, 120]], 'rejected': [1, 3]}], ['control 6', [['sell', 12, 250], ['sell', 12, 200], ['buy', 5, 100], ['sell', 12, 250], ['sell', 12, 200], ['purchase_return', 1, 100], ['sell', 3, 250]], {'cogs': 300, 'revenue': 750, 'inventory': 100, 'layers': [[1, 100]], 'rejected': [0, 1, 3, 4]}]], [['regression: return layer selection', [['buy', 10, 100], ['purchase_return', 1, 100], ['buy', 5, 150], ['buy', 10, 100], ['purchase_return', 2, 100], ['buy', 2, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 2690, 'layers': [[9, 100], [5, 150], [8, 100], [2, 120]], 'rejected': []}], ['control 1', [['sell', 12, 200], ['sell', 6, 250], ['sell', 6, 200]], {'cogs': 0, 'revenue': 0, 'inventory': 0, 'layers': [], 'rejected': [0, 1, 2]}], ['control 2', [['buy', 10, 100], ['sell', 12, 250], ['sell', 2, 250], ['sell', 12, 200], ['sell', 6, 200], ['buy', 1, 150], ['buy', 2, 120]], {'cogs': 800, 'revenue': 1700, 'inventory': 590, 'layers': [[2, 100], [1, 150], [2, 120]], 'rejected': [1, 3]}], ['control 3', [['purchase_return', 2, 100], ['sell', 12, 250], ['buy', 10, 100], ['buy', 1, 100], ['sell', 6, 200]], {'cogs': 600, 'revenue': 1200, 'inventory': 500, 'layers': [[5, 100]], 'rejected': [0, 1]}], ['control 4', [['buy', 10, 150], ['sell', 3, 250], ['sell', 12, 200], ['buy', 5, 120], ['sell', 3, 200], ['buy', 1, 100], ['sell', 1, 250], ['buy', 2, 100], ['sell', 12, 200], ['buy', 10, 100]], {'cogs': 1050, 'revenue': 1600, 'inventory': 2350, 'layers': [[3, 150], [5, 120], [13, 100]], 'rejected': [2, 8]}], ['control 5', [['sell', 2, 250], ['purchase_return', 1, 150], ['buy', 10, 100], ['buy', 10, 150], ['buy', 2, 150], ['buy', 2, 100], ['sell', 2, 250], ['sell', 3, 250], ['buy', 5, 120]], {'cogs': 500, 'revenue': 1250, 'inventory': 3100, 'layers': [[5, 100], [12, 150], [2, 100], [5, 120]], 'rejected': [0, 1]}], ['control 6', [['buy', 10, 120], ['sell', 1, 200], ['buy', 10, 120], ['buy', 2, 120], ['sell', 6, 250], ['buy', 1, 100], ['buy', 2, 150], ['sell', 1, 250]], {'cogs': 960, 'revenue': 1950, 'inventory': 2080, 'layers': [[14, 120], [1, 100], [2, 150]], 'rejected': []}]], [['regression: return layer selection', [['sell', 2, 250], ['sell', 3, 250], ['sell', 1, 200], ['buy', 5, 100], ['buy', 10, 150], ['buy', 10, 100], ['purchase_return', 5, 100], ['sell', 3, 250], ['buy', 1, 100]], {'cogs': 300, 'revenue': 750, 'inventory': 2300, 'layers': [[2, 100], [10, 150], [6, 100]], 'rejected': [0, 1, 2]}], ['control 1', [['purchase_return', 5, 100], ['sell', 2, 250], ['buy', 2, 100], ['buy', 1, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 320, 'layers': [[2, 100], [1, 120]], 'rejected': [0, 1]}], ['control 2', [['sell', 1, 250], ['buy', 5, 100], ['buy', 10, 100], ['sell', 2, 250], ['buy', 2, 100], ['buy', 10, 100], ['sell', 6, 200], ['buy', 1, 120], ['buy', 10, 150], ['buy', 10, 150]], {'cogs': 800, 'revenue': 1700, 'inventory': 5020, 'layers': [[19, 100], [1, 120], [20, 150]], 'rejected': [0]}], ['control 3', [['purchase_return', 1, 100], ['sell', 1, 200], ['sell', 1, 250], ['sell', 3, 200], ['sell', 6, 200], ['buy', 10, 120], ['buy', 2, 150], ['buy', 2, 100], ['purchase_return', 2, 150]], {'cogs': 0, 'revenue': 0, 'inventory': 1400, 'layers': [[10, 120], [2, 100]], 'rejected': [0, 1, 2, 3, 4]}], ['control 4', [['buy', 1, 100], ['purchase_return', 5, 100], ['sell', 3, 200], ['buy', 1, 150], ['buy', 1, 150], ['sell', 3, 200], ['buy', 2, 120], ['buy', 10, 120]], {'cogs': 400, 'revenue': 600, 'inventory': 1440, 'layers': [[12, 120]], 'rejected': [1, 2]}], ['control 5', [['purchase_return', 1, 100], ['buy', 2, 150], ['sell', 6, 200], ['sell', 2, 250], ['buy', 5, 120], ['buy', 5, 150], ['sell', 1, 250], ['purchase_return', 2, 100]], {'cogs': 420, 'revenue': 750, 'inventory': 1230, 'layers': [[4, 120], [5, 150]], 'rejected': [0, 2, 7]}], ['control 6', [['buy', 2, 120], ['purchase_return', 1, 150], ['buy', 1, 100], ['buy', 5, 100], ['sell', 3, 200]], {'cogs': 340, 'revenue': 600, 'inventory': 500, 'layers': [[5, 100]], 'rejected': [1]}]], [['regression: return layer selection', [['buy', 5, 100], ['sell', 1, 250], ['buy', 1, 120], ['buy', 10, 100], ['buy', 5, 100], ['buy', 10, 100], ['purchase_return', 1, 100]], {'cogs': 100, 'revenue': 250, 'inventory': 2920, 'layers': [[4, 100], [1, 120], [24, 100]], 'rejected': []}], ['control 1', [['sell', 1, 250], ['sell', 3, 200], ['purchase_return', 1, 100], ['buy', 2, 120], ['buy', 5, 150], ['sell', 3, 200], ['sell', 1, 200], ['sell', 6, 250], ['buy', 2, 120]], {'cogs': 540, 'revenue': 800, 'inventory': 690, 'layers': [[3, 150], [2, 120]], 'rejected': [0, 1, 2, 7]}], ['control 2', [['buy', 1, 100], ['purchase_return', 2, 150], ['purchase_return', 1, 120], ['purchase_return', 2, 100], ['buy', 5, 100], ['buy', 10, 100], ['buy', 1, 150], ['buy', 1, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 1870, 'layers': [[16, 100], [1, 150], [1, 120]], 'rejected': [1, 2, 3]}], ['control 3', [['buy', 2, 150], ['buy', 10, 120], ['sell', 1, 200], ['purchase_return', 5, 100], ['buy', 1, 100], ['buy', 2, 150], ['buy', 1, 100], ['buy', 5, 100], ['sell', 3, 200]], {'cogs': 540, 'revenue': 800, 'inventory': 1960, 'layers': [[8, 120], [1, 100], [2, 150], [6, 100]], 'rejected': [3]}], ['control 4', [['sell', 12, 200], ['sell', 12, 250], ['buy', 2, 150], ['sell', 12, 250], ['buy', 2, 150], ['buy', 1, 100], ['buy', 5, 120], ['buy', 10, 150], ['sell', 3, 200], ['buy', 2, 150]], {'cogs': 450, 'revenue': 600, 'inventory': 2650, 'layers': [[1, 150], [1, 100], [5, 120], [12, 150]], 'rejected': [0, 1, 3]}], ['control 5', [['buy', 1, 100], ['buy', 2, 120], ['buy', 2, 120], ['sell', 3, 200], ['sell', 12, 200], ['buy', 5, 120], ['sell', 3, 200], ['purchase_return', 1, 100], ['buy', 2, 100]], {'cogs': 700, 'revenue': 1200, 'inventory': 680, 'layers': [[4, 120], [2, 100]], 'rejected': [4, 7]}], ['control 6', [['sell', 3, 250], ['purchase_return', 1, 150], ['purchase_return', 2, 120], ['sell', 6, 200], ['purchase_return', 2, 100]], {'cogs': 0, 'revenue': 0, 'inventory': 0, 'layers': [], 'rejected': [0, 1, 2, 3, 4]}]], [['regression: return layer selection', [['sell', 2, 200], ['buy', 2, 100], ['buy', 5, 100], ['buy', 10, 120], ['buy', 1, 100], ['purchase_return', 1, 100], ['buy', 2, 100], ['buy', 2, 150]], {'cogs': 0, 'revenue': 0, 'inventory': 2400, 'layers': [[7, 100], [10, 120], [2, 100], [2, 150]], 'rejected': [0]}], ['control 1', [['buy', 10, 100], ['buy', 10, 150], ['purchase_return', 5, 100], ['sell', 6, 200], ['sell', 3, 200], ['sell', 2, 200]], {'cogs': 1400, 'revenue': 2200, 'inventory': 600, 'layers': [[4, 150]], 'rejected': []}], ['control 2', [['purchase_return', 2, 100], ['sell', 1, 200], ['buy', 5, 100], ['buy', 5, 100], ['purchase_return', 1, 150], ['sell', 2, 250], ['buy', 1, 100], ['sell', 1, 200]], {'cogs': 300, 'revenue': 700, 'inventory': 800, 'layers': [[8, 100]], 'rejected': [0, 1, 4]}], ['control 3', [['purchase_return', 1, 100], ['buy', 1, 100], ['sell', 3, 200], ['buy', 10, 100], ['buy', 5, 100], ['sell', 2, 200], ['purchase_return', 2, 150]], {'cogs': 200, 'revenue': 400, 'inventory': 1400, 'layers': [[14, 100]], 'rejected': [0, 2, 6]}], ['control 4', [['buy', 10, 120], ['buy', 1, 120], ['purchase_return', 2, 150], ['sell', 2, 250], ['buy', 1, 100]], {'cogs': 240, 'revenue': 500, 'inventory': 1180, 'layers': [[9, 120], [1, 100]], 'rejected': [2]}], ['control 5', [['sell', 6, 250], ['purchase_return', 2, 100], ['sell', 12, 250], ['sell', 3, 200]], {'cogs': 0, 'revenue': 0, 'inventory': 0, 'layers': [], 'rejected': [0, 1, 2, 3]}], ['control 6', [['sell', 6, 250], ['sell', 3, 250], ['sell', 12, 200], ['sell', 1, 250], ['sell', 3, 250], ['purchase_return', 5, 150], ['sell', 6, 200]], {'cogs': 0, 'revenue': 0, 'inventory': 0, 'layers': [], 'rejected': [0, 1, 2, 3, 4, 5, 6]}]]]
for label, args, expected in fixtures[N-1]:
    try:
        actual = solve(args)
    except Exception as exc:
        actual = 'raised ' + type(exc).__name__
    check(label, actual, expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

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

N = 1
observations = []
def solve(x):
    layers = []
    cogs = revenue = 0
    short = []
    for i, ev in enumerate(x):
        if ev[0] == 'buy':
            if layers and layers[-1][1] == ev[2]:
                layers[-1][0] += ev[1]
            else:
                layers.append([ev[1], ev[2]])
        elif ev[0] == 'sell':
            qty = ev[1]
            if qty > sum(l[0] for l in layers):
                short.append(i)
                continue
            revenue += qty * ev[2]
            while qty:
                head = layers[0]
                take = min(qty, head[0])
                cogs += take * head[1]
                head[0] -= take
                qty -= take
                if head[0] == 0:
                    layers.pop(0)
        elif ev[0] == 'purchase_return':
            match = [l for l in layers if l[1] == ev[2] and l[0] >= ev[1]]
            if not match:
                short.append(i)
                continue
            match[0][0] -= ev[1]
            if match[-1][0] == 0:
                layers.remove(match[-1])
    inventory = sum(q * c for q, c in layers)
    return {'cogs': cogs, 'revenue': revenue, 'inventory': inventory, 'layers': layers, 'rejected': short}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: return layer selection', [['buy', 5, 100], ['buy', 10, 100], ['sell', 12, 200], ['buy', 10, 120], ['sell', 1, 250], ['buy', 1, 120], ['buy', 1, 100], ['buy', 2, 100], ['purchase_return', 1, 100], ['buy', 10, 150]], {'cogs': 1300, 'revenue': 2650, 'inventory': 3220, 'layers': [[2, 100], [11, 120], [2, 100], [10, 150]], 'rejected': []}], ['control 1', [['sell', 3, 250], ['buy', 2, 120], ['purchase_return', 1, 100], ['buy', 5, 100], ['buy', 2, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 980, 'layers': [[2, 120], [5, 100], [2, 120]], 'rejected': [0, 2]}], ['control 2', [['buy', 5, 150], ['sell', 3, 250], ['sell', 2, 250], ['buy', 10, 100], ['buy', 10, 120], ['purchase_return', 2, 100], ['purchase_return', 5, 100], ['buy', 10, 150], ['buy', 2, 120], ['purchase_return', 5, 100]], {'cogs': 750, 'revenue': 1250, 'inventory': 3240, 'layers': [[3, 100], [10, 120], [10, 150], [2, 120]], 'rejected': [9]}], ['control 3', [['buy', 1, 120], ['sell', 12, 200], ['sell', 2, 250], ['sell', 2, 250]], {'cogs': 0, 'revenue': 0, 'inventory': 120, 'layers': [[1, 120]], 'rejected': [1, 2, 3]}], ['control 4', [['buy', 5, 100], ['sell', 3, 250], ['sell', 12, 200]], {'cogs': 300, 'revenue': 750, 'inventory': 200, 'layers': [[2, 100]], 'rejected': [2]}], ['control 5', [['buy', 10, 120], ['purchase_return', 1, 100], ['sell', 1, 200], ['purchase_return', 2, 100], ['sell', 2, 200], ['purchase_return', 1, 120], ['buy', 10, 120], ['buy', 5, 120]], {'cogs': 360, 'revenue': 600, 'inventory': 2520, 'layers': [[21, 120]], 'rejected': [1, 3]}], ['control 6', [['sell', 12, 250], ['sell', 12, 200], ['buy', 5, 100], ['sell', 12, 250], ['sell', 12, 200], ['purchase_return', 1, 100], ['sell', 3, 250]], {'cogs': 300, 'revenue': 750, 'inventory': 100, 'layers': [[1, 100]], 'rejected': [0, 1, 3, 4]}]], [['regression: return layer selection', [['buy', 10, 100], ['purchase_return', 1, 100], ['buy', 5, 150], ['buy', 10, 100], ['purchase_return', 2, 100], ['buy', 2, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 2690, 'layers': [[9, 100], [5, 150], [8, 100], [2, 120]], 'rejected': []}], ['control 1', [['sell', 12, 200], ['sell', 6, 250], ['sell', 6, 200]], {'cogs': 0, 'revenue': 0, 'inventory': 0, 'layers': [], 'rejected': [0, 1, 2]}], ['control 2', [['buy', 10, 100], ['sell', 12, 250], ['sell', 2, 250], ['sell', 12, 200], ['sell', 6, 200], ['buy', 1, 150], ['buy', 2, 120]], {'cogs': 800, 'revenue': 1700, 'inventory': 590, 'layers': [[2, 100], [1, 150], [2, 120]], 'rejected': [1, 3]}], ['control 3', [['purchase_return', 2, 100], ['sell', 12, 250], ['buy', 10, 100], ['buy', 1, 100], ['sell', 6, 200]], {'cogs': 600, 'revenue': 1200, 'inventory': 500, 'layers': [[5, 100]], 'rejected': [0, 1]}], ['control 4', [['buy', 10, 150], ['sell', 3, 250], ['sell', 12, 200], ['buy', 5, 120], ['sell', 3, 200], ['buy', 1, 100], ['sell', 1, 250], ['buy', 2, 100], ['sell', 12, 200], ['buy', 10, 100]], {'cogs': 1050, 'revenue': 1600, 'inventory': 2350, 'layers': [[3, 150], [5, 120], [13, 100]], 'rejected': [2, 8]}], ['control 5', [['sell', 2, 250], ['purchase_return', 1, 150], ['buy', 10, 100], ['buy', 10, 150], ['buy', 2, 150], ['buy', 2, 100], ['sell', 2, 250], ['sell', 3, 250], ['buy', 5, 120]], {'cogs': 500, 'revenue': 1250, 'inventory': 3100, 'layers': [[5, 100], [12, 150], [2, 100], [5, 120]], 'rejected': [0, 1]}], ['control 6', [['buy', 10, 120], ['sell', 1, 200], ['buy', 10, 120], ['buy', 2, 120], ['sell', 6, 250], ['buy', 1, 100], ['buy', 2, 150], ['sell', 1, 250]], {'cogs': 960, 'revenue': 1950, 'inventory': 2080, 'layers': [[14, 120], [1, 100], [2, 150]], 'rejected': []}]], [['regression: return layer selection', [['sell', 2, 250], ['sell', 3, 250], ['sell', 1, 200], ['buy', 5, 100], ['buy', 10, 150], ['buy', 10, 100], ['purchase_return', 5, 100], ['sell', 3, 250], ['buy', 1, 100]], {'cogs': 300, 'revenue': 750, 'inventory': 2300, 'layers': [[2, 100], [10, 150], [6, 100]], 'rejected': [0, 1, 2]}], ['control 1', [['purchase_return', 5, 100], ['sell', 2, 250], ['buy', 2, 100], ['buy', 1, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 320, 'layers': [[2, 100], [1, 120]], 'rejected': [0, 1]}], ['control 2', [['sell', 1, 250], ['buy', 5, 100], ['buy', 10, 100], ['sell', 2, 250], ['buy', 2, 100], ['buy', 10, 100], ['sell', 6, 200], ['buy', 1, 120], ['buy', 10, 150], ['buy', 10, 150]], {'cogs': 800, 'revenue': 1700, 'inventory': 5020, 'layers': [[19, 100], [1, 120], [20, 150]], 'rejected': [0]}], ['control 3', [['purchase_return', 1, 100], ['sell', 1, 200], ['sell', 1, 250], ['sell', 3, 200], ['sell', 6, 200], ['buy', 10, 120], ['buy', 2, 150], ['buy', 2, 100], ['purchase_return', 2, 150]], {'cogs': 0, 'revenue': 0, 'inventory': 1400, 'layers': [[10, 120], [2, 100]], 'rejected': [0, 1, 2, 3, 4]}], ['control 4', [['buy', 1, 100], ['purchase_return', 5, 100], ['sell', 3, 200], ['buy', 1, 150], ['buy', 1, 150], ['sell', 3, 200], ['buy', 2, 120], ['buy', 10, 120]], {'cogs': 400, 'revenue': 600, 'inventory': 1440, 'layers': [[12, 120]], 'rejected': [1, 2]}], ['control 5', [['purchase_return', 1, 100], ['buy', 2, 150], ['sell', 6, 200], ['sell', 2, 250], ['buy', 5, 120], ['buy', 5, 150], ['sell', 1, 250], ['purchase_return', 2, 100]], {'cogs': 420, 'revenue': 750, 'inventory': 1230, 'layers': [[4, 120], [5, 150]], 'rejected': [0, 2, 7]}], ['control 6', [['buy', 2, 120], ['purchase_return', 1, 150], ['buy', 1, 100], ['buy', 5, 100], ['sell', 3, 200]], {'cogs': 340, 'revenue': 600, 'inventory': 500, 'layers': [[5, 100]], 'rejected': [1]}]], [['regression: return layer selection', [['buy', 5, 100], ['sell', 1, 250], ['buy', 1, 120], ['buy', 10, 100], ['buy', 5, 100], ['buy', 10, 100], ['purchase_return', 1, 100]], {'cogs': 100, 'revenue': 250, 'inventory': 2920, 'layers': [[4, 100], [1, 120], [24, 100]], 'rejected': []}], ['control 1', [['sell', 1, 250], ['sell', 3, 200], ['purchase_return', 1, 100], ['buy', 2, 120], ['buy', 5, 150], ['sell', 3, 200], ['sell', 1, 200], ['sell', 6, 250], ['buy', 2, 120]], {'cogs': 540, 'revenue': 800, 'inventory': 690, 'layers': [[3, 150], [2, 120]], 'rejected': [0, 1, 2, 7]}], ['control 2', [['buy', 1, 100], ['purchase_return', 2, 150], ['purchase_return', 1, 120], ['purchase_return', 2, 100], ['buy', 5, 100], ['buy', 10, 100], ['buy', 1, 150], ['buy', 1, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 1870, 'layers': [[16, 100], [1, 150], [1, 120]], 'rejected': [1, 2, 3]}], ['control 3', [['buy', 2, 150], ['buy', 10, 120], ['sell', 1, 200], ['purchase_return', 5, 100], ['buy', 1, 100], ['buy', 2, 150], ['buy', 1, 100], ['buy', 5, 100], ['sell', 3, 200]], {'cogs': 540, 'revenue': 800, 'inventory': 1960, 'layers': [[8, 120], [1, 100], [2, 150], [6, 100]], 'rejected': [3]}], ['control 4', [['sell', 12, 200], ['sell', 12, 250], ['buy', 2, 150], ['sell', 12, 250], ['buy', 2, 150], ['buy', 1, 100], ['buy', 5, 120], ['buy', 10, 150], ['sell', 3, 200], ['buy', 2, 150]], {'cogs': 450, 'revenue': 600, 'inventory': 2650, 'layers': [[1, 150], [1, 100], [5, 120], [12, 150]], 'rejected': [0, 1, 3]}], ['control 5', [['buy', 1, 100], ['buy', 2, 120], ['buy', 2, 120], ['sell', 3, 200], ['sell', 12, 200], ['buy', 5, 120], ['sell', 3, 200], ['purchase_return', 1, 100], ['buy', 2, 100]], {'cogs': 700, 'revenue': 1200, 'inventory': 680, 'layers': [[4, 120], [2, 100]], 'rejected': [4, 7]}], ['control 6', [['sell', 3, 250], ['purchase_return', 1, 150], ['purchase_return', 2, 120], ['sell', 6, 200], ['purchase_return', 2, 100]], {'cogs': 0, 'revenue': 0, 'inventory': 0, 'layers': [], 'rejected': [0, 1, 2, 3, 4]}]], [['regression: return layer selection', [['sell', 2, 200], ['buy', 2, 100], ['buy', 5, 100], ['buy', 10, 120], ['buy', 1, 100], ['purchase_return', 1, 100], ['buy', 2, 100], ['buy', 2, 150]], {'cogs': 0, 'revenue': 0, 'inventory': 2400, 'layers': [[7, 100], [10, 120], [2, 100], [2, 150]], 'rejected': [0]}], ['control 1', [['buy', 10, 100], ['buy', 10, 150], ['purchase_return', 5, 100], ['sell', 6, 200], ['sell', 3, 200], ['sell', 2, 200]], {'cogs': 1400, 'revenue': 2200, 'inventory': 600, 'layers': [[4, 150]], 'rejected': []}], ['control 2', [['purchase_return', 2, 100], ['sell', 1, 200], ['buy', 5, 100], ['buy', 5, 100], ['purchase_return', 1, 150], ['sell', 2, 250], ['buy', 1, 100], ['sell', 1, 200]], {'cogs': 300, 'revenue': 700, 'inventory': 800, 'layers': [[8, 100]], 'rejected': [0, 1, 4]}], ['control 3', [['purchase_return', 1, 100], ['buy', 1, 100], ['sell', 3, 200], ['buy', 10, 100], ['buy', 5, 100], ['sell', 2, 200], ['purchase_return', 2, 150]], {'cogs': 200, 'revenue': 400, 'inventory': 1400, 'layers': [[14, 100]], 'rejected': [0, 2, 6]}], ['control 4', [['buy', 10, 120], ['buy', 1, 120], ['purchase_return', 2, 150], ['sell', 2, 250], ['buy', 1, 100]], {'cogs': 240, 'revenue': 500, 'inventory': 1180, 'layers': [[9, 120], [1, 100]], 'rejected': [2]}], ['control 5', [['sell', 6, 250], ['purchase_return', 2, 100], ['sell', 12, 250], ['sell', 3, 200]], {'cogs': 0, 'revenue': 0, 'inventory': 0, 'layers': [], 'rejected': [0, 1, 2, 3]}], ['control 6', [['sell', 6, 250], ['sell', 3, 250], ['sell', 12, 200], ['sell', 1, 250], ['sell', 3, 250], ['purchase_return', 5, 150], ['sell', 6, 200]], {'cogs': 0, 'revenue': 0, 'inventory': 0, 'layers': [], 'rejected': [0, 1, 2, 3, 4, 5, 6]}]]]
for label, args, expected in fixtures[N-1]:
    try:
        actual = solve(args)
    except Exception as exc:
        actual = 'raised ' + type(exc).__name__
    check(label, actual, expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
Purchase returns remove units from the oldest matching layer.

x = [['buy', qty, unit_cost] | ['sell', qty, unit_price] | ['purchase_return', qty, unit_cost]]. Layers are kept oldest first; a buy at the same cost as the newest layer merges into it. A sale consumes layers oldest first (COGS) and records revenue; a sale exceeding on-hand quantity is rejected whole. A purchase return removes qty from the newest layer at that cost holding at least qty, else it is rejected. Emptied layers are removed. Return {'cogs', 'revenue', 'inventory': sum qty*cost, 'layers', 'rejected': event indexes}.

split: open-access


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

N = 1
observations = []
def solve(x):
    layers = []
    cogs = revenue = 0
    short = []
    for i, ev in enumerate(x):
        if ev[0] == 'buy':
            if layers and layers[-1][1] == ev[2]:
                layers[-1][0] += ev[1]
            else:
                layers.append([ev[1], ev[2]])
        elif ev[0] == 'sell':
            qty = ev[1]
            if qty > sum(l[0] for l in layers):
                short.append(i)
                continue
            revenue += qty * ev[2]
            while qty:
                head = layers[0]
                take = min(qty, head[0])
                cogs += take * head[1]
                head[0] -= take
                qty -= take
                if head[0] == 0:
                    layers.pop(0)
        elif ev[0] == 'purchase_return':
            match = [l for l in layers if l[1] == ev[2] and l[0] > ev[1]]
            if not match:
                short.append(i)
                continue
            match[-1][0] -= ev[1]
            if match[-1][0] == 0:
                layers.remove(match[-1])
    inventory = sum(q * c for q, c in layers)
    return {'cogs': cogs, 'revenue': revenue, 'inventory': inventory, 'layers': layers, 'rejected': short}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: return quantity check', [['buy', 2, 120], ['purchase_return', 1, 150], ['buy', 10, 100], ['sell', 6, 250], ['buy', 2, 100], ['sell', 12, 250], ['buy', 5, 120], ['buy', 5, 100], ['purchase_return', 5, 120]], {'cogs': 640, 'revenue': 1500, 'inventory': 1300, 'layers': [[8, 100], [5, 100]], 'rejected': [1, 5]}], ['regression: return quantity check, partial-repair probe', [['buy', 5, 150], ['sell', 3, 250], ['sell', 2, 250], ['buy', 10, 100], ['buy', 10, 120], ['purchase_return', 2, 100], ['purchase_return', 5, 100], ['buy', 10, 150], ['buy', 2, 120], ['purchase_return', 5, 100]], {'cogs': 750, 'revenue': 1250, 'inventory': 3240, 'layers': [[3, 100], [10, 120], [10, 150], [2, 120]], 'rejected': [9]}], ['control 1', [['sell', 3, 250], ['buy', 2, 120], ['purchase_return', 1, 100], ['buy', 5, 100], ['buy', 2, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 980, 'layers': [[2, 120], [5, 100], [2, 120]], 'rejected': [0, 2]}], ['control 2', [['buy', 1, 120], ['sell', 12, 200], ['sell', 2, 250], ['sell', 2, 250]], {'cogs': 0, 'revenue': 0, 'inventory': 120, 'layers': [[1, 120]], 'rejected': [1, 2, 3]}], ['control 3', [['buy', 5, 100], ['sell', 3, 250], ['sell', 12, 200]], {'cogs': 300, 'revenue': 750, 'inventory': 200, 'layers': [[2, 100]], 'rejected': [2]}], ['control 4', [['buy', 10, 120], ['purchase_return', 1, 100], ['sell', 1, 200], ['purchase_return', 2, 100], ['sell', 2, 200], ['purchase_return', 1, 120], ['buy', 10, 120], ['buy', 5, 120]], {'cogs': 360, 'revenue': 600, 'inventory': 2520, 'layers': [[21, 120]], 'rejected': [1, 3]}], ['control 5', [['sell', 12, 250], ['sell', 12, 200], ['buy', 5, 100], ['sell', 12, 250], ['sell', 12, 200], ['purchase_return', 1, 100], ['sell', 3, 250]], {'cogs': 300, 'revenue': 750, 'inventory': 100, 'layers': [[1, 100]], 'rejected': [0, 1, 3, 4]}]], [['regression: return quantity check', [['sell', 1, 200], ['buy', 5, 120], ['sell', 6, 200], ['purchase_return', 2, 120], ['sell', 3, 200], ['buy', 10, 150], ['buy', 10, 120], ['buy', 5, 100], ['purchase_return', 5, 100]], {'cogs': 360, 'revenue': 600, 'inventory': 2700, 'layers': [[10, 150], [10, 120]], 'rejected': [0, 2]}], ['regression: return quantity check, partial-repair probe', [['buy', 2, 120], ['sell', 3, 200], ['buy', 1, 150], ['sell', 1, 200], ['purchase_return', 1, 100], ['sell', 6, 200], ['buy', 10, 100], ['buy', 10, 150], ['purchase_return', 2, 120], ['buy', 10, 100]], {'cogs': 120, 'revenue': 200, 'inventory': 3770, 'layers': [[1, 120], [1, 150], [10, 100], [10, 150], [10, 100]], 'rejected': [1, 4, 5, 8]}], ['control 1', [['sell', 12, 200], ['sell', 6, 250], ['sell', 6, 200]], {'cogs': 0, 'revenue': 0, 'inventory': 0, 'layers': [], 'rejected': [0, 1, 2]}], ['control 2', [['buy', 10, 100], ['sell', 12, 250], ['sell', 2, 250], ['sell', 12, 200], ['sell', 6, 200], ['buy', 1, 150], ['buy', 2, 120]], {'cogs': 800, 'revenue': 1700, 'inventory': 590, 'layers': [[2, 100], [1, 150], [2, 120]], 'rejected': [1, 3]}], ['control 3', [['purchase_return', 2, 100], ['sell', 12, 250], ['buy', 10, 100], ['buy', 1, 100], ['sell', 6, 200]], {'cogs': 600, 'revenue': 1200, 'inventory': 500, 'layers': [[5, 100]], 'rejected': [0, 1]}], ['control 4', [['buy', 10, 150], ['sell', 3, 250], ['sell', 12, 200], ['buy', 5, 120], ['sell', 3, 200], ['buy', 1, 100], ['sell', 1, 250], ['buy', 2, 100], ['sell', 12, 200], ['buy', 10, 100]], {'cogs': 1050, 'revenue': 1600, 'inventory': 2350, 'layers': [[3, 150], [5, 120], [13, 100]], 'rejected': [2, 8]}], ['control 5', [['sell', 2, 250], ['purchase_return', 1, 150], ['buy', 10, 100], ['buy', 10, 150], ['buy', 2, 150], ['buy', 2, 100], ['sell', 2, 250], ['sell', 3, 250], ['buy', 5, 120]], {'cogs': 500, 'revenue': 1250, 'inventory': 3100, 'layers': [[5, 100], [12, 150], [2, 100], [5, 120]], 'rejected': [0, 1]}]], [['regression: return quantity check', [['purchase_return', 1, 100], ['sell', 1, 200], ['sell', 1, 250], ['sell', 3, 200], ['sell', 6, 200], ['buy', 10, 120], ['buy', 2, 150], ['buy', 2, 100], ['purchase_return', 2, 150]], {'cogs': 0, 'revenue': 0, 'inventory': 1400, 'layers': [[10, 120], [2, 100]], 'rejected': [0, 1, 2, 3, 4]}], ['regression: return quantity check, partial-repair probe', [['buy', 1, 150], ['sell', 6, 200], ['sell', 3, 250], ['buy', 1, 120], ['buy', 5, 100], ['purchase_return', 2, 100], ['buy', 2, 100], ['purchase_return', 5, 150], ['buy', 1, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 890, 'layers': [[1, 150], [1, 120], [5, 100], [1, 120]], 'rejected': [1, 2, 7]}], ['control 1', [['purchase_return', 5, 100], ['sell', 2, 250], ['buy', 2, 100], ['buy', 1, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 320, 'layers': [[2, 100], [1, 120]], 'rejected': [0, 1]}], ['control 2', [['sell', 1, 250], ['buy', 5, 100], ['buy', 10, 100], ['sell', 2, 250], ['buy', 2, 100], ['buy', 10, 100], ['sell', 6, 200], ['buy', 1, 120], ['buy', 10, 150], ['buy', 10, 150]], {'cogs': 800, 'revenue': 1700, 'inventory': 5020, 'layers': [[19, 100], [1, 120], [20, 150]], 'rejected': [0]}], ['control 3', [['buy', 1, 100], ['purchase_return', 5, 100], ['sell', 3, 200], ['buy', 1, 150], ['buy', 1, 150], ['sell', 3, 200], ['buy', 2, 120], ['buy', 10, 120]], {'cogs': 400, 'revenue': 600, 'inventory': 1440, 'layers': [[12, 120]], 'rejected': [1, 2]}], ['control 4', [['purchase_return', 1, 100], ['buy', 2, 150], ['sell', 6, 200], ['sell', 2, 250], ['buy', 5, 120], ['buy', 5, 150], ['sell', 1, 250], ['purchase_return', 2, 100]], {'cogs': 420, 'revenue': 750, 'inventory': 1230, 'layers': [[4, 120], [5, 150]], 'rejected': [0, 2, 7]}], ['control 5', [['buy', 2, 120], ['purchase_return', 1, 150], ['buy', 1, 100], ['buy', 5, 100], ['sell', 3, 200]], {'cogs': 340, 'revenue': 600, 'inventory': 500, 'layers': [[5, 100]], 'rejected': [1]}]], [['regression: return quantity check', [['buy', 5, 120], ['purchase_return', 2, 100], ['buy', 2, 100], ['purchase_return', 5, 120], ['buy', 2, 100], ['purchase_return', 2, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 400, 'layers': [[4, 100]], 'rejected': [1, 5]}], ['regression: return quantity check, partial-repair probe', [['buy', 1, 150], ['buy', 5, 100], ['purchase_return', 2, 150], ['buy', 1, 100], ['buy', 1, 100], ['sell', 3, 250], ['buy', 10, 150], ['buy', 5, 100], ['sell', 1, 250]], {'cogs': 450, 'revenue': 1000, 'inventory': 2400, 'layers': [[4, 100], [10, 150], [5, 100]], 'rejected': [2]}], ['control 1', [['sell', 1, 250], ['sell', 3, 200], ['purchase_return', 1, 100], ['buy', 2, 120], ['buy', 5, 150], ['sell', 3, 200], ['sell', 1, 200], ['sell', 6, 250], ['buy', 2, 120]], {'cogs': 540, 'revenue': 800, 'inventory': 690, 'layers': [[3, 150], [2, 120]], 'rejected': [0, 1, 2, 7]}], ['control 2', [['buy', 1, 100], ['purchase_return', 2, 150], ['purchase_return', 1, 120], ['purchase_return', 2, 100], ['buy', 5, 100], ['buy', 10, 100], ['buy', 1, 150], ['buy', 1, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 1870, 'layers': [[16, 100], [1, 150], [1, 120]], 'rejected': [1, 2, 3]}], ['control 3', [['buy', 2, 150], ['buy', 10, 120], ['sell', 1, 200], ['purchase_return', 5, 100], ['buy', 1, 100], ['buy', 2, 150], ['buy', 1, 100], ['buy', 5, 100], ['sell', 3, 200]], {'cogs': 540, 'revenue': 800, 'inventory': 1960, 'layers': [[8, 120], [1, 100], [2, 150], [6, 100]], 'rejected': [3]}], ['control 4', [['sell', 12, 200], ['sell', 12, 250], ['buy', 2, 150], ['sell', 12, 250], ['buy', 2, 150], ['buy', 1, 100], ['buy', 5, 120], ['buy', 10, 150], ['sell', 3, 200], ['buy', 2, 150]], {'cogs': 450, 'revenue': 600, 'inventory': 2650, 'layers': [[1, 150], [1, 100], [5, 120], [12, 150]], 'rejected': [0, 1, 3]}], ['control 5', [['buy', 1, 100], ['buy', 2, 120], ['buy', 2, 120], ['sell', 3, 200], ['sell', 12, 200], ['buy', 5, 120], ['sell', 3, 200], ['purchase_return', 1, 100], ['buy', 2, 100]], {'cogs': 700, 'revenue': 1200, 'inventory': 680, 'layers': [[4, 120], [2, 100]], 'rejected': [4, 7]}]], [['regression: return quantity check', [['purchase_return', 1, 120], ['buy', 2, 150], ['sell', 6, 200], ['buy', 1, 120], ['sell', 12, 250], ['purchase_return', 1, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 300, 'layers': [[2, 150]], 'rejected': [0, 2, 4]}], ['regression: return quantity check, partial-repair probe', [['sell', 3, 200], ['sell', 1, 250], ['buy', 2, 100], ['purchase_return', 1, 100], ['buy', 10, 120], ['purchase_return', 5, 100]], {'cogs': 0, 'revenue': 0, 'inventory': 1300, 'layers': [[1, 100], [10, 120]], 'rejected': [0, 1, 5]}], ['control 1', [['buy', 10, 100], ['buy', 10, 150], ['purchase_return', 5, 100], ['sell', 6, 200], ['sell', 3, 200], ['sell', 2, 200]], {'cogs': 1400, 'revenue': 2200, 'inventory': 600, 'layers': [[4, 150]], 'rejected': []}], ['control 2', [['purchase_return', 2, 100], ['sell', 1, 200], ['buy', 5, 100], ['buy', 5, 100], ['purchase_return', 1, 150], ['sell', 2, 250], ['buy', 1, 100], ['sell', 1, 200]], {'cogs': 300, 'revenue': 700, 'inventory': 800, 'layers': [[8, 100]], 'rejected': [0, 1, 4]}], ['control 3', [['purchase_return', 1, 100], ['buy', 1, 100], ['sell', 3, 200], ['buy', 10, 100], ['buy', 5, 100], ['sell', 2, 200], ['purchase_return', 2, 150]], {'cogs': 200, 'revenue': 400, 'inventory': 1400, 'layers': [[14, 100]], 'rejected': [0, 2, 6]}], ['control 4', [['buy', 10, 120], ['buy', 1, 120], ['purchase_return', 2, 150], ['sell', 2, 250], ['buy', 1, 100]], {'cogs': 240, 'revenue': 500, 'inventory': 1180, 'layers': [[9, 120], [1, 100]], 'rejected': [2]}], ['control 5', [['sell', 6, 250], ['purchase_return', 2, 100], ['sell', 12, 250], ['sell', 3, 200]], {'cogs': 0, 'revenue': 0, 'inventory': 0, 'layers': [], 'rejected': [0, 1, 2, 3]}]]]
for label, args, expected in fixtures[N-1]:
    try:
        actual = solve(args)
    except Exception as exc:
        actual = 'raised ' + type(exc).__name__
    check(label, actual, expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

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):
    layers = []
    cogs = revenue = 0
    short = []
    for i, ev in enumerate(x):
        if ev[0] == 'buy':
            if layers and layers[-1][1] == ev[2]:
                layers[-1][0] += ev[1]
            else:
                layers.append([ev[1], ev[2]])
        elif ev[0] == 'sell':
            qty = ev[1]
            if qty > sum(l[0] for l in layers):
                short.append(i)
                continue
            revenue += qty * ev[2]
            while qty:
                head = layers[0]
                take = min(qty, head[0])
                cogs += take * head[1]
                head[0] -= take
                qty -= take
                if head[0] == 0:
                    layers.pop(0)
        elif ev[0] == 'purchase_return':
            match = [l for l in layers if l[1] == ev[2] and sum(k[0] for k in layers) >= ev[1]]
            if not match:
                short.append(i)
                continue
            match[-1][0] -= ev[1]
            if match[-1][0] == 0:
                layers.remove(match[-1])
    inventory = sum(q * c for q, c in layers)
    return {'cogs': cogs, 'revenue': revenue, 'inventory': inventory, 'layers': layers, 'rejected': short}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: return quantity check', [['buy', 2, 120], ['purchase_return', 1, 150], ['buy', 10, 100], ['sell', 6, 250], ['buy', 2, 100], ['sell', 12, 250], ['buy', 5, 120], ['buy', 5, 100], ['purchase_return', 5, 120]], {'cogs': 640, 'revenue': 1500, 'inventory': 1300, 'layers': [[8, 100], [5, 100]], 'rejected': [1, 5]}], ['regression: return quantity check, partial-repair probe', [['buy', 5, 150], ['sell', 3, 250], ['sell', 2, 250], ['buy', 10, 100], ['buy', 10, 120], ['purchase_return', 2, 100], ['purchase_return', 5, 100], ['buy', 10, 150], ['buy', 2, 120], ['purchase_return', 5, 100]], {'cogs': 750, 'revenue': 1250, 'inventory': 3240, 'layers': [[3, 100], [10, 120], [10, 150], [2, 120]], 'rejected': [9]}], ['control 1', [['sell', 3, 250], ['buy', 2, 120], ['purchase_return', 1, 100], ['buy', 5, 100], ['buy', 2, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 980, 'layers': [[2, 120], [5, 100], [2, 120]], 'rejected': [0, 2]}], ['control 2', [['buy', 1, 120], ['sell', 12, 200], ['sell', 2, 250], ['sell', 2, 250]], {'cogs': 0, 'revenue': 0, 'inventory': 120, 'layers': [[1, 120]], 'rejected': [1, 2, 3]}], ['control 3', [['buy', 5, 100], ['sell', 3, 250], ['sell', 12, 200]], {'cogs': 300, 'revenue': 750, 'inventory': 200, 'layers': [[2, 100]], 'rejected': [2]}], ['control 4', [['buy', 10, 120], ['purchase_return', 1, 100], ['sell', 1, 200], ['purchase_return', 2, 100], ['sell', 2, 200], ['purchase_return', 1, 120], ['buy', 10, 120], ['buy', 5, 120]], {'cogs': 360, 'revenue': 600, 'inventory': 2520, 'layers': [[21, 120]], 'rejected': [1, 3]}], ['control 5', [['sell', 12, 250], ['sell', 12, 200], ['buy', 5, 100], ['sell', 12, 250], ['sell', 12, 200], ['purchase_return', 1, 100], ['sell', 3, 250]], {'cogs': 300, 'revenue': 750, 'inventory': 100, 'layers': [[1, 100]], 'rejected': [0, 1, 3, 4]}]], [['regression: return quantity check', [['sell', 1, 200], ['buy', 5, 120], ['sell', 6, 200], ['purchase_return', 2, 120], ['sell', 3, 200], ['buy', 10, 150], ['buy', 10, 120], ['buy', 5, 100], ['purchase_return', 5, 100]], {'cogs': 360, 'revenue': 600, 'inventory': 2700, 'layers': [[10, 150], [10, 120]], 'rejected': [0, 2]}], ['regression: return quantity check, partial-repair probe', [['buy', 2, 120], ['sell', 3, 200], ['buy', 1, 150], ['sell', 1, 200], ['purchase_return', 1, 100], ['sell', 6, 200], ['buy', 10, 100], ['buy', 10, 150], ['purchase_return', 2, 120], ['buy', 10, 100]], {'cogs': 120, 'revenue': 200, 'inventory': 3770, 'layers': [[1, 120], [1, 150], [10, 100], [10, 150], [10, 100]], 'rejected': [1, 4, 5, 8]}], ['control 1', [['sell', 12, 200], ['sell', 6, 250], ['sell', 6, 200]], {'cogs': 0, 'revenue': 0, 'inventory': 0, 'layers': [], 'rejected': [0, 1, 2]}], ['control 2', [['buy', 10, 100], ['sell', 12, 250], ['sell', 2, 250], ['sell', 12, 200], ['sell', 6, 200], ['buy', 1, 150], ['buy', 2, 120]], {'cogs': 800, 'revenue': 1700, 'inventory': 590, 'layers': [[2, 100], [1, 150], [2, 120]], 'rejected': [1, 3]}], ['control 3', [['purchase_return', 2, 100], ['sell', 12, 250], ['buy', 10, 100], ['buy', 1, 100], ['sell', 6, 200]], {'cogs': 600, 'revenue': 1200, 'inventory': 500, 'layers': [[5, 100]], 'rejected': [0, 1]}], ['control 4', [['buy', 10, 150], ['sell', 3, 250], ['sell', 12, 200], ['buy', 5, 120], ['sell', 3, 200], ['buy', 1, 100], ['sell', 1, 250], ['buy', 2, 100], ['sell', 12, 200], ['buy', 10, 100]], {'cogs': 1050, 'revenue': 1600, 'inventory': 2350, 'layers': [[3, 150], [5, 120], [13, 100]], 'rejected': [2, 8]}], ['control 5', [['sell', 2, 250], ['purchase_return', 1, 150], ['buy', 10, 100], ['buy', 10, 150], ['buy', 2, 150], ['buy', 2, 100], ['sell', 2, 250], ['sell', 3, 250], ['buy', 5, 120]], {'cogs': 500, 'revenue': 1250, 'inventory': 3100, 'layers': [[5, 100], [12, 150], [2, 100], [5, 120]], 'rejected': [0, 1]}]], [['regression: return quantity check', [['purchase_return', 1, 100], ['sell', 1, 200], ['sell', 1, 250], ['sell', 3, 200], ['sell', 6, 200], ['buy', 10, 120], ['buy', 2, 150], ['buy', 2, 100], ['purchase_return', 2, 150]], {'cogs': 0, 'revenue': 0, 'inventory': 1400, 'layers': [[10, 120], [2, 100]], 'rejected': [0, 1, 2, 3, 4]}], ['regression: return quantity check, partial-repair probe', [['buy', 1, 150], ['sell', 6, 200], ['sell', 3, 250], ['buy', 1, 120], ['buy', 5, 100], ['purchase_return', 2, 100], ['buy', 2, 100], ['purchase_return', 5, 150], ['buy', 1, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 890, 'layers': [[1, 150], [1, 120], [5, 100], [1, 120]], 'rejected': [1, 2, 7]}], ['control 1', [['purchase_return', 5, 100], ['sell', 2, 250], ['buy', 2, 100], ['buy', 1, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 320, 'layers': [[2, 100], [1, 120]], 'rejected': [0, 1]}], ['control 2', [['sell', 1, 250], ['buy', 5, 100], ['buy', 10, 100], ['sell', 2, 250], ['buy', 2, 100], ['buy', 10, 100], ['sell', 6, 200], ['buy', 1, 120], ['buy', 10, 150], ['buy', 10, 150]], {'cogs': 800, 'revenue': 1700, 'inventory': 5020, 'layers': [[19, 100], [1, 120], [20, 150]], 'rejected': [0]}], ['control 3', [['buy', 1, 100], ['purchase_return', 5, 100], ['sell', 3, 200], ['buy', 1, 150], ['buy', 1, 150], ['sell', 3, 200], ['buy', 2, 120], ['buy', 10, 120]], {'cogs': 400, 'revenue': 600, 'inventory': 1440, 'layers': [[12, 120]], 'rejected': [1, 2]}], ['control 4', [['purchase_return', 1, 100], ['buy', 2, 150], ['sell', 6, 200], ['sell', 2, 250], ['buy', 5, 120], ['buy', 5, 150], ['sell', 1, 250], ['purchase_return', 2, 100]], {'cogs': 420, 'revenue': 750, 'inventory': 1230, 'layers': [[4, 120], [5, 150]], 'rejected': [0, 2, 7]}], ['control 5', [['buy', 2, 120], ['purchase_return', 1, 150], ['buy', 1, 100], ['buy', 5, 100], ['sell', 3, 200]], {'cogs': 340, 'revenue': 600, 'inventory': 500, 'layers': [[5, 100]], 'rejected': [1]}]], [['regression: return quantity check', [['buy', 5, 120], ['purchase_return', 2, 100], ['buy', 2, 100], ['purchase_return', 5, 120], ['buy', 2, 100], ['purchase_return', 2, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 400, 'layers': [[4, 100]], 'rejected': [1, 5]}], ['regression: return quantity check, partial-repair probe', [['buy', 1, 150], ['buy', 5, 100], ['purchase_return', 2, 150], ['buy', 1, 100], ['buy', 1, 100], ['sell', 3, 250], ['buy', 10, 150], ['buy', 5, 100], ['sell', 1, 250]], {'cogs': 450, 'revenue': 1000, 'inventory': 2400, 'layers': [[4, 100], [10, 150], [5, 100]], 'rejected': [2]}], ['control 1', [['sell', 1, 250], ['sell', 3, 200], ['purchase_return', 1, 100], ['buy', 2, 120], ['buy', 5, 150], ['sell', 3, 200], ['sell', 1, 200], ['sell', 6, 250], ['buy', 2, 120]], {'cogs': 540, 'revenue': 800, 'inventory': 690, 'layers': [[3, 150], [2, 120]], 'rejected': [0, 1, 2, 7]}], ['control 2', [['buy', 1, 100], ['purchase_return', 2, 150], ['purchase_return', 1, 120], ['purchase_return', 2, 100], ['buy', 5, 100], ['buy', 10, 100], ['buy', 1, 150], ['buy', 1, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 1870, 'layers': [[16, 100], [1, 150], [1, 120]], 'rejected': [1, 2, 3]}], ['control 3', [['buy', 2, 150], ['buy', 10, 120], ['sell', 1, 200], ['purchase_return', 5, 100], ['buy', 1, 100], ['buy', 2, 150], ['buy', 1, 100], ['buy', 5, 100], ['sell', 3, 200]], {'cogs': 540, 'revenue': 800, 'inventory': 1960, 'layers': [[8, 120], [1, 100], [2, 150], [6, 100]], 'rejected': [3]}], ['control 4', [['sell', 12, 200], ['sell', 12, 250], ['buy', 2, 150], ['sell', 12, 250], ['buy', 2, 150], ['buy', 1, 100], ['buy', 5, 120], ['buy', 10, 150], ['sell', 3, 200], ['buy', 2, 150]], {'cogs': 450, 'revenue': 600, 'inventory': 2650, 'layers': [[1, 150], [1, 100], [5, 120], [12, 150]], 'rejected': [0, 1, 3]}], ['control 5', [['buy', 1, 100], ['buy', 2, 120], ['buy', 2, 120], ['sell', 3, 200], ['sell', 12, 200], ['buy', 5, 120], ['sell', 3, 200], ['purchase_return', 1, 100], ['buy', 2, 100]], {'cogs': 700, 'revenue': 1200, 'inventory': 680, 'layers': [[4, 120], [2, 100]], 'rejected': [4, 7]}]], [['regression: return quantity check', [['purchase_return', 1, 120], ['buy', 2, 150], ['sell', 6, 200], ['buy', 1, 120], ['sell', 12, 250], ['purchase_return', 1, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 300, 'layers': [[2, 150]], 'rejected': [0, 2, 4]}], ['regression: return quantity check, partial-repair probe', [['sell', 3, 200], ['sell', 1, 250], ['buy', 2, 100], ['purchase_return', 1, 100], ['buy', 10, 120], ['purchase_return', 5, 100]], {'cogs': 0, 'revenue': 0, 'inventory': 1300, 'layers': [[1, 100], [10, 120]], 'rejected': [0, 1, 5]}], ['control 1', [['buy', 10, 100], ['buy', 10, 150], ['purchase_return', 5, 100], ['sell', 6, 200], ['sell', 3, 200], ['sell', 2, 200]], {'cogs': 1400, 'revenue': 2200, 'inventory': 600, 'layers': [[4, 150]], 'rejected': []}], ['control 2', [['purchase_return', 2, 100], ['sell', 1, 200], ['buy', 5, 100], ['buy', 5, 100], ['purchase_return', 1, 150], ['sell', 2, 250], ['buy', 1, 100], ['sell', 1, 200]], {'cogs': 300, 'revenue': 700, 'inventory': 800, 'layers': [[8, 100]], 'rejected': [0, 1, 4]}], ['control 3', [['purchase_return', 1, 100], ['buy', 1, 100], ['sell', 3, 200], ['buy', 10, 100], ['buy', 5, 100], ['sell', 2, 200], ['purchase_return', 2, 150]], {'cogs': 200, 'revenue': 400, 'inventory': 1400, 'layers': [[14, 100]], 'rejected': [0, 2, 6]}], ['control 4', [['buy', 10, 120], ['buy', 1, 120], ['purchase_return', 2, 150], ['sell', 2, 250], ['buy', 1, 100]], {'cogs': 240, 'revenue': 500, 'inventory': 1180, 'layers': [[9, 120], [1, 100]], 'rejected': [2]}], ['control 5', [['sell', 6, 250], ['purchase_return', 2, 100], ['sell', 12, 250], ['sell', 3, 200]], {'cogs': 0, 'revenue': 0, 'inventory': 0, 'layers': [], 'rejected': [0, 1, 2, 3]}]]]
for label, args, expected in fixtures[N-1]:
    try:
        actual = solve(args)
    except Exception as exc:
        actual = 'raised ' + type(exc).__name__
    check(label, actual, expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
Returning an entire purchase layer is rejected.

x = [['buy', qty, unit_cost] | ['sell', qty, unit_price] | ['purchase_return', qty, unit_cost]]. Layers are kept oldest first; a buy at the same cost as the newest layer merges into it. A sale consumes layers oldest first (COGS) and records revenue; a sale exceeding on-hand quantity is rejected whole. A purchase return removes qty from the newest layer at that cost holding at least qty, else it is rejected. Emptied layers are removed. Return {'cogs', 'revenue', 'inventory': sum qty*cost, 'layers', 'rejected': event indexes}.

split: open-access


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

N = 1
observations = []
def solve(x):
    layers = []
    cogs = revenue = 0
    short = []
    for i, ev in enumerate(x):
        if ev[0] == 'buy':
            if layers and layers[-1][1] == ev[2]:
                layers[-1][0] += ev[1]
            else:
                layers.append([ev[1], ev[2]])
        elif ev[0] == 'sell':
            qty = ev[1]
            if qty > sum(l[0] for l in layers):
                short.append(i)
                continue
            revenue += qty * ev[2]
            while qty:
                head = layers[0]
                take = min(qty, head[0])
                cogs += take * head[1]
                head[0] -= take
                qty -= take
                if head[0] == 0:
                    layers.pop(0)
        elif ev[0] == 'purchase_return':
            match = [l for l in layers if l[1] == ev[2] and l[0] >= ev[1]]
            if not match:
                short.append(i)
                continue
            match[-1][0] -= ev[1]
            if match[-1][0] == 0:
                layers.remove(match[-1])
    inventory = sum(q for q, c in layers) * layers[-1][1] if layers else 0
    return {'cogs': cogs, 'revenue': revenue, 'inventory': inventory, 'layers': layers, 'rejected': short}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: inventory valuation', [['sell', 3, 250], ['buy', 2, 120], ['purchase_return', 1, 100], ['buy', 5, 100], ['buy', 2, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 980, 'layers': [[2, 120], [5, 100], [2, 120]], 'rejected': [0, 2]}], ['control 1', [['buy', 1, 120], ['sell', 12, 200], ['sell', 2, 250], ['sell', 2, 250]], {'cogs': 0, 'revenue': 0, 'inventory': 120, 'layers': [[1, 120]], 'rejected': [1, 2, 3]}], ['control 2', [['buy', 5, 100], ['sell', 3, 250], ['sell', 12, 200]], {'cogs': 300, 'revenue': 750, 'inventory': 200, 'layers': [[2, 100]], 'rejected': [2]}], ['control 3', [['buy', 10, 120], ['purchase_return', 1, 100], ['sell', 1, 200], ['purchase_return', 2, 100], ['sell', 2, 200], ['purchase_return', 1, 120], ['buy', 10, 120], ['buy', 5, 120]], {'cogs': 360, 'revenue': 600, 'inventory': 2520, 'layers': [[21, 120]], 'rejected': [1, 3]}], ['control 4', [['sell', 12, 250], ['sell', 12, 200], ['buy', 5, 100], ['sell', 12, 250], ['sell', 12, 200], ['purchase_return', 1, 100], ['sell', 3, 250]], {'cogs': 300, 'revenue': 750, 'inventory': 100, 'layers': [[1, 100]], 'rejected': [0, 1, 3, 4]}], ['control 5', [['buy', 5, 100], ['sell', 3, 250], ['buy', 5, 100]], {'cogs': 300, 'revenue': 750, 'inventory': 700, 'layers': [[7, 100]], 'rejected': []}], ['control 6', [['sell', 3, 250], ['sell', 6, 200], ['buy', 10, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 1200, 'layers': [[10, 120]], 'rejected': [0, 1]}]], [['regression: inventory valuation', [['buy', 10, 100], ['sell', 12, 250], ['sell', 2, 250], ['sell', 12, 200], ['sell', 6, 200], ['buy', 1, 150], ['buy', 2, 120]], {'cogs': 800, 'revenue': 1700, 'inventory': 590, 'layers': [[2, 100], [1, 150], [2, 120]], 'rejected': [1, 3]}], ['control 1', [['sell', 12, 200], ['sell', 6, 250], ['sell', 6, 200]], {'cogs': 0, 'revenue': 0, 'inventory': 0, 'layers': [], 'rejected': [0, 1, 2]}], ['control 2', [['purchase_return', 2, 100], ['sell', 12, 250], ['buy', 10, 100], ['buy', 1, 100], ['sell', 6, 200]], {'cogs': 600, 'revenue': 1200, 'inventory': 500, 'layers': [[5, 100]], 'rejected': [0, 1]}], ['control 3', [['purchase_return', 5, 100], ['sell', 2, 200], ['purchase_return', 5, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 0, 'layers': [], 'rejected': [0, 1, 2]}], ['control 4', [['purchase_return', 2, 120], ['sell', 1, 250], ['purchase_return', 1, 120], ['purchase_return', 1, 120], ['buy', 10, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 1200, 'layers': [[10, 120]], 'rejected': [0, 1, 2, 3]}], ['control 5', [['sell', 6, 250], ['purchase_return', 1, 100], ['buy', 5, 100]], {'cogs': 0, 'revenue': 0, 'inventory': 500, 'layers': [[5, 100]], 'rejected': [0, 1]}], ['control 6', [['buy', 1, 100], ['purchase_return', 5, 100], ['sell', 1, 250]], {'cogs': 100, 'revenue': 250, 'inventory': 0, 'layers': [], 'rejected': [1]}]], [['regression: inventory valuation', [['purchase_return', 5, 100], ['sell', 2, 250], ['buy', 2, 100], ['buy', 1, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 320, 'layers': [[2, 100], [1, 120]], 'rejected': [0, 1]}], ['control 1', [['buy', 1, 100], ['purchase_return', 5, 100], ['sell', 3, 200], ['buy', 1, 150], ['buy', 1, 150], ['sell', 3, 200], ['buy', 2, 120], ['buy', 10, 120]], {'cogs': 400, 'revenue': 600, 'inventory': 1440, 'layers': [[12, 120]], 'rejected': [1, 2]}], ['control 2', [['buy', 2, 120], ['purchase_return', 1, 150], ['buy', 1, 100], ['buy', 5, 100], ['sell', 3, 200]], {'cogs': 340, 'revenue': 600, 'inventory': 500, 'layers': [[5, 100]], 'rejected': [1]}], ['control 3', [['sell', 6, 200], ['sell', 12, 200], ['sell', 2, 200], ['sell', 2, 200], ['buy', 2, 100], ['purchase_return', 1, 120], ['buy', 2, 150], ['sell', 2, 200], ['sell', 2, 200], ['sell', 2, 200]], {'cogs': 500, 'revenue': 800, 'inventory': 0, 'layers': [], 'rejected': [0, 1, 2, 3, 5, 9]}], ['control 4', [['sell', 12, 200], ['buy', 10, 100], ['purchase_return', 2, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 1000, 'layers': [[10, 100]], 'rejected': [0, 2]}], ['control 5', [['buy', 5, 100], ['sell', 6, 250], ['buy', 2, 100], ['buy', 5, 120], ['sell', 12, 250], ['sell', 1, 250]], {'cogs': 1300, 'revenue': 3000, 'inventory': 0, 'layers': [], 'rejected': [1, 5]}], ['control 6', [['purchase_return', 1, 150], ['sell', 1, 200], ['purchase_return', 5, 100], ['sell', 2, 250]], {'cogs': 0, 'revenue': 0, 'inventory': 0, 'layers': [], 'rejected': [0, 1, 2, 3]}]], [['regression: inventory valuation', [['sell', 1, 250], ['sell', 3, 200], ['purchase_return', 1, 100], ['buy', 2, 120], ['buy', 5, 150], ['sell', 3, 200], ['sell', 1, 200], ['sell', 6, 250], ['buy', 2, 120]], {'cogs': 540, 'revenue': 800, 'inventory': 690, 'layers': [[3, 150], [2, 120]], 'rejected': [0, 1, 2, 7]}], ['control 1', [['sell', 3, 250], ['purchase_return', 1, 150], ['purchase_return', 2, 120], ['sell', 6, 200], ['purchase_return', 2, 100]], {'cogs': 0, 'revenue': 0, 'inventory': 0, 'layers': [], 'rejected': [0, 1, 2, 3, 4]}], ['control 2', [['sell', 6, 200], ['purchase_return', 1, 150], ['buy', 5, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 600, 'layers': [[5, 120]], 'rejected': [0, 1]}], ['control 3', [['buy', 1, 150], ['sell', 12, 250], ['purchase_return', 5, 120], ['sell', 2, 250], ['buy', 2, 150], ['buy', 1, 150], ['purchase_return', 2, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 600, 'layers': [[4, 150]], 'rejected': [1, 2, 3, 6]}], ['control 4', [['buy', 2, 100], ['purchase_return', 2, 120], ['sell', 3, 200], ['buy', 10, 100], ['buy', 10, 100], ['sell', 2, 200], ['purchase_return', 2, 100], ['buy', 1, 100], ['purchase_return', 2, 100], ['buy', 1, 100]], {'cogs': 200, 'revenue': 400, 'inventory': 1800, 'layers': [[18, 100]], 'rejected': [1, 2]}], ['control 5', [['purchase_return', 2, 100], ['buy', 10, 100], ['sell', 12, 250], ['sell', 1, 200], ['purchase_return', 1, 150], ['sell', 6, 200], ['buy', 5, 100], ['purchase_return', 2, 100], ['sell', 6, 250], ['sell', 6, 200]], {'cogs': 1300, 'revenue': 2900, 'inventory': 0, 'layers': [], 'rejected': [0, 2, 4, 9]}], ['control 6', [['sell', 12, 200], ['sell', 3, 250], ['purchase_return', 2, 100], ['sell', 12, 250], ['sell', 12, 250], ['buy', 5, 100], ['sell', 3, 250]], {'cogs': 300, 'revenue': 750, 'inventory': 200, 'layers': [[2, 100]], 'rejected': [0, 1, 2, 3, 4]}]], [['regression: inventory valuation', [['buy', 10, 120], ['buy', 1, 120], ['purchase_return', 2, 150], ['sell', 2, 250], ['buy', 1, 100]], {'cogs': 240, 'revenue': 500, 'inventory': 1180, 'layers': [[9, 120], [1, 100]], 'rejected': [2]}], ['control 1', [['buy', 10, 100], ['buy', 10, 150], ['purchase_return', 5, 100], ['sell', 6, 200], ['sell', 3, 200], ['sell', 2, 200]], {'cogs': 1400, 'revenue': 2200, 'inventory': 600, 'layers': [[4, 150]], 'rejected': []}], ['control 2', [['purchase_return', 2, 100], ['sell', 1, 200], ['buy', 5, 100], ['buy', 5, 100], ['purchase_return', 1, 150], ['sell', 2, 250], ['buy', 1, 100], ['sell', 1, 200]], {'cogs': 300, 'revenue': 700, 'inventory': 800, 'layers': [[8, 100]], 'rejected': [0, 1, 4]}], ['control 3', [['purchase_return', 1, 100], ['buy', 1, 100], ['sell', 3, 200], ['buy', 10, 100], ['buy', 5, 100], ['sell', 2, 200], ['purchase_return', 2, 150]], {'cogs': 200, 'revenue': 400, 'inventory': 1400, 'layers': [[14, 100]], 'rejected': [0, 2, 6]}], ['control 4', [['sell', 6, 250], ['purchase_return', 2, 100], ['sell', 12, 250], ['sell', 3, 200]], {'cogs': 0, 'revenue': 0, 'inventory': 0, 'layers': [], 'rejected': [0, 1, 2, 3]}], ['control 5', [['sell', 6, 250], ['sell', 3, 250], ['sell', 12, 200], ['sell', 1, 250], ['sell', 3, 250], ['purchase_return', 5, 150], ['sell', 6, 200]], {'cogs': 0, 'revenue': 0, 'inventory': 0, 'layers': [], 'rejected': [0, 1, 2, 3, 4, 5, 6]}], ['control 6', [['sell', 3, 200], ['sell', 12, 200], ['buy', 10, 120], ['sell', 3, 200], ['sell', 12, 200]], {'cogs': 360, 'revenue': 600, 'inventory': 840, 'layers': [[7, 120]], 'rejected': [0, 1, 4]}]]]
for label, args, expected in fixtures[N-1]:
    try:
        actual = solve(args)
    except Exception as exc:
        actual = 'raised ' + type(exc).__name__
    check(label, actual, expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

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

N = 1
observations = []
def solve(x):
    layers = []
    cogs = revenue = 0
    short = []
    for i, ev in enumerate(x):
        if ev[0] == 'buy':
            if layers and layers[-1][1] == ev[2]:
                layers[-1][0] += ev[1]
            else:
                layers.append([ev[1], ev[2]])
        elif ev[0] == 'sell':
            qty = ev[1]
            if qty > sum(l[0] for l in layers):
                short.append(i)
                continue
            revenue += qty * ev[2]
            while qty:
                head = layers[0]
                take = min(qty, head[0])
                cogs += take * head[1]
                head[0] -= take
                qty -= take
                if head[0] == 0:
                    layers.pop(0)
        elif ev[0] == 'purchase_return':
            match = [l for l in layers if l[1] == ev[2] and l[0] >= ev[1]]
            if not match:
                short.append(i)
                continue
            match[-1][0] -= ev[1]
            if match[-1][0] == 0:
                layers.remove(match[-1])
    inventory = sum(q for q, c in layers) * layers[0][1] if layers else 0
    return {'cogs': cogs, 'revenue': revenue, 'inventory': inventory, 'layers': layers, 'rejected': short}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: inventory valuation', [['sell', 3, 250], ['buy', 2, 120], ['purchase_return', 1, 100], ['buy', 5, 100], ['buy', 2, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 980, 'layers': [[2, 120], [5, 100], [2, 120]], 'rejected': [0, 2]}], ['control 1', [['buy', 1, 120], ['sell', 12, 200], ['sell', 2, 250], ['sell', 2, 250]], {'cogs': 0, 'revenue': 0, 'inventory': 120, 'layers': [[1, 120]], 'rejected': [1, 2, 3]}], ['control 2', [['buy', 5, 100], ['sell', 3, 250], ['sell', 12, 200]], {'cogs': 300, 'revenue': 750, 'inventory': 200, 'layers': [[2, 100]], 'rejected': [2]}], ['control 3', [['buy', 10, 120], ['purchase_return', 1, 100], ['sell', 1, 200], ['purchase_return', 2, 100], ['sell', 2, 200], ['purchase_return', 1, 120], ['buy', 10, 120], ['buy', 5, 120]], {'cogs': 360, 'revenue': 600, 'inventory': 2520, 'layers': [[21, 120]], 'rejected': [1, 3]}], ['control 4', [['sell', 12, 250], ['sell', 12, 200], ['buy', 5, 100], ['sell', 12, 250], ['sell', 12, 200], ['purchase_return', 1, 100], ['sell', 3, 250]], {'cogs': 300, 'revenue': 750, 'inventory': 100, 'layers': [[1, 100]], 'rejected': [0, 1, 3, 4]}], ['control 5', [['buy', 5, 100], ['sell', 3, 250], ['buy', 5, 100]], {'cogs': 300, 'revenue': 750, 'inventory': 700, 'layers': [[7, 100]], 'rejected': []}], ['control 6', [['sell', 3, 250], ['sell', 6, 200], ['buy', 10, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 1200, 'layers': [[10, 120]], 'rejected': [0, 1]}]], [['regression: inventory valuation', [['buy', 10, 100], ['sell', 12, 250], ['sell', 2, 250], ['sell', 12, 200], ['sell', 6, 200], ['buy', 1, 150], ['buy', 2, 120]], {'cogs': 800, 'revenue': 1700, 'inventory': 590, 'layers': [[2, 100], [1, 150], [2, 120]], 'rejected': [1, 3]}], ['control 1', [['sell', 12, 200], ['sell', 6, 250], ['sell', 6, 200]], {'cogs': 0, 'revenue': 0, 'inventory': 0, 'layers': [], 'rejected': [0, 1, 2]}], ['control 2', [['purchase_return', 2, 100], ['sell', 12, 250], ['buy', 10, 100], ['buy', 1, 100], ['sell', 6, 200]], {'cogs': 600, 'revenue': 1200, 'inventory': 500, 'layers': [[5, 100]], 'rejected': [0, 1]}], ['control 3', [['purchase_return', 5, 100], ['sell', 2, 200], ['purchase_return', 5, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 0, 'layers': [], 'rejected': [0, 1, 2]}], ['control 4', [['purchase_return', 2, 120], ['sell', 1, 250], ['purchase_return', 1, 120], ['purchase_return', 1, 120], ['buy', 10, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 1200, 'layers': [[10, 120]], 'rejected': [0, 1, 2, 3]}], ['control 5', [['sell', 6, 250], ['purchase_return', 1, 100], ['buy', 5, 100]], {'cogs': 0, 'revenue': 0, 'inventory': 500, 'layers': [[5, 100]], 'rejected': [0, 1]}], ['control 6', [['buy', 1, 100], ['purchase_return', 5, 100], ['sell', 1, 250]], {'cogs': 100, 'revenue': 250, 'inventory': 0, 'layers': [], 'rejected': [1]}]], [['regression: inventory valuation', [['purchase_return', 5, 100], ['sell', 2, 250], ['buy', 2, 100], ['buy', 1, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 320, 'layers': [[2, 100], [1, 120]], 'rejected': [0, 1]}], ['control 1', [['buy', 1, 100], ['purchase_return', 5, 100], ['sell', 3, 200], ['buy', 1, 150], ['buy', 1, 150], ['sell', 3, 200], ['buy', 2, 120], ['buy', 10, 120]], {'cogs': 400, 'revenue': 600, 'inventory': 1440, 'layers': [[12, 120]], 'rejected': [1, 2]}], ['control 2', [['buy', 2, 120], ['purchase_return', 1, 150], ['buy', 1, 100], ['buy', 5, 100], ['sell', 3, 200]], {'cogs': 340, 'revenue': 600, 'inventory': 500, 'layers': [[5, 100]], 'rejected': [1]}], ['control 3', [['sell', 6, 200], ['sell', 12, 200], ['sell', 2, 200], ['sell', 2, 200], ['buy', 2, 100], ['purchase_return', 1, 120], ['buy', 2, 150], ['sell', 2, 200], ['sell', 2, 200], ['sell', 2, 200]], {'cogs': 500, 'revenue': 800, 'inventory': 0, 'layers': [], 'rejected': [0, 1, 2, 3, 5, 9]}], ['control 4', [['sell', 12, 200], ['buy', 10, 100], ['purchase_return', 2, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 1000, 'layers': [[10, 100]], 'rejected': [0, 2]}], ['control 5', [['buy', 5, 100], ['sell', 6, 250], ['buy', 2, 100], ['buy', 5, 120], ['sell', 12, 250], ['sell', 1, 250]], {'cogs': 1300, 'revenue': 3000, 'inventory': 0, 'layers': [], 'rejected': [1, 5]}], ['control 6', [['purchase_return', 1, 150], ['sell', 1, 200], ['purchase_return', 5, 100], ['sell', 2, 250]], {'cogs': 0, 'revenue': 0, 'inventory': 0, 'layers': [], 'rejected': [0, 1, 2, 3]}]], [['regression: inventory valuation', [['sell', 1, 250], ['sell', 3, 200], ['purchase_return', 1, 100], ['buy', 2, 120], ['buy', 5, 150], ['sell', 3, 200], ['sell', 1, 200], ['sell', 6, 250], ['buy', 2, 120]], {'cogs': 540, 'revenue': 800, 'inventory': 690, 'layers': [[3, 150], [2, 120]], 'rejected': [0, 1, 2, 7]}], ['control 1', [['sell', 3, 250], ['purchase_return', 1, 150], ['purchase_return', 2, 120], ['sell', 6, 200], ['purchase_return', 2, 100]], {'cogs': 0, 'revenue': 0, 'inventory': 0, 'layers': [], 'rejected': [0, 1, 2, 3, 4]}], ['control 2', [['sell', 6, 200], ['purchase_return', 1, 150], ['buy', 5, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 600, 'layers': [[5, 120]], 'rejected': [0, 1]}], ['control 3', [['buy', 1, 150], ['sell', 12, 250], ['purchase_return', 5, 120], ['sell', 2, 250], ['buy', 2, 150], ['buy', 1, 150], ['purchase_return', 2, 120]], {'cogs': 0, 'revenue': 0, 'inventory': 600, 'layers': [[4, 150]], 'rejected': [1, 2, 3, 6]}], ['control 4', [['buy', 2, 100], ['purchase_return', 2, 120], ['sell', 3, 200], ['buy', 10, 100], ['buy', 10, 100], ['sell', 2, 200], ['purchase_return', 2, 100], ['buy', 1, 100], ['purchase_return', 2, 100], ['buy', 1, 100]], {'cogs': 200, 'revenue': 400, 'inventory': 1800, 'layers': [[18, 100]], 'rejected': [1, 2]}], ['control 5', [['purchase_return', 2, 100], ['buy', 10, 100], ['sell', 12, 250], ['sell', 1, 200], ['purchase_return', 1, 150], ['sell', 6, 200], ['buy', 5, 100], ['purchase_return', 2, 100], ['sell', 6, 250], ['sell', 6, 200]], {'cogs': 1300, 'revenue': 2900, 'inventory': 0, 'layers': [], 'rejected': [0, 2, 4, 9]}], ['control 6', [['sell', 12, 200], ['sell', 3, 250], ['purchase_return', 2, 100], ['sell', 12, 250], ['sell', 12, 250], ['buy', 5, 100], ['sell', 3, 250]], {'cogs': 300, 'revenue': 750, 'inventory': 200, 'layers': [[2, 100]], 'rejected': [0, 1, 2, 3, 4]}]], [['regression: inventory valuation', [['buy', 10, 120], ['buy', 1, 120], ['purchase_return', 2, 150], ['sell', 2, 250], ['buy', 1, 100]], {'cogs': 240, 'revenue': 500, 'inventory': 1180, 'layers': [[9, 120], [1, 100]], 'rejected': [2]}], ['control 1', [['buy', 10, 100], ['buy', 10, 150], ['purchase_return', 5, 100], ['sell', 6, 200], ['sell', 3, 200], ['sell', 2, 200]], {'cogs': 1400, 'revenue': 2200, 'inventory': 600, 'layers': [[4, 150]], 'rejected': []}], ['control 2', [['purchase_return', 2, 100], ['sell', 1, 200], ['buy', 5, 100], ['buy', 5, 100], ['purchase_return', 1, 150], ['sell', 2, 250], ['buy', 1, 100], ['sell', 1, 200]], {'cogs': 300, 'revenue': 700, 'inventory': 800, 'layers': [[8, 100]], 'rejected': [0, 1, 4]}], ['control 3', [['purchase_return', 1, 100], ['buy', 1, 100], ['sell', 3, 200], ['buy', 10, 100], ['buy', 5, 100], ['sell', 2, 200], ['purchase_return', 2, 150]], {'cogs': 200, 'revenue': 400, 'inventory': 1400, 'layers': [[14, 100]], 'rejected': [0, 2, 6]}], ['control 4', [['sell', 6, 250], ['purchase_return', 2, 100], ['sell', 12, 250], ['sell', 3, 200]], {'cogs': 0, 'revenue': 0, 'inventory': 0, 'layers': [], 'rejected': [0, 1, 2, 3]}], ['control 5', [['sell', 6, 250], ['sell', 3, 250], ['sell', 12, 200], ['sell', 1, 250], ['sell', 3, 250], ['purchase_return', 5, 150], ['sell', 6, 200]], {'cogs': 0, 'revenue': 0, 'inventory': 0, 'layers': [], 'rejected': [0, 1, 2, 3, 4, 5, 6]}], ['control 6', [['sell', 3, 200], ['sell', 12, 200], ['buy', 10, 120], ['sell', 3, 200], ['sell', 12, 200]], {'cogs': 360, 'revenue': 600, 'inventory': 840, 'layers': [[7, 120]], 'rejected': [0, 1, 4]}]]]
for label, args, expected in fixtures[N-1]:
    try:
        actual = solve(args)
    except Exception as exc:
        actual = 'raised ' + type(exc).__name__
    check(label, actual, expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
Ending inventory is valued at the latest purchase price.

x = [['buy', qty, unit_cost] | ['sell', qty, unit_price] | ['purchase_return', qty, unit_cost]]. Layers are kept oldest first; a buy at the same cost as the newest layer merges into it. A sale consumes layers oldest first (COGS) and records revenue; a sale exceeding on-hand quantity is rejected whole. A purchase return removes qty from the newest layer at that cost holding at least qty, else it is rejected. Emptied layers are removed. Return {'cogs', 'revenue', 'inventory': sum qty*cost, 'layers', 'rejected': event indexes}.

split: open-access


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

N = 1
observations = []
def solve(x):
    wo = set(x['writeoffs'])
    allowance = x['allowance']
    buckets = [0] * len(x['rates'])
    for iid, due, amt in x['invoices']:
        if iid in wo:
            allowance -= amt
            continue
        past = max(0, x['as_of'] - due)
        for k, (limit, bp) in enumerate(x['rates']):
            if limit is None or past < limit:
                buckets[k] += amt
                break
    required = 0
    for total, (limit, bp) in zip(buckets, x['rates']):
        q, r = divmod(total * bp, 10000)
        required += q + (1 if 2 * r >= 10000 else 0)
    ar = sum(buckets)
    return {'buckets': buckets, 'required': required, 'adjustment': required - allowance, 'net_ar': ar - required}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: bucket upper bound', {'as_of': 100, 'invoices': [['I0', 99, 4000], ['I1', 55, 150], ['I2', -100, 333], ['I3', 100, 150], ['I4', 100, 5], ['I5', 9, 4000]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 200, 'writeoffs': ['I5']}, {'buckets': [155, 4000, 150, 0, 333], 'required': 475, 'adjustment': 4275, 'net_ar': 4163}], ['regression: bucket upper bound, partial-repair probe', {'as_of': 100, 'invoices': [['I0', 39, 4000], ['I1', 10, 150], ['I2', 110, 5], ['I3', 40, 5], ['I4', 99, 150], ['I5', 54, 4000], ['I6', 54, 1000]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 500, 'writeoffs': ['I6']}, {'buckets': [5, 150, 4005, 4150, 0], 'required': 2269, 'adjustment': 2769, 'net_ar': 6041}], ['control 1', {'as_of': 100, 'invoices': [['I0', -100, 5], ['I1', 39, 333], ['I2', 9, 2500], ['I3', -100, 4000], ['I4', 69, 150], ['I5', 70, 2500], ['I6', 55, 4000]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 0, 'writeoffs': ['I5', 'I6']}, {'buckets': [0, 0, 150, 333, 6505], 'required': 5035, 'adjustment': 11535, 'net_ar': 1953}], ['control 2', {'as_of': 100, 'invoices': [['I0', 55, 2500], ['I1', 99, 4000], ['I2', 99, 150], ['I3', 55, 5]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 200, 'writeoffs': ['I0']}, {'buckets': [0, 4150, 5, 0, 0], 'required': 209, 'adjustment': 2509, 'net_ar': 3946}], ['control 3', {'as_of': 100, 'invoices': [['I0', 40, 2500], ['I1', 99, 4000], ['I2', 9, 1000]], 'rates': [[0, 200], [45, 1250], [None, 5000]], 'allowance': 0, 'writeoffs': []}, {'buckets': [0, 4000, 3500], 'required': 2250, 'adjustment': 2250, 'net_ar': 5250}], ['control 4', {'as_of': 100, 'invoices': [['I0', 54, 333], ['I1', 9, 4000], ['I2', 54, 2500], ['I3', 55, 1000], ['I4', 10, 1000], ['I5', 71, 1000]], 'rates': [[0, 200], [45, 1250], [None, 5000]], 'allowance': -150, 'writeoffs': ['I0', 'I1', 'I3']}, {'buckets': [0, 1000, 3500], 'required': 1875, 'adjustment': 7358, 'net_ar': 2625}], ['control 5', {'as_of': 100, 'invoices': [['I0', 39, 4000], ['I1', 70, 333], ['I2', 9, 1000]], 'rates': [[0, 200], [45, 1250], [None, 5000]], 'allowance': 500, 'writeoffs': ['I2']}, {'buckets': [0, 333, 4000], 'required': 2042, 'adjustment': 2542, 'net_ar': 2291}]], [['regression: bucket upper bound', {'as_of': 100, 'invoices': [['I0', 99, 5], ['I1', 39, 5], ['I2', 10, 150], ['I3', -100, 333], ['I4', 39, 1000], ['I5', 39, 4000], ['I6', 100, 2500]], 'rates': [[0, 200], [45, 1250], [None, 5000]], 'allowance': -150, 'writeoffs': ['I2', 'I3']}, {'buckets': [2500, 5, 5005], 'required': 2554, 'adjustment': 3187, 'net_ar': 4956}], ['regression: bucket upper bound, partial-repair probe', {'as_of': 100, 'invoices': [['I0', 54, 2500], ['I1', 55, 5], ['I2', 10, 1000], ['I3', 71, 333], ['I4', 71, 1000], ['I5', 100, 5]], 'rates': [[0, 200], [45, 1250], [None, 5000]], 'allowance': -150, 'writeoffs': ['I2', 'I5']}, {'buckets': [0, 1338, 2500], 'required': 1417, 'adjustment': 2572, 'net_ar': 2421}], ['control 1', {'as_of': 100, 'invoices': [['I0', 99, 2500], ['I1', 69, 1000], ['I2', 55, 333], ['I3', 39, 1000], ['I4', 39, 333], ['I5', 40, 4000]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 200, 'writeoffs': ['I1', 'I4', 'I5']}, {'buckets': [0, 2500, 333, 1000, 0], 'required': 575, 'adjustment': 5708, 'net_ar': 3258}], ['control 2', {'as_of': 100, 'invoices': [['I0', 70, 5], ['I1', 69, 5], ['I2', 71, 333], ['I3', -100, 5], ['I4', 54, 333], ['I5', 100, 150], ['I6', 71, 150]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 200, 'writeoffs': ['I0', 'I5']}, {'buckets': [0, 483, 338, 0, 5], 'required': 79, 'adjustment': 34, 'net_ar': 747}], ['control 3', {'as_of': 100, 'invoices': [['I0', -100, 150], ['I1', 40, 1000], ['I2', 40, 5], ['I3', 39, 1000], ['I4', 9, 150], ['I5', 10, 1000], ['I6', 10, 150]], 'rates': [[0, 200], [45, 1250], [None, 5000]], 'allowance': 200, 'writeoffs': ['I2', 'I5']}, {'buckets': [0, 0, 2450], 'required': 1225, 'adjustment': 2030, 'net_ar': 1225}], ['control 4', {'as_of': 100, 'invoices': [['I0', 54, 333], ['I1', 40, 2500], ['I2', 9, 150]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': -150, 'writeoffs': ['I1']}, {'buckets': [0, 0, 333, 0, 150], 'required': 163, 'adjustment': 2813, 'net_ar': 320}], ['control 5', {'as_of': 100, 'invoices': [['I0', 69, 2500], ['I1', 9, 5], ['I2', 71, 333]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 200, 'writeoffs': ['I2']}, {'buckets': [0, 0, 2500, 0, 5], 'required': 379, 'adjustment': 512, 'net_ar': 2126}]], [['regression: bucket upper bound', {'as_of': 100, 'invoices': [['I0', 54, 150], ['I1', 71, 4000], ['I2', 70, 2500], ['I3', 110, 150], ['I4', 99, 5]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 500, 'writeoffs': ['I3']}, {'buckets': [0, 6505, 150, 0, 0], 'required': 348, 'adjustment': -2, 'net_ar': 6307}], ['control 1', {'as_of': 100, 'invoices': [['I0', 39, 2500], ['I1', 69, 150], ['I2', 55, 333]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 200, 'writeoffs': ['I1']}, {'buckets': [0, 0, 333, 2500, 0], 'required': 1050, 'adjustment': 1000, 'net_ar': 1783}], ['control 2', {'as_of': 100, 'invoices': [['I0', -100, 333], ['I1', 99, 5], ['I2', 10, 150], ['I3', 9, 2500], ['I4', -100, 2500], ['I5', 55, 333], ['I6', 71, 2500]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': -150, 'writeoffs': ['I2']}, {'buckets': [0, 2505, 333, 0, 5333], 'required': 4175, 'adjustment': 4475, 'net_ar': 3996}], ['control 3', {'as_of': 100, 'invoices': [['I0', 71, 2500], ['I1', 100, 150], ['I2', 9, 5]], 'rates': [[0, 200], [45, 1250], [None, 5000]], 'allowance': 0, 'writeoffs': ['I1']}, {'buckets': [0, 2500, 5], 'required': 316, 'adjustment': 466, 'net_ar': 2189}], ['control 4', {'as_of': 100, 'invoices': [['I0', 71, 4000], ['I1', -100, 4000], ['I2', 39, 5], ['I3', 99, 2500]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 0, 'writeoffs': ['I0', 'I3']}, {'buckets': [0, 0, 0, 5, 4000], 'required': 3002, 'adjustment': 9502, 'net_ar': 1003}], ['control 5', {'as_of': 100, 'invoices': [['I0', 10, 333], ['I1', -100, 150], ['I2', 99, 1000], ['I3', 71, 2500], ['I4', 39, 2500], ['I5', 54, 333]], 'rates': [[0, 200], [45, 1250], [None, 5000]], 'allowance': 500, 'writeoffs': []}, {'buckets': [0, 3500, 3316], 'required': 2096, 'adjustment': 1596, 'net_ar': 4720}], ['control 6', {'as_of': 100, 'invoices': [['I0', 99, 333], ['I1', 55, 2500], ['I2', 100, 5]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': -150, 'writeoffs': ['I0', 'I2']}, {'buckets': [0, 0, 2500, 0, 0], 'required': 375, 'adjustment': 863, 'net_ar': 2125}]], [['regression: bucket upper bound', {'as_of': 100, 'invoices': [['I0', 110, 150], ['I1', 10, 1000], ['I2', 70, 150], ['I3', 99, 1000], ['I4', 100, 2500], ['I5', 55, 333], ['I6', 54, 150]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 0, 'writeoffs': ['I5', 'I6']}, {'buckets': [2650, 1150, 0, 1000, 0], 'required': 485, 'adjustment': 968, 'net_ar': 4315}], ['control 1', {'as_of': 100, 'invoices': [['I0', 70, 1000], ['I1', 10, 5], ['I2', 39, 150], ['I3', 54, 5], ['I4', 70, 2500], ['I5', 40, 150], ['I6', 39, 5]], 'rates': [[0, 200], [45, 1250], [None, 5000]], 'allowance': 200, 'writeoffs': ['I2', 'I4']}, {'buckets': [0, 1000, 165], 'required': 208, 'adjustment': 2658, 'net_ar': 957}], ['control 2', {'as_of': 100, 'invoices': [['I0', 69, 150], ['I1', 71, 150], ['I2', 70, 150]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 500, 'writeoffs': ['I2']}, {'buckets': [0, 150, 150, 0, 0], 'required': 31, 'adjustment': -319, 'net_ar': 269}], ['control 3', {'as_of': 100, 'invoices': [['I0', 71, 333], ['I1', 39, 150], ['I2', 71, 4000]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 0, 'writeoffs': []}, {'buckets': [0, 4333, 0, 150, 0], 'required': 277, 'adjustment': 277, 'net_ar': 4206}], ['control 4', {'as_of': 100, 'invoices': [['I0', 9, 5], ['I1', 71, 150], ['I2', 70, 1000], ['I3', 54, 1000]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 0, 'writeoffs': ['I2']}, {'buckets': [0, 150, 1000, 0, 5], 'required': 162, 'adjustment': 1162, 'net_ar': 993}], ['control 5', {'as_of': 100, 'invoices': [['I0', 69, 2500], ['I1', 69, 150], ['I2', 55, 5], ['I3', 71, 1000], ['I4', 55, 4000], ['I5', -100, 2500], ['I6', 69, 4000]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 500, 'writeoffs': []}, {'buckets': [0, 1000, 10655, 0, 2500], 'required': 3523, 'adjustment': 3023, 'net_ar': 10632}], ['control 6', {'as_of': 100, 'invoices': [['I0', 10, 4000], ['I1', 9, 1000], ['I2', -100, 2500], ['I3', -100, 150], ['I4', 70, 4000]], 'rates': [[0, 200], [45, 1250], [None, 5000]], 'allowance': 0, 'writeoffs': ['I0']}, {'buckets': [0, 4000, 3650], 'required': 2325, 'adjustment': 6325, 'net_ar': 5325}]], [['regression: bucket upper bound', {'as_of': 100, 'invoices': [['I0', 70, 4000], ['I1', 70, 2500], ['I2', 100, 4000], ['I3', 71, 5]], 'rates': [[0, 200], [45, 1250], [None, 5000]], 'allowance': 0, 'writeoffs': ['I1']}, {'buckets': [4000, 4005, 0], 'required': 581, 'adjustment': 3081, 'net_ar': 7424}], ['regression: bucket upper bound, partial-repair probe', {'as_of': 100, 'invoices': [['I0', 40, 4000], ['I1', 39, 1000], ['I2', -100, 5], ['I3', 99, 5], ['I4', -100, 333], ['I5', 10, 4000]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 500, 'writeoffs': ['I3']}, {'buckets': [0, 0, 4000, 5000, 338], 'required': 2854, 'adjustment': 2359, 'net_ar': 6484}], ['control 1', {'as_of': 100, 'invoices': [['I0', 9, 150], ['I1', 9, 1000], ['I2', 54, 1000], ['I3', 99, 2500], ['I4', 69, 333], ['I5', 71, 5]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': -150, 'writeoffs': []}, {'buckets': [0, 2505, 1333, 0, 1150], 'required': 1188, 'adjustment': 1338, 'net_ar': 3800}], ['control 2', {'as_of': 100, 'invoices': [['I0', 39, 5], ['I1', 99, 4000], ['I2', 55, 4000]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 0, 'writeoffs': ['I0', 'I1']}, {'buckets': [0, 0, 4000, 0, 0], 'required': 600, 'adjustment': 4605, 'net_ar': 3400}], ['control 3', {'as_of': 100, 'invoices': [['I0', 54, 5], ['I1', 40, 5], ['I2', 99, 333], ['I3', 71, 150], ['I4', 54, 4000]], 'rates': [[0, 200], [45, 1250], [None, 5000]], 'allowance': 0, 'writeoffs': []}, {'buckets': [0, 483, 4010], 'required': 2065, 'adjustment': 2065, 'net_ar': 2428}], ['control 4', {'as_of': 100, 'invoices': [['I0', 55, 5], ['I1', 100, 150], ['I2', 99, 150]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 0, 'writeoffs': ['I0', 'I1', 'I2']}, {'buckets': [0, 0, 0, 0, 0], 'required': 0, 'adjustment': 305, 'net_ar': 0}], ['control 5', {'as_of': 100, 'invoices': [['I0', 39, 2500], ['I1', 99, 333], ['I2', 69, 333]], 'rates': [[0, 200], [45, 1250], [None, 5000]], 'allowance': 0, 'writeoffs': ['I0']}, {'buckets': [0, 666, 0], 'required': 83, 'adjustment': 2583, 'net_ar': 583}]]]
for label, args, expected in fixtures[N-1]:
    try:
        actual = solve(args)
    except Exception as exc:
        actual = 'raised ' + type(exc).__name__
    check(label, actual, expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

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

N = 1
observations = []
def solve(x):
    wo = set(x['writeoffs'])
    allowance = x['allowance']
    buckets = [0] * len(x['rates'])
    for iid, due, amt in x['invoices']:
        if iid in wo:
            allowance -= amt
            continue
        past = max(0, x['as_of'] - due)
        for k, (limit, bp) in enumerate(x['rates']):
            if limit is None or past < limit or past == 0:
                buckets[k] += amt
                break
    required = 0
    for total, (limit, bp) in zip(buckets, x['rates']):
        q, r = divmod(total * bp, 10000)
        required += q + (1 if 2 * r >= 10000 else 0)
    ar = sum(buckets)
    return {'buckets': buckets, 'required': required, 'adjustment': required - allowance, 'net_ar': ar - required}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: bucket upper bound', {'as_of': 100, 'invoices': [['I0', 99, 4000], ['I1', 55, 150], ['I2', -100, 333], ['I3', 100, 150], ['I4', 100, 5], ['I5', 9, 4000]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 200, 'writeoffs': ['I5']}, {'buckets': [155, 4000, 150, 0, 333], 'required': 475, 'adjustment': 4275, 'net_ar': 4163}], ['regression: bucket upper bound, partial-repair probe', {'as_of': 100, 'invoices': [['I0', 39, 4000], ['I1', 10, 150], ['I2', 110, 5], ['I3', 40, 5], ['I4', 99, 150], ['I5', 54, 4000], ['I6', 54, 1000]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 500, 'writeoffs': ['I6']}, {'buckets': [5, 150, 4005, 4150, 0], 'required': 2269, 'adjustment': 2769, 'net_ar': 6041}], ['control 1', {'as_of': 100, 'invoices': [['I0', -100, 5], ['I1', 39, 333], ['I2', 9, 2500], ['I3', -100, 4000], ['I4', 69, 150], ['I5', 70, 2500], ['I6', 55, 4000]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 0, 'writeoffs': ['I5', 'I6']}, {'buckets': [0, 0, 150, 333, 6505], 'required': 5035, 'adjustment': 11535, 'net_ar': 1953}], ['control 2', {'as_of': 100, 'invoices': [['I0', 55, 2500], ['I1', 99, 4000], ['I2', 99, 150], ['I3', 55, 5]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 200, 'writeoffs': ['I0']}, {'buckets': [0, 4150, 5, 0, 0], 'required': 209, 'adjustment': 2509, 'net_ar': 3946}], ['control 3', {'as_of': 100, 'invoices': [['I0', 40, 2500], ['I1', 99, 4000], ['I2', 9, 1000]], 'rates': [[0, 200], [45, 1250], [None, 5000]], 'allowance': 0, 'writeoffs': []}, {'buckets': [0, 4000, 3500], 'required': 2250, 'adjustment': 2250, 'net_ar': 5250}], ['control 4', {'as_of': 100, 'invoices': [['I0', 54, 333], ['I1', 9, 4000], ['I2', 54, 2500], ['I3', 55, 1000], ['I4', 10, 1000], ['I5', 71, 1000]], 'rates': [[0, 200], [45, 1250], [None, 5000]], 'allowance': -150, 'writeoffs': ['I0', 'I1', 'I3']}, {'buckets': [0, 1000, 3500], 'required': 1875, 'adjustment': 7358, 'net_ar': 2625}], ['control 5', {'as_of': 100, 'invoices': [['I0', 39, 4000], ['I1', 70, 333], ['I2', 9, 1000]], 'rates': [[0, 200], [45, 1250], [None, 5000]], 'allowance': 500, 'writeoffs': ['I2']}, {'buckets': [0, 333, 4000], 'required': 2042, 'adjustment': 2542, 'net_ar': 2291}]], [['regression: bucket upper bound', {'as_of': 100, 'invoices': [['I0', 99, 5], ['I1', 39, 5], ['I2', 10, 150], ['I3', -100, 333], ['I4', 39, 1000], ['I5', 39, 4000], ['I6', 100, 2500]], 'rates': [[0, 200], [45, 1250], [None, 5000]], 'allowance': -150, 'writeoffs': ['I2', 'I3']}, {'buckets': [2500, 5, 5005], 'required': 2554, 'adjustment': 3187, 'net_ar': 4956}], ['regression: bucket upper bound, partial-repair probe', {'as_of': 100, 'invoices': [['I0', 54, 2500], ['I1', 55, 5], ['I2', 10, 1000], ['I3', 71, 333], ['I4', 71, 1000], ['I5', 100, 5]], 'rates': [[0, 200], [45, 1250], [None, 5000]], 'allowance': -150, 'writeoffs': ['I2', 'I5']}, {'buckets': [0, 1338, 2500], 'required': 1417, 'adjustment': 2572, 'net_ar': 2421}], ['control 1', {'as_of': 100, 'invoices': [['I0', 99, 2500], ['I1', 69, 1000], ['I2', 55, 333], ['I3', 39, 1000], ['I4', 39, 333], ['I5', 40, 4000]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 200, 'writeoffs': ['I1', 'I4', 'I5']}, {'buckets': [0, 2500, 333, 1000, 0], 'required': 575, 'adjustment': 5708, 'net_ar': 3258}], ['control 2', {'as_of': 100, 'invoices': [['I0', 70, 5], ['I1', 69, 5], ['I2', 71, 333], ['I3', -100, 5], ['I4', 54, 333], ['I5', 100, 150], ['I6', 71, 150]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 200, 'writeoffs': ['I0', 'I5']}, {'buckets': [0, 483, 338, 0, 5], 'required': 79, 'adjustment': 34, 'net_ar': 747}], ['control 3', {'as_of': 100, 'invoices': [['I0', -100, 150], ['I1', 40, 1000], ['I2', 40, 5], ['I3', 39, 1000], ['I4', 9, 150], ['I5', 10, 1000], ['I6', 10, 150]], 'rates': [[0, 200], [45, 1250], [None, 5000]], 'allowance': 200, 'writeoffs': ['I2', 'I5']}, {'buckets': [0, 0, 2450], 'required': 1225, 'adjustment': 2030, 'net_ar': 1225}], ['control 4', {'as_of': 100, 'invoices': [['I0', 54, 333], ['I1', 40, 2500], ['I2', 9, 150]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': -150, 'writeoffs': ['I1']}, {'buckets': [0, 0, 333, 0, 150], 'required': 163, 'adjustment': 2813, 'net_ar': 320}], ['control 5', {'as_of': 100, 'invoices': [['I0', 69, 2500], ['I1', 9, 5], ['I2', 71, 333]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 200, 'writeoffs': ['I2']}, {'buckets': [0, 0, 2500, 0, 5], 'required': 379, 'adjustment': 512, 'net_ar': 2126}]], [['regression: bucket upper bound', {'as_of': 100, 'invoices': [['I0', 54, 150], ['I1', 71, 4000], ['I2', 70, 2500], ['I3', 110, 150], ['I4', 99, 5]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 500, 'writeoffs': ['I3']}, {'buckets': [0, 6505, 150, 0, 0], 'required': 348, 'adjustment': -2, 'net_ar': 6307}], ['control 1', {'as_of': 100, 'invoices': [['I0', 39, 2500], ['I1', 69, 150], ['I2', 55, 333]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 200, 'writeoffs': ['I1']}, {'buckets': [0, 0, 333, 2500, 0], 'required': 1050, 'adjustment': 1000, 'net_ar': 1783}], ['control 2', {'as_of': 100, 'invoices': [['I0', -100, 333], ['I1', 99, 5], ['I2', 10, 150], ['I3', 9, 2500], ['I4', -100, 2500], ['I5', 55, 333], ['I6', 71, 2500]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': -150, 'writeoffs': ['I2']}, {'buckets': [0, 2505, 333, 0, 5333], 'required': 4175, 'adjustment': 4475, 'net_ar': 3996}], ['control 3', {'as_of': 100, 'invoices': [['I0', 71, 2500], ['I1', 100, 150], ['I2', 9, 5]], 'rates': [[0, 200], [45, 1250], [None, 5000]], 'allowance': 0, 'writeoffs': ['I1']}, {'buckets': [0, 2500, 5], 'required': 316, 'adjustment': 466, 'net_ar': 2189}], ['control 4', {'as_of': 100, 'invoices': [['I0', 71, 4000], ['I1', -100, 4000], ['I2', 39, 5], ['I3', 99, 2500]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 0, 'writeoffs': ['I0', 'I3']}, {'buckets': [0, 0, 0, 5, 4000], 'required': 3002, 'adjustment': 9502, 'net_ar': 1003}], ['control 5', {'as_of': 100, 'invoices': [['I0', 10, 333], ['I1', -100, 150], ['I2', 99, 1000], ['I3', 71, 2500], ['I4', 39, 2500], ['I5', 54, 333]], 'rates': [[0, 200], [45, 1250], [None, 5000]], 'allowance': 500, 'writeoffs': []}, {'buckets': [0, 3500, 3316], 'required': 2096, 'adjustment': 1596, 'net_ar': 4720}], ['control 6', {'as_of': 100, 'invoices': [['I0', 99, 333], ['I1', 55, 2500], ['I2', 100, 5]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': -150, 'writeoffs': ['I0', 'I2']}, {'buckets': [0, 0, 2500, 0, 0], 'required': 375, 'adjustment': 863, 'net_ar': 2125}]], [['regression: bucket upper bound', {'as_of': 100, 'invoices': [['I0', 110, 150], ['I1', 10, 1000], ['I2', 70, 150], ['I3', 99, 1000], ['I4', 100, 2500], ['I5', 55, 333], ['I6', 54, 150]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 0, 'writeoffs': ['I5', 'I6']}, {'buckets': [2650, 1150, 0, 1000, 0], 'required': 485, 'adjustment': 968, 'net_ar': 4315}], ['control 1', {'as_of': 100, 'invoices': [['I0', 70, 1000], ['I1', 10, 5], ['I2', 39, 150], ['I3', 54, 5], ['I4', 70, 2500], ['I5', 40, 150], ['I6', 39, 5]], 'rates': [[0, 200], [45, 1250], [None, 5000]], 'allowance': 200, 'writeoffs': ['I2', 'I4']}, {'buckets': [0, 1000, 165], 'required': 208, 'adjustment': 2658, 'net_ar': 957}], ['control 2', {'as_of': 100, 'invoices': [['I0', 69, 150], ['I1', 71, 150], ['I2', 70, 150]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 500, 'writeoffs': ['I2']}, {'buckets': [0, 150, 150, 0, 0], 'required': 31, 'adjustment': -319, 'net_ar': 269}], ['control 3', {'as_of': 100, 'invoices': [['I0', 71, 333], ['I1', 39, 150], ['I2', 71, 4000]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 0, 'writeoffs': []}, {'buckets': [0, 4333, 0, 150, 0], 'required': 277, 'adjustment': 277, 'net_ar': 4206}], ['control 4', {'as_of': 100, 'invoices': [['I0', 9, 5], ['I1', 71, 150], ['I2', 70, 1000], ['I3', 54, 1000]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 0, 'writeoffs': ['I2']}, {'buckets': [0, 150, 1000, 0, 5], 'required': 162, 'adjustment': 1162, 'net_ar': 993}], ['control 5', {'as_of': 100, 'invoices': [['I0', 69, 2500], ['I1', 69, 150], ['I2', 55, 5], ['I3', 71, 1000], ['I4', 55, 4000], ['I5', -100, 2500], ['I6', 69, 4000]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 500, 'writeoffs': []}, {'buckets': [0, 1000, 10655, 0, 2500], 'required': 3523, 'adjustment': 3023, 'net_ar': 10632}], ['control 6', {'as_of': 100, 'invoices': [['I0', 10, 4000], ['I1', 9, 1000], ['I2', -100, 2500], ['I3', -100, 150], ['I4', 70, 4000]], 'rates': [[0, 200], [45, 1250], [None, 5000]], 'allowance': 0, 'writeoffs': ['I0']}, {'buckets': [0, 4000, 3650], 'required': 2325, 'adjustment': 6325, 'net_ar': 5325}]], [['regression: bucket upper bound', {'as_of': 100, 'invoices': [['I0', 70, 4000], ['I1', 70, 2500], ['I2', 100, 4000], ['I3', 71, 5]], 'rates': [[0, 200], [45, 1250], [None, 5000]], 'allowance': 0, 'writeoffs': ['I1']}, {'buckets': [4000, 4005, 0], 'required': 581, 'adjustment': 3081, 'net_ar': 7424}], ['regression: bucket upper bound, partial-repair probe', {'as_of': 100, 'invoices': [['I0', 40, 4000], ['I1', 39, 1000], ['I2', -100, 5], ['I3', 99, 5], ['I4', -100, 333], ['I5', 10, 4000]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 500, 'writeoffs': ['I3']}, {'buckets': [0, 0, 4000, 5000, 338], 'required': 2854, 'adjustment': 2359, 'net_ar': 6484}], ['control 1', {'as_of': 100, 'invoices': [['I0', 9, 150], ['I1', 9, 1000], ['I2', 54, 1000], ['I3', 99, 2500], ['I4', 69, 333], ['I5', 71, 5]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': -150, 'writeoffs': []}, {'buckets': [0, 2505, 1333, 0, 1150], 'required': 1188, 'adjustment': 1338, 'net_ar': 3800}], ['control 2', {'as_of': 100, 'invoices': [['I0', 39, 5], ['I1', 99, 4000], ['I2', 55, 4000]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 0, 'writeoffs': ['I0', 'I1']}, {'buckets': [0, 0, 4000, 0, 0], 'required': 600, 'adjustment': 4605, 'net_ar': 3400}], ['control 3', {'as_of': 100, 'invoices': [['I0', 54, 5], ['I1', 40, 5], ['I2', 99, 333], ['I3', 71, 150], ['I4', 54, 4000]], 'rates': [[0, 200], [45, 1250], [None, 5000]], 'allowance': 0, 'writeoffs': []}, {'buckets': [0, 483, 4010], 'required': 2065, 'adjustment': 2065, 'net_ar': 2428}], ['control 4', {'as_of': 100, 'invoices': [['I0', 55, 5], ['I1', 100, 150], ['I2', 99, 150]], 'rates': [[0, 100], [30, 500], [60, 1500], [90, 4000], [None, 7500]], 'allowance': 0, 'writeoffs': ['I0', 'I1', 'I2']}, {'buckets': [0, 0, 0, 0, 0], 'required': 0, 'adjustment': 305, 'net_ar': 0}], ['control 5', {'as_of': 100, 'invoices': [['I0', 39, 2500], ['I1', 99, 333], ['I2', 69, 333]], 'rates': [[0, 200], [45, 1250], [None, 5000]], 'allowance': 0, 'writeoffs': ['I0']}, {'buckets': [0, 666, 0], 'required': 83, 'adjustment': 2583, 'net_ar': 583}]]]
for label, args, expected in fixtures[N-1]:
    try:
        actual = solve(args)
    except Exception as exc:
        actual = 'raised ' + type(exc).__name__
    check(label, actual, expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
An invoice exactly 30 days past due is aged into the 31-60 bucket.

x = {'as_of': day, 'invoices': [[id, due_day, open cents]], 'rates': [[max_days_past_due or None, basis points]] ascending, 'allowance': existing credit balance (negative = debit balance), 'writeoffs': ids}. Written-off invoices leave receivables and reduce the allowance by their amount. Days past due = max(0, as_of - due); an invoice goes in the first bucket whose limit is None or >= days. Required allowance = sum over buckets of bucket total * bp / 10000 rounded half-up per bucket. Return {'buckets', 'required', 'adjustment': required - allowance after write-offs, 'net_ar'}.

split: open-access


prompt:
Invoices due next month are reserved as if already delinquent.

x = {'as_of': day, 'invoices': [[id, due_day, open cents]], 'rates': [[max_days_past_due or None, basis points]] ascending, 'allowance': existing credit balance (negative = debit balance), 'writeoffs': ids}. Written-off invoices leave receivables and reduce the allowance by their amount. Days past due = max(0, as_of - due); an invoice goes in the first bucket whose limit is None or >= days. Required allowance = sum over buckets of bucket total * bp / 10000 rounded half-up per bucket. Return {'buckets', 'required', 'adjustment': required - allowance after write-offs, 'net_ar'}.

split: open-access