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

N = 1
observations = []
def solve(x):
    status = {}
    amounts = {}
    errors = []
    for i, cmd in enumerate(x):
        if cmd[0] == 'post':
            _, eid, amt = cmd
            if eid in status:
                errors.append([i, 'duplicate'])
                continue
            status[eid] = 'posted'
            amounts[eid] = amt
        elif cmd[0] == 'void':
            _, target, new = cmd
            if target not in status:
                errors.append([i, 'unknown'])
            elif status[target] != 'posted':
                errors.append([i, 'not_voidable'])
            elif new in status:
                status[target] = 'voided'
                errors.append([i, 'duplicate'])
            else:
                status[target] = 'voided'
                status[new] = 'reversal'
                amounts[new] = -amounts[target]
        else:
            errors.append([i, 'bad_command'])
    return {'status': status, 'balance': sum(amounts.values()), 'errors': errors}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: failed void side effect', [['post', 'R1', -40], ['post', 'R1', 100], ['post', 'D', 999], ['edit', 'A', 5], ['void', 'R1', 'D'], ['void', 'R1', 'R2'], ['post', 'D', 999], ['void', 'R1', 'R1']], {'status': {'R1': 'voided', 'D': 'posted', 'R2': 'reversal'}, 'balance': 999, 'errors': [[1, 'duplicate'], [3, 'bad_command'], [4, 'duplicate'], [6, 'duplicate'], [7, 'not_voidable']]}], ['control 1', [['edit', 'A', 5], ['post', 'C', 999], ['void', 'C', 'R2'], ['void', 'R3', 'D']], {'status': {'C': 'voided', 'R2': 'reversal'}, 'balance': 0, 'errors': [[0, 'bad_command'], [3, 'unknown']]}], ['control 2', [['post', 'C', 250], ['edit', 'A', 5], ['edit', 'A', 5], ['void', 'R1', 'D']], {'status': {'C': 'posted'}, 'balance': 250, 'errors': [[1, 'bad_command'], [2, 'bad_command'], [3, 'unknown']]}], ['control 3', [['void', 'R2', 'D'], ['post', 'D', 999], ['post', 'D', 999], ['post', 'R1', 100], ['void', 'A', 'D']], {'status': {'D': 'posted', 'R1': 'posted'}, 'balance': 1099, 'errors': [[0, 'unknown'], [2, 'duplicate'], [4, 'unknown']]}], ['control 4', [['void', 'R3', 'R2'], ['void', 'R2', 'D'], ['void', 'R1', 'R2'], ['post', 'D', 250], ['void', 'R2', 'R1'], ['void', 'R1', 'R2'], ['void', 'D', 'R3'], ['post', 'R1', 100]], {'status': {'D': 'voided', 'R3': 'reversal', 'R1': 'posted'}, 'balance': 100, 'errors': [[0, 'unknown'], [1, 'unknown'], [2, 'unknown'], [4, 'unknown'], [5, 'unknown']]}], ['control 5', [['void', 'C', 'R1'], ['void', 'R1', 'R2'], ['edit', 'A', 5], ['void', 'C', 'R1'], ['void', 'R3', 'R1'], ['post', 'D', 999]], {'status': {'D': 'posted'}, 'balance': 999, 'errors': [[0, 'unknown'], [1, 'unknown'], [2, 'bad_command'], [3, 'unknown'], [4, 'unknown']]}], ['control 6', [['post', 'A', 999], ['post', 'D', -40], ['void', 'R1', 'R1'], ['post', 'B', 999], ['void', 'B', 'R3'], ['post', 'R1', 999], ['post', 'B', 250]], {'status': {'A': 'posted', 'D': 'posted', 'B': 'voided', 'R3': 'reversal', 'R1': 'posted'}, 'balance': 1958, 'errors': [[2, 'unknown'], [6, 'duplicate']]}]], [['regression: failed void side effect', [['post', 'B', 250], ['void', 'D', 'R3'], ['post', 'D', -40], ['post', 'A', -40], ['void', 'R3', 'R1'], ['void', 'R2', 'R3'], ['post', 'R1', -40], ['void', 'B', 'R1']], {'status': {'B': 'posted', 'D': 'posted', 'A': 'posted', 'R1': 'posted'}, 'balance': 130, 'errors': [[1, 'unknown'], [4, 'unknown'], [5, 'unknown'], [7, 'duplicate']]}], ['control 1', [['post', 'B', 250], ['post', 'C', 250], ['edit', 'A', 5], ['post', 'B', 250], ['post', 'B', 100]], {'status': {'B': 'posted', 'C': 'posted'}, 'balance': 500, 'errors': [[2, 'bad_command'], [3, 'duplicate'], [4, 'duplicate']]}], ['control 2', [['post', 'R1', -40], ['post', 'B', 250], ['post', 'C', 250], ['void', 'R2', 'R3']], {'status': {'R1': 'posted', 'B': 'posted', 'C': 'posted'}, 'balance': 460, 'errors': [[3, 'unknown']]}], ['control 3', [['post', 'A', 999], ['void', 'R1', 'R3'], ['void', 'R2', 'R2'], ['post', 'R1', 999]], {'status': {'A': 'posted', 'R1': 'posted'}, 'balance': 1998, 'errors': [[1, 'unknown'], [2, 'unknown']]}], ['control 4', [['void', 'C', 'D'], ['void', 'D', 'R1'], ['void', 'R3', 'D'], ['post', 'A', -40], ['post', 'D', 999], ['post', 'C', -40], ['void', 'R1', 'R3']], {'status': {'A': 'posted', 'D': 'posted', 'C': 'posted'}, 'balance': 919, 'errors': [[0, 'unknown'], [1, 'unknown'], [2, 'unknown'], [6, 'unknown']]}], ['control 5', [['void', 'R1', 'R3'], ['void', 'C', 'D'], ['void', 'B', 'D'], ['post', 'R1', 250], ['void', 'R2', 'D'], ['post', 'D', -40], ['void', 'C', 'D']], {'status': {'R1': 'posted', 'D': 'posted'}, 'balance': 210, 'errors': [[0, 'unknown'], [1, 'unknown'], [2, 'unknown'], [4, 'unknown'], [6, 'unknown']]}], ['control 6', [['post', 'A', 250], ['post', 'A', 100], ['post', 'D', 999]], {'status': {'A': 'posted', 'D': 'posted'}, 'balance': 1249, 'errors': [[1, 'duplicate']]}]], [['regression: failed void side effect', [['void', 'R3', 'R1'], ['post', 'D', -40], ['void', 'R3', 'R1'], ['post', 'R1', 100], ['post', 'A', 250], ['void', 'R1', 'R3'], ['void', 'A', 'D'], ['void', 'R1', 'R1']], {'status': {'D': 'posted', 'R1': 'voided', 'A': 'posted', 'R3': 'reversal'}, 'balance': 210, 'errors': [[0, 'unknown'], [2, 'unknown'], [6, 'duplicate'], [7, 'not_voidable']]}], ['control 1', [['void', 'R1', 'R3'], ['void', 'A', 'R3'], ['void', 'R3', 'R1']], {'status': {}, 'balance': 0, 'errors': [[0, 'unknown'], [1, 'unknown'], [2, 'unknown']]}], ['control 2', [['void', 'C', 'R3'], ['void', 'R1', 'R3'], ['void', 'R2', 'R1'], ['void', 'R1', 'R1'], ['void', 'C', 'D'], ['void', 'A', 'R1'], ['post', 'D', 999]], {'status': {'D': 'posted'}, 'balance': 999, 'errors': [[0, 'unknown'], [1, 'unknown'], [2, 'unknown'], [3, 'unknown'], [4, 'unknown'], [5, 'unknown']]}], ['control 3', [['post', 'D', -40], ['void', 'R3', 'R1'], ['post', 'B', 100], ['post', 'R1', 250], ['void', 'C', 'D'], ['post', 'A', 999], ['void', 'R2', 'R2']], {'status': {'D': 'posted', 'B': 'posted', 'R1': 'posted', 'A': 'posted'}, 'balance': 1309, 'errors': [[1, 'unknown'], [4, 'unknown'], [6, 'unknown']]}], ['control 4', [['edit', 'A', 5], ['post', 'R1', -40], ['post', 'C', 100], ['post', 'C', 100], ['post', 'R1', 100], ['void', 'R2', 'D'], ['post', 'B', -40]], {'status': {'R1': 'posted', 'C': 'posted', 'B': 'posted'}, 'balance': 20, 'errors': [[0, 'bad_command'], [3, 'duplicate'], [4, 'duplicate'], [5, 'unknown']]}], ['control 5', [['post', 'C', 250], ['post', 'B', 999], ['void', 'C', 'D'], ['post', 'A', -40], ['void', 'R3', 'R1'], ['void', 'R2', 'R3'], ['void', 'R2', 'R3'], ['void', 'B', 'R1']], {'status': {'C': 'voided', 'B': 'voided', 'D': 'reversal', 'A': 'posted', 'R1': 'reversal'}, 'balance': -40, 'errors': [[4, 'unknown'], [5, 'unknown'], [6, 'unknown']]}], ['control 6', [['post', 'B', 999], ['void', 'R3', 'R1'], ['void', 'D', 'R3'], ['post', 'C', 100], ['post', 'D', 999]], {'status': {'B': 'posted', 'C': 'posted', 'D': 'posted'}, 'balance': 2098, 'errors': [[1, 'unknown'], [2, 'unknown']]}]], [['regression: failed void side effect', [['post', 'C', 999], ['void', 'R2', 'R1'], ['post', 'D', 999], ['post', 'A', 999], ['void', 'D', 'D'], ['post', 'B', -40], ['post', 'B', 999]], {'status': {'C': 'posted', 'D': 'posted', 'A': 'posted', 'B': 'posted'}, 'balance': 2957, 'errors': [[1, 'unknown'], [4, 'duplicate'], [6, 'duplicate']]}], ['control 1', [['void', 'A', 'R1'], ['void', 'A', 'R1'], ['void', 'B', 'R3'], ['post', 'C', 100], ['post', 'B', -40], ['edit', 'A', 5], ['void', 'R2', 'D']], {'status': {'C': 'posted', 'B': 'posted'}, 'balance': 60, 'errors': [[0, 'unknown'], [1, 'unknown'], [2, 'unknown'], [5, 'bad_command'], [6, 'unknown']]}], ['control 2', [['void', 'D', 'R1'], ['post', 'D', -40], ['post', 'A', 100], ['void', 'A', 'R1'], ['void', 'A', 'R3']], {'status': {'D': 'posted', 'A': 'voided', 'R1': 'reversal'}, 'balance': -40, 'errors': [[0, 'unknown'], [4, 'not_voidable']]}], ['control 3', [['void', 'D', 'R2'], ['void', 'R3', 'R3'], ['post', 'B', 250], ['void', 'D', 'D'], ['post', 'C', 999], ['post', 'B', -40]], {'status': {'B': 'posted', 'C': 'posted'}, 'balance': 1249, 'errors': [[0, 'unknown'], [1, 'unknown'], [3, 'unknown'], [5, 'duplicate']]}], ['control 4', [['post', 'R1', -40], ['void', 'D', 'R1'], ['post', 'A', 250], ['void', 'R1', 'D']], {'status': {'R1': 'voided', 'A': 'posted', 'D': 'reversal'}, 'balance': 250, 'errors': [[1, 'unknown']]}], ['control 5', [['edit', 'A', 5], ['edit', 'A', 5], ['post', 'D', 100], ['post', 'B', 999]], {'status': {'D': 'posted', 'B': 'posted'}, 'balance': 1099, 'errors': [[0, 'bad_command'], [1, 'bad_command']]}], ['control 6', [['post', 'R1', 250], ['void', 'R1', 'D'], ['void', 'R1', 'R3'], ['void', 'R1', 'R3'], ['void', 'D', 'D'], ['post', 'B', -40], ['void', 'B', 'R2'], ['post', 'C', -40]], {'status': {'R1': 'voided', 'D': 'reversal', 'B': 'voided', 'R2': 'reversal', 'C': 'posted'}, 'balance': -40, 'errors': [[2, 'not_voidable'], [3, 'not_voidable'], [4, 'not_voidable']]}]], [['regression: failed void side effect', [['post', 'D', 100], ['void', 'B', 'R3'], ['post', 'A', 999], ['post', 'A', -40], ['void', 'D', 'D'], ['void', 'R1', 'R3']], {'status': {'D': 'posted', 'A': 'posted'}, 'balance': 1099, 'errors': [[1, 'unknown'], [3, 'duplicate'], [4, 'duplicate'], [5, 'unknown']]}], ['control 1', [['void', 'R2', 'R1'], ['void', 'B', 'D'], ['post', 'C', 250]], {'status': {'C': 'posted'}, 'balance': 250, 'errors': [[0, 'unknown'], [1, 'unknown']]}], ['control 2', [['void', 'A', 'R1'], ['post', 'A', -40], ['post', 'A', -40], ['post', 'A', 999], ['void', 'R1', 'R2']], {'status': {'A': 'posted'}, 'balance': -40, 'errors': [[0, 'unknown'], [2, 'duplicate'], [3, 'duplicate'], [4, 'unknown']]}], ['control 3', [['post', 'B', 250], ['post', 'D', 100], ['post', 'A', 999], ['post', 'D', -40]], {'status': {'B': 'posted', 'D': 'posted', 'A': 'posted'}, 'balance': 1349, 'errors': [[3, 'duplicate']]}], ['control 4', [['void', 'C', 'R2'], ['void', 'B', 'R3'], ['void', 'R1', 'R2'], ['void', 'D', 'D'], ['void', 'R3', 'R2'], ['post', 'C', 250], ['post', 'A', 999], ['post', 'R1', 100]], {'status': {'C': 'posted', 'A': 'posted', 'R1': 'posted'}, 'balance': 1349, 'errors': [[0, 'unknown'], [1, 'unknown'], [2, 'unknown'], [3, 'unknown'], [4, 'unknown']]}], ['control 5', [['void', 'R1', 'R3'], ['post', 'C', 999], ['post', 'R1', -40], ['post', 'D', 999], ['post', 'A', 250], ['post', 'B', 250], ['void', 'R2', 'D']], {'status': {'C': 'posted', 'R1': 'posted', 'D': 'posted', 'A': 'posted', 'B': 'posted'}, 'balance': 2458, 'errors': [[0, 'unknown'], [6, 'unknown']]}], ['control 6', [['void', 'C', 'R1'], ['void', 'R1', 'R1'], ['void', 'R1', 'D'], ['post', 'C', 999], ['void', 'R2', 'D'], ['void', 'R2', 'D'], ['void', 'C', 'R2']], {'status': {'C': 'voided', 'R2': 'reversal'}, 'balance': 0, 'errors': [[0, 'unknown'], [1, 'unknown'], [2, 'unknown'], [4, 'unknown'], [5, 'unknown']]}]]]
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):
    status = {}
    amounts = {}
    errors = []
    for i, cmd in enumerate(x):
        if cmd[0] == 'post':
            _, eid, amt = cmd
            if eid in status:
                errors.append([i, 'duplicate'])
                continue
            status[eid] = 'posted'
            amounts[eid] = amt
        elif cmd[0] == 'void':
            _, target, new = cmd
            if target not in status:
                errors.append([i, 'unknown'])
            elif status[target] != 'posted':
                errors.append([i, 'not_voidable'])
            elif new in status:
                status[target] = 'voided'
                amounts[target] = 0
                errors.append([i, 'duplicate'])
            else:
                status[target] = 'voided'
                status[new] = 'reversal'
                amounts[new] = -amounts[target]
        else:
            errors.append([i, 'bad_command'])
    return {'status': status, 'balance': sum(amounts.values()), 'errors': errors}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: failed void side effect', [['post', 'R1', -40], ['post', 'R1', 100], ['post', 'D', 999], ['edit', 'A', 5], ['void', 'R1', 'D'], ['void', 'R1', 'R2'], ['post', 'D', 999], ['void', 'R1', 'R1']], {'status': {'R1': 'voided', 'D': 'posted', 'R2': 'reversal'}, 'balance': 999, 'errors': [[1, 'duplicate'], [3, 'bad_command'], [4, 'duplicate'], [6, 'duplicate'], [7, 'not_voidable']]}], ['control 1', [['edit', 'A', 5], ['post', 'C', 999], ['void', 'C', 'R2'], ['void', 'R3', 'D']], {'status': {'C': 'voided', 'R2': 'reversal'}, 'balance': 0, 'errors': [[0, 'bad_command'], [3, 'unknown']]}], ['control 2', [['post', 'C', 250], ['edit', 'A', 5], ['edit', 'A', 5], ['void', 'R1', 'D']], {'status': {'C': 'posted'}, 'balance': 250, 'errors': [[1, 'bad_command'], [2, 'bad_command'], [3, 'unknown']]}], ['control 3', [['void', 'R2', 'D'], ['post', 'D', 999], ['post', 'D', 999], ['post', 'R1', 100], ['void', 'A', 'D']], {'status': {'D': 'posted', 'R1': 'posted'}, 'balance': 1099, 'errors': [[0, 'unknown'], [2, 'duplicate'], [4, 'unknown']]}], ['control 4', [['void', 'R3', 'R2'], ['void', 'R2', 'D'], ['void', 'R1', 'R2'], ['post', 'D', 250], ['void', 'R2', 'R1'], ['void', 'R1', 'R2'], ['void', 'D', 'R3'], ['post', 'R1', 100]], {'status': {'D': 'voided', 'R3': 'reversal', 'R1': 'posted'}, 'balance': 100, 'errors': [[0, 'unknown'], [1, 'unknown'], [2, 'unknown'], [4, 'unknown'], [5, 'unknown']]}], ['control 5', [['void', 'C', 'R1'], ['void', 'R1', 'R2'], ['edit', 'A', 5], ['void', 'C', 'R1'], ['void', 'R3', 'R1'], ['post', 'D', 999]], {'status': {'D': 'posted'}, 'balance': 999, 'errors': [[0, 'unknown'], [1, 'unknown'], [2, 'bad_command'], [3, 'unknown'], [4, 'unknown']]}], ['control 6', [['post', 'A', 999], ['post', 'D', -40], ['void', 'R1', 'R1'], ['post', 'B', 999], ['void', 'B', 'R3'], ['post', 'R1', 999], ['post', 'B', 250]], {'status': {'A': 'posted', 'D': 'posted', 'B': 'voided', 'R3': 'reversal', 'R1': 'posted'}, 'balance': 1958, 'errors': [[2, 'unknown'], [6, 'duplicate']]}]], [['regression: failed void side effect', [['post', 'B', 250], ['void', 'D', 'R3'], ['post', 'D', -40], ['post', 'A', -40], ['void', 'R3', 'R1'], ['void', 'R2', 'R3'], ['post', 'R1', -40], ['void', 'B', 'R1']], {'status': {'B': 'posted', 'D': 'posted', 'A': 'posted', 'R1': 'posted'}, 'balance': 130, 'errors': [[1, 'unknown'], [4, 'unknown'], [5, 'unknown'], [7, 'duplicate']]}], ['control 1', [['post', 'B', 250], ['post', 'C', 250], ['edit', 'A', 5], ['post', 'B', 250], ['post', 'B', 100]], {'status': {'B': 'posted', 'C': 'posted'}, 'balance': 500, 'errors': [[2, 'bad_command'], [3, 'duplicate'], [4, 'duplicate']]}], ['control 2', [['post', 'R1', -40], ['post', 'B', 250], ['post', 'C', 250], ['void', 'R2', 'R3']], {'status': {'R1': 'posted', 'B': 'posted', 'C': 'posted'}, 'balance': 460, 'errors': [[3, 'unknown']]}], ['control 3', [['post', 'A', 999], ['void', 'R1', 'R3'], ['void', 'R2', 'R2'], ['post', 'R1', 999]], {'status': {'A': 'posted', 'R1': 'posted'}, 'balance': 1998, 'errors': [[1, 'unknown'], [2, 'unknown']]}], ['control 4', [['void', 'C', 'D'], ['void', 'D', 'R1'], ['void', 'R3', 'D'], ['post', 'A', -40], ['post', 'D', 999], ['post', 'C', -40], ['void', 'R1', 'R3']], {'status': {'A': 'posted', 'D': 'posted', 'C': 'posted'}, 'balance': 919, 'errors': [[0, 'unknown'], [1, 'unknown'], [2, 'unknown'], [6, 'unknown']]}], ['control 5', [['void', 'R1', 'R3'], ['void', 'C', 'D'], ['void', 'B', 'D'], ['post', 'R1', 250], ['void', 'R2', 'D'], ['post', 'D', -40], ['void', 'C', 'D']], {'status': {'R1': 'posted', 'D': 'posted'}, 'balance': 210, 'errors': [[0, 'unknown'], [1, 'unknown'], [2, 'unknown'], [4, 'unknown'], [6, 'unknown']]}], ['control 6', [['post', 'A', 250], ['post', 'A', 100], ['post', 'D', 999]], {'status': {'A': 'posted', 'D': 'posted'}, 'balance': 1249, 'errors': [[1, 'duplicate']]}]], [['regression: failed void side effect', [['void', 'R3', 'R1'], ['post', 'D', -40], ['void', 'R3', 'R1'], ['post', 'R1', 100], ['post', 'A', 250], ['void', 'R1', 'R3'], ['void', 'A', 'D'], ['void', 'R1', 'R1']], {'status': {'D': 'posted', 'R1': 'voided', 'A': 'posted', 'R3': 'reversal'}, 'balance': 210, 'errors': [[0, 'unknown'], [2, 'unknown'], [6, 'duplicate'], [7, 'not_voidable']]}], ['control 1', [['void', 'R1', 'R3'], ['void', 'A', 'R3'], ['void', 'R3', 'R1']], {'status': {}, 'balance': 0, 'errors': [[0, 'unknown'], [1, 'unknown'], [2, 'unknown']]}], ['control 2', [['void', 'C', 'R3'], ['void', 'R1', 'R3'], ['void', 'R2', 'R1'], ['void', 'R1', 'R1'], ['void', 'C', 'D'], ['void', 'A', 'R1'], ['post', 'D', 999]], {'status': {'D': 'posted'}, 'balance': 999, 'errors': [[0, 'unknown'], [1, 'unknown'], [2, 'unknown'], [3, 'unknown'], [4, 'unknown'], [5, 'unknown']]}], ['control 3', [['post', 'D', -40], ['void', 'R3', 'R1'], ['post', 'B', 100], ['post', 'R1', 250], ['void', 'C', 'D'], ['post', 'A', 999], ['void', 'R2', 'R2']], {'status': {'D': 'posted', 'B': 'posted', 'R1': 'posted', 'A': 'posted'}, 'balance': 1309, 'errors': [[1, 'unknown'], [4, 'unknown'], [6, 'unknown']]}], ['control 4', [['edit', 'A', 5], ['post', 'R1', -40], ['post', 'C', 100], ['post', 'C', 100], ['post', 'R1', 100], ['void', 'R2', 'D'], ['post', 'B', -40]], {'status': {'R1': 'posted', 'C': 'posted', 'B': 'posted'}, 'balance': 20, 'errors': [[0, 'bad_command'], [3, 'duplicate'], [4, 'duplicate'], [5, 'unknown']]}], ['control 5', [['post', 'C', 250], ['post', 'B', 999], ['void', 'C', 'D'], ['post', 'A', -40], ['void', 'R3', 'R1'], ['void', 'R2', 'R3'], ['void', 'R2', 'R3'], ['void', 'B', 'R1']], {'status': {'C': 'voided', 'B': 'voided', 'D': 'reversal', 'A': 'posted', 'R1': 'reversal'}, 'balance': -40, 'errors': [[4, 'unknown'], [5, 'unknown'], [6, 'unknown']]}], ['control 6', [['post', 'B', 999], ['void', 'R3', 'R1'], ['void', 'D', 'R3'], ['post', 'C', 100], ['post', 'D', 999]], {'status': {'B': 'posted', 'C': 'posted', 'D': 'posted'}, 'balance': 2098, 'errors': [[1, 'unknown'], [2, 'unknown']]}]], [['regression: failed void side effect', [['post', 'C', 999], ['void', 'R2', 'R1'], ['post', 'D', 999], ['post', 'A', 999], ['void', 'D', 'D'], ['post', 'B', -40], ['post', 'B', 999]], {'status': {'C': 'posted', 'D': 'posted', 'A': 'posted', 'B': 'posted'}, 'balance': 2957, 'errors': [[1, 'unknown'], [4, 'duplicate'], [6, 'duplicate']]}], ['control 1', [['void', 'A', 'R1'], ['void', 'A', 'R1'], ['void', 'B', 'R3'], ['post', 'C', 100], ['post', 'B', -40], ['edit', 'A', 5], ['void', 'R2', 'D']], {'status': {'C': 'posted', 'B': 'posted'}, 'balance': 60, 'errors': [[0, 'unknown'], [1, 'unknown'], [2, 'unknown'], [5, 'bad_command'], [6, 'unknown']]}], ['control 2', [['void', 'D', 'R1'], ['post', 'D', -40], ['post', 'A', 100], ['void', 'A', 'R1'], ['void', 'A', 'R3']], {'status': {'D': 'posted', 'A': 'voided', 'R1': 'reversal'}, 'balance': -40, 'errors': [[0, 'unknown'], [4, 'not_voidable']]}], ['control 3', [['void', 'D', 'R2'], ['void', 'R3', 'R3'], ['post', 'B', 250], ['void', 'D', 'D'], ['post', 'C', 999], ['post', 'B', -40]], {'status': {'B': 'posted', 'C': 'posted'}, 'balance': 1249, 'errors': [[0, 'unknown'], [1, 'unknown'], [3, 'unknown'], [5, 'duplicate']]}], ['control 4', [['post', 'R1', -40], ['void', 'D', 'R1'], ['post', 'A', 250], ['void', 'R1', 'D']], {'status': {'R1': 'voided', 'A': 'posted', 'D': 'reversal'}, 'balance': 250, 'errors': [[1, 'unknown']]}], ['control 5', [['edit', 'A', 5], ['edit', 'A', 5], ['post', 'D', 100], ['post', 'B', 999]], {'status': {'D': 'posted', 'B': 'posted'}, 'balance': 1099, 'errors': [[0, 'bad_command'], [1, 'bad_command']]}], ['control 6', [['post', 'R1', 250], ['void', 'R1', 'D'], ['void', 'R1', 'R3'], ['void', 'R1', 'R3'], ['void', 'D', 'D'], ['post', 'B', -40], ['void', 'B', 'R2'], ['post', 'C', -40]], {'status': {'R1': 'voided', 'D': 'reversal', 'B': 'voided', 'R2': 'reversal', 'C': 'posted'}, 'balance': -40, 'errors': [[2, 'not_voidable'], [3, 'not_voidable'], [4, 'not_voidable']]}]], [['regression: failed void side effect', [['post', 'D', 100], ['void', 'B', 'R3'], ['post', 'A', 999], ['post', 'A', -40], ['void', 'D', 'D'], ['void', 'R1', 'R3']], {'status': {'D': 'posted', 'A': 'posted'}, 'balance': 1099, 'errors': [[1, 'unknown'], [3, 'duplicate'], [4, 'duplicate'], [5, 'unknown']]}], ['control 1', [['void', 'R2', 'R1'], ['void', 'B', 'D'], ['post', 'C', 250]], {'status': {'C': 'posted'}, 'balance': 250, 'errors': [[0, 'unknown'], [1, 'unknown']]}], ['control 2', [['void', 'A', 'R1'], ['post', 'A', -40], ['post', 'A', -40], ['post', 'A', 999], ['void', 'R1', 'R2']], {'status': {'A': 'posted'}, 'balance': -40, 'errors': [[0, 'unknown'], [2, 'duplicate'], [3, 'duplicate'], [4, 'unknown']]}], ['control 3', [['post', 'B', 250], ['post', 'D', 100], ['post', 'A', 999], ['post', 'D', -40]], {'status': {'B': 'posted', 'D': 'posted', 'A': 'posted'}, 'balance': 1349, 'errors': [[3, 'duplicate']]}], ['control 4', [['void', 'C', 'R2'], ['void', 'B', 'R3'], ['void', 'R1', 'R2'], ['void', 'D', 'D'], ['void', 'R3', 'R2'], ['post', 'C', 250], ['post', 'A', 999], ['post', 'R1', 100]], {'status': {'C': 'posted', 'A': 'posted', 'R1': 'posted'}, 'balance': 1349, 'errors': [[0, 'unknown'], [1, 'unknown'], [2, 'unknown'], [3, 'unknown'], [4, 'unknown']]}], ['control 5', [['void', 'R1', 'R3'], ['post', 'C', 999], ['post', 'R1', -40], ['post', 'D', 999], ['post', 'A', 250], ['post', 'B', 250], ['void', 'R2', 'D']], {'status': {'C': 'posted', 'R1': 'posted', 'D': 'posted', 'A': 'posted', 'B': 'posted'}, 'balance': 2458, 'errors': [[0, 'unknown'], [6, 'unknown']]}], ['control 6', [['void', 'C', 'R1'], ['void', 'R1', 'R1'], ['void', 'R1', 'D'], ['post', 'C', 999], ['void', 'R2', 'D'], ['void', 'R2', 'D'], ['void', 'C', 'R2']], {'status': {'C': 'voided', 'R2': 'reversal'}, 'balance': 0, 'errors': [[0, 'unknown'], [1, 'unknown'], [2, 'unknown'], [4, 'unknown'], [5, 'unknown']]}]]]
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:
A rejected void still leaves the target entry marked voided.

x = [['post', id, amount] | ['void', target_id, reversal_id] | other]. Posting an existing id is an error 'duplicate'. Voiding needs a known target ('unknown'), whose status is 'posted' ('not_voidable' for voided entries and reversals) and an unused reversal id ('duplicate'), checked in that order. A void marks the target 'voided' and creates a 'reversal' entry with the negated amount. Other commands give 'bad_command'. Return {'status', 'balance': sum of all amounts, 'errors': [[index, reason]]}.

split: open-access


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

N = 1
observations = []
def solve(x):
    PAIRS = (('ic_receivable', 'ic_payable'), ('ic_sales', 'ic_purchases'))
    PAIRED = {a for p in PAIRS for a in p}
    cons = {}
    ic = {}
    for ent, acct, cp, amt in x:
        if cp is None or cp == ent or acct not in PAIRED:
            cons[acct] = cons.get(acct, 0) + amt
        else:
            ic[(ent, acct, cp)] = ic.get((ent, acct, cp), 0) + amt
    keys = set()
    for (ent, acct, cp) in ic:
        for left, right in PAIRS:
            if acct == left:
                keys.add((ent, cp, left, right))
            elif acct == right:
                keys.add((cp, ent, left, right))
    mism = []
    for ent, cp, left, right in sorted(keys):
        a = ic.get((ent, left, cp), 0)
        b = ic.get((ent, right, cp), 0)
        m = min(a, b)
        if a != b:
            mism.append([ent, cp, left, a - b])
        if a - m:
            cons[left] = cons.get(left, 0) + a - m
        if b - m:
            cons[right] = cons.get(right, 0) + b - m
    return {'consolidated': {k: v for k, v in sorted(cons.items()) if v}, 'mismatches': mism}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: counterparty lookup', [['S1', 'ic_purchases', 'S2', 1000], ['S1', 'ic_loan', 'P', 250], ['S2', 'sales', None, -100]], {'consolidated': {'ic_loan': 250, 'ic_purchases': 1000, 'sales': -100}, 'mismatches': [['S2', 'S1', 'ic_sales', -1000]]}], ['control 1', [['P', 'ic_loan', 'S1', 250], ['S1', 'ic_payable', 'S1', 100], ['S2', 'sales', None, 1000], ['S1', 'ic_receivable', 'P', 250], ['P', 'ic_loan', 'P', 400], ['S1', 'ic_loan', 'P', 400]], {'consolidated': {'ic_loan': 1050, 'ic_payable': 100, 'ic_receivable': 250, 'sales': 1000}, 'mismatches': [['S1', 'P', 'ic_receivable', 250]]}], ['control 2', [['S2', 'cash', None, 400], ['S2', 'ic_receivable', 'S1', 250], ['S1', 'ic_loan', 'P', 400]], {'consolidated': {'cash': 400, 'ic_loan': 400, 'ic_receivable': 250}, 'mismatches': [['S2', 'S1', 'ic_receivable', 250]]}], ['control 3', [['S2', 'ic_sales', 'S2', 400], ['P', 'ic_receivable', 'S2', 100], ['S1', 'ic_payable', 'S1', 400]], {'consolidated': {'ic_payable': 400, 'ic_receivable': 100, 'ic_sales': 400}, 'mismatches': [['P', 'S2', 'ic_receivable', 100]]}], ['control 4', [['S2', 'ic_payable', 'S2', 100], ['S1', 'ic_sales', 'P', 400], ['P', 'ic_sales', 'P', 400], ['P', 'sales', None, 400], ['S2', 'ic_receivable', 'S2', 400], ['S2', 'ic_sales', 'P', 250], ['S1', 'ic_payable', 'S1', 400]], {'consolidated': {'ic_payable': 500, 'ic_receivable': 400, 'ic_sales': 1050, 'sales': 400}, 'mismatches': [['S1', 'P', 'ic_sales', 400], ['S2', 'P', 'ic_sales', 250]]}], ['control 5', [['P', 'ic_purchases', 'P', 400], ['P', 'sales', None, -1000], ['P', 'cash', None, 400]], {'consolidated': {'cash': 400, 'ic_purchases': 400, 'sales': -1000}, 'mismatches': []}], ['control 6', [['S1', 'sales', None, 1000], ['S1', 'ic_purchases', 'S1', 400], ['S1', 'ic_loan', 'S2', 400]], {'consolidated': {'ic_loan': 400, 'ic_purchases': 400, 'sales': 1000}, 'mismatches': []}]], [['regression: counterparty lookup', [['S1', 'ic_sales', 'P', 400], ['S2', 'ic_sales', 'S1', 400], ['S2', 'ic_purchases', 'S1', 1000]], {'consolidated': {'ic_purchases': 1000, 'ic_sales': 800}, 'mismatches': [['S1', 'P', 'ic_sales', 400], ['S1', 'S2', 'ic_sales', -1000], ['S2', 'S1', 'ic_sales', 400]]}], ['control 1', [['S1', 'cash', None, 400], ['P', 'ic_receivable', 'S1', 100], ['S1', 'ic_sales', 'P', 100]], {'consolidated': {'cash': 400, 'ic_receivable': 100, 'ic_sales': 100}, 'mismatches': [['P', 'S1', 'ic_receivable', 100], ['S1', 'P', 'ic_sales', 100]]}], ['control 2', [['S1', 'ic_loan', 'S2', 400], ['P', 'ic_receivable', 'P', 400], ['S2', 'sales', None, -250], ['S2', 'ic_sales', 'P', 100], ['P', 'ic_receivable', 'S1', 1000]], {'consolidated': {'ic_loan': 400, 'ic_receivable': 1400, 'ic_sales': 100, 'sales': -250}, 'mismatches': [['P', 'S1', 'ic_receivable', 1000], ['S2', 'P', 'ic_sales', 100]]}], ['control 3', [['S1', 'ic_sales', 'S2', 250], ['P', 'ic_receivable', 'S1', 400], ['S1', 'ic_loan', 'S2', 400]], {'consolidated': {'ic_loan': 400, 'ic_receivable': 400, 'ic_sales': 250}, 'mismatches': [['P', 'S1', 'ic_receivable', 400], ['S1', 'S2', 'ic_sales', 250]]}], ['control 4', [['P', 'ic_sales', 'P', 1000], ['S2', 'ic_purchases', 'S2', 400], ['P', 'ic_purchases', 'P', 100], ['P', 'ic_payable', 'P', 400], ['S1', 'ic_loan', 'S2', 250], ['S2', 'ic_sales', 'P', 250], ['S2', 'cash', None, -400]], {'consolidated': {'cash': -400, 'ic_loan': 250, 'ic_payable': 400, 'ic_purchases': 500, 'ic_sales': 1250}, 'mismatches': [['S2', 'P', 'ic_sales', 250]]}], ['control 5', [['P', 'sales', None, -1000], ['P', 'ic_loan', 'P', 400], ['P', 'ic_receivable', 'S1', 400], ['S2', 'cash', None, 400], ['S2', 'ic_loan', 'P', 400], ['S2', 'ic_loan', 'P', 1000], ['S2', 'ic_loan', 'S2', 100]], {'consolidated': {'cash': 400, 'ic_loan': 1900, 'ic_receivable': 400, 'sales': -1000}, 'mismatches': [['P', 'S1', 'ic_receivable', 400]]}], ['control 6', [['P', 'ic_receivable', None, 250], ['S2', 'ic_loan', 'S1', 400], ['S2', 'ic_receivable', 'S1', 250]], {'consolidated': {'ic_loan': 400, 'ic_receivable': 500}, 'mismatches': [['S2', 'S1', 'ic_receivable', 250]]}]], [['regression: counterparty lookup', [['S2', 'ic_payable', 'P', 250], ['S2', 'ic_loan', 'S2', 1000], ['P', 'ic_loan', 'P', 250], ['S1', 'ic_receivable', 'S2', 400], ['P', 'ic_receivable', 'S1', 250], ['S2', 'ic_sales', 'P', 1000]], {'consolidated': {'ic_loan': 1250, 'ic_payable': 250, 'ic_receivable': 650, 'ic_sales': 1000}, 'mismatches': [['P', 'S1', 'ic_receivable', 250], ['P', 'S2', 'ic_receivable', -250], ['S1', 'S2', 'ic_receivable', 400], ['S2', 'P', 'ic_sales', 1000]]}], ['control 1', [['S2', 'sales', None, -250], ['S2', 'ic_receivable', 'S1', 400], ['S2', 'cash', None, -400], ['P', 'ic_receivable', 'S1', 400], ['S2', 'ic_payable', 'S2', 400], ['S1', 'ic_sales', 'P', 400], ['S1', 'cash', None, 400]], {'consolidated': {'ic_payable': 400, 'ic_receivable': 800, 'ic_sales': 400, 'sales': -250}, 'mismatches': [['P', 'S1', 'ic_receivable', 400], ['S1', 'P', 'ic_sales', 400], ['S2', 'S1', 'ic_receivable', 400]]}], ['control 2', [['P', 'ic_receivable', None, -250], ['S1', 'sales', None, -250], ['S2', 'ic_sales', 'S1', 400]], {'consolidated': {'ic_receivable': -250, 'ic_sales': 400, 'sales': -250}, 'mismatches': [['S2', 'S1', 'ic_sales', 400]]}], ['control 3', [['P', 'ic_receivable', 'S1', 400], ['P', 'ic_purchases', 'P', 250], ['S1', 'ic_purchases', 'S1', 1000], ['S2', 'ic_receivable', 'P', 100], ['S2', 'ic_receivable', None, -400]], {'consolidated': {'ic_purchases': 1250, 'ic_receivable': 100}, 'mismatches': [['P', 'S1', 'ic_receivable', 400], ['S2', 'P', 'ic_receivable', 100]]}], ['control 4', [['S2', 'ic_receivable', 'P', 100], ['S1', 'ic_purchases', 'S2', 250], ['S2', 'ic_purchases', 'S1', 250]], {'consolidated': {'ic_purchases': 500, 'ic_receivable': 100}, 'mismatches': [['S1', 'S2', 'ic_sales', -250], ['S2', 'P', 'ic_receivable', 100], ['S2', 'S1', 'ic_sales', -250]]}], ['control 5', [['S1', 'ic_sales', 'S2', 400], ['S1', 'ic_loan', 'S2', 400], ['P', 'ic_receivable', 'S1', 1000], ['P', 'ic_receivable', 'S2', 400]], {'consolidated': {'ic_loan': 400, 'ic_receivable': 1400, 'ic_sales': 400}, 'mismatches': [['P', 'S1', 'ic_receivable', 1000], ['P', 'S2', 'ic_receivable', 400], ['S1', 'S2', 'ic_sales', 400]]}], ['control 6', [['S1', 'cash', None, 1000], ['P', 'ic_sales', 'P', 400], ['P', 'ic_receivable', 'P', 1000]], {'consolidated': {'cash': 1000, 'ic_receivable': 1000, 'ic_sales': 400}, 'mismatches': []}]], [['regression: counterparty lookup', [['P', 'ic_payable', 'S2', 400], ['S2', 'ic_purchases', 'S2', 400], ['S1', 'sales', None, -250], ['S1', 'ic_loan', 'S2', 100], ['P', 'ic_payable', 'S2', 400], ['P', 'ic_purchases', 'P', 100]], {'consolidated': {'ic_loan': 100, 'ic_payable': 800, 'ic_purchases': 500, 'sales': -250}, 'mismatches': [['S2', 'P', 'ic_receivable', -800]]}], ['control 1', [['S1', 'cash', None, 400], ['P', 'sales', None, -400], ['S1', 'ic_receivable', None, 1000]], {'consolidated': {'cash': 400, 'ic_receivable': 1000, 'sales': -400}, 'mismatches': []}], ['control 2', [['S2', 'ic_purchases', 'S2', 100], ['S1', 'ic_loan', 'P', 1000], ['P', 'ic_receivable', 'P', 100]], {'consolidated': {'ic_loan': 1000, 'ic_purchases': 100, 'ic_receivable': 100}, 'mismatches': []}], ['control 3', [['P', 'ic_sales', 'S2', 100], ['P', 'ic_loan', 'S2', 100], ['S1', 'ic_receivable', None, 400]], {'consolidated': {'ic_loan': 100, 'ic_receivable': 400, 'ic_sales': 100}, 'mismatches': [['P', 'S2', 'ic_sales', 100]]}], ['control 4', [['S1', 'ic_receivable', 'P', 400], ['P', 'ic_loan', 'S1', 1000], ['P', 'ic_receivable', None, 1000], ['S2', 'ic_loan', 'P', 400]], {'consolidated': {'ic_loan': 1400, 'ic_receivable': 1400}, 'mismatches': [['S1', 'P', 'ic_receivable', 400]]}], ['control 5', [['P', 'ic_sales', 'P', 1000], ['S2', 'ic_sales', 'P', 1000], ['S2', 'ic_sales', 'S2', 400], ['S2', 'ic_sales', 'P', 400]], {'consolidated': {'ic_sales': 2800}, 'mismatches': [['S2', 'P', 'ic_sales', 1400]]}], ['control 6', [['S1', 'ic_loan', 'P', 400], ['S2', 'ic_loan', 'P', 400], ['S2', 'ic_loan', 'P', 400], ['P', 'ic_sales', 'S1', 100], ['P', 'ic_loan', 'S2', 250], ['S2', 'ic_receivable', None, 250], ['S2', 'ic_loan', 'S1', 400]], {'consolidated': {'ic_loan': 1850, 'ic_receivable': 250, 'ic_sales': 100}, 'mismatches': [['P', 'S1', 'ic_sales', 100]]}]], [['regression: counterparty lookup', [['S2', 'ic_sales', 'P', 400], ['S2', 'ic_sales', 'P', 250], ['S2', 'ic_payable', 'S1', 400], ['S1', 'ic_purchases', 'P', 1000], ['P', 'ic_loan', 'S1', 100], ['S2', 'ic_receivable', 'P', 400], ['S2', 'cash', None, -1000]], {'consolidated': {'cash': -1000, 'ic_loan': 100, 'ic_payable': 400, 'ic_purchases': 1000, 'ic_receivable': 400, 'ic_sales': 650}, 'mismatches': [['P', 'S1', 'ic_sales', -1000], ['S1', 'S2', 'ic_receivable', -400], ['S2', 'P', 'ic_receivable', 400], ['S2', 'P', 'ic_sales', 650]]}], ['control 1', [['S1', 'ic_sales', 'S1', 1000], ['S1', 'ic_receivable', 'S2', 100], ['P', 'ic_sales', 'S2', 400], ['P', 'ic_sales', 'S1', 250]], {'consolidated': {'ic_receivable': 100, 'ic_sales': 1650}, 'mismatches': [['P', 'S1', 'ic_sales', 250], ['P', 'S2', 'ic_sales', 400], ['S1', 'S2', 'ic_receivable', 100]]}], ['control 2', [['P', 'ic_loan', 'P', 100], ['P', 'ic_loan', 'S2', 1000], ['S1', 'cash', None, -400], ['S2', 'ic_loan', 'P', 100], ['S2', 'ic_receivable', 'S1', 400], ['S1', 'ic_payable', 'S1', 400], ['P', 'sales', None, -1000]], {'consolidated': {'cash': -400, 'ic_loan': 1200, 'ic_payable': 400, 'ic_receivable': 400, 'sales': -1000}, 'mismatches': [['S2', 'S1', 'ic_receivable', 400]]}], ['control 3', [['P', 'sales', None, -100], ['P', 'ic_receivable', 'P', 1000], ['P', 'ic_sales', 'S1', 400], ['S2', 'ic_receivable', 'P', 250], ['P', 'cash', None, 250], ['P', 'ic_purchases', 'P', 400]], {'consolidated': {'cash': 250, 'ic_purchases': 400, 'ic_receivable': 1250, 'ic_sales': 400, 'sales': -100}, 'mismatches': [['P', 'S1', 'ic_sales', 400], ['S2', 'P', 'ic_receivable', 250]]}], ['control 4', [['P', 'ic_sales', 'S1', 1000], ['S2', 'ic_loan', 'P', 1000], ['S1', 'ic_payable', 'S1', 400], ['S1', 'ic_loan', 'P', 400], ['S1', 'ic_loan', 'S1', 400], ['S2', 'sales', None, 400]], {'consolidated': {'ic_loan': 1800, 'ic_payable': 400, 'ic_sales': 1000, 'sales': 400}, 'mismatches': [['P', 'S1', 'ic_sales', 1000]]}], ['control 5', [['S2', 'ic_loan', 'P', 100], ['S2', 'ic_receivable', 'S1', 100], ['P', 'ic_sales', 'P', 400], ['S1', 'ic_sales', 'S2', 400], ['S1', 'sales', None, 400]], {'consolidated': {'ic_loan': 100, 'ic_receivable': 100, 'ic_sales': 800, 'sales': 400}, 'mismatches': [['S1', 'S2', 'ic_sales', 400], ['S2', 'S1', 'ic_receivable', 100]]}], ['control 6', [['S2', 'ic_receivable', 'P', 400], ['P', 'ic_receivable', 'S2', 400], ['S2', 'ic_receivable', None, -1000]], {'consolidated': {'ic_receivable': -200}, 'mismatches': [['P', 'S2', 'ic_receivable', 400], ['S2', 'P', 'ic_receivable', 400]]}]]]
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):
    PAIRS = (('ic_receivable', 'ic_payable'), ('ic_sales', 'ic_purchases'))
    PAIRED = {a for p in PAIRS for a in p}
    cons = {}
    ic = {}
    for ent, acct, cp, amt in x:
        if cp is None or cp == ent or acct not in PAIRED:
            cons[acct] = cons.get(acct, 0) + amt
        else:
            ic[(ent, acct, cp)] = ic.get((ent, acct, cp), 0) + amt
    keys = set()
    for (ent, acct, cp) in ic:
        for left, right in PAIRS:
            if acct == left:
                keys.add((ent, cp, left, right))
            elif acct == right:
                keys.add((cp, ent, left, right))
    mism = []
    for ent, cp, left, right in sorted(keys):
        a = ic.get((ent, left, cp), 0)
        b = ic.get((cp, left, ent), 0)
        m = min(a, b)
        if a != b:
            mism.append([ent, cp, left, a - b])
        if a - m:
            cons[left] = cons.get(left, 0) + a - m
        if b - m:
            cons[right] = cons.get(right, 0) + b - m
    return {'consolidated': {k: v for k, v in sorted(cons.items()) if v}, 'mismatches': mism}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: counterparty lookup', [['S1', 'ic_purchases', 'S2', 1000], ['S1', 'ic_loan', 'P', 250], ['S2', 'sales', None, -100]], {'consolidated': {'ic_loan': 250, 'ic_purchases': 1000, 'sales': -100}, 'mismatches': [['S2', 'S1', 'ic_sales', -1000]]}], ['control 1', [['P', 'ic_loan', 'S1', 250], ['S1', 'ic_payable', 'S1', 100], ['S2', 'sales', None, 1000], ['S1', 'ic_receivable', 'P', 250], ['P', 'ic_loan', 'P', 400], ['S1', 'ic_loan', 'P', 400]], {'consolidated': {'ic_loan': 1050, 'ic_payable': 100, 'ic_receivable': 250, 'sales': 1000}, 'mismatches': [['S1', 'P', 'ic_receivable', 250]]}], ['control 2', [['S2', 'cash', None, 400], ['S2', 'ic_receivable', 'S1', 250], ['S1', 'ic_loan', 'P', 400]], {'consolidated': {'cash': 400, 'ic_loan': 400, 'ic_receivable': 250}, 'mismatches': [['S2', 'S1', 'ic_receivable', 250]]}], ['control 3', [['S2', 'ic_sales', 'S2', 400], ['P', 'ic_receivable', 'S2', 100], ['S1', 'ic_payable', 'S1', 400]], {'consolidated': {'ic_payable': 400, 'ic_receivable': 100, 'ic_sales': 400}, 'mismatches': [['P', 'S2', 'ic_receivable', 100]]}], ['control 4', [['S2', 'ic_payable', 'S2', 100], ['S1', 'ic_sales', 'P', 400], ['P', 'ic_sales', 'P', 400], ['P', 'sales', None, 400], ['S2', 'ic_receivable', 'S2', 400], ['S2', 'ic_sales', 'P', 250], ['S1', 'ic_payable', 'S1', 400]], {'consolidated': {'ic_payable': 500, 'ic_receivable': 400, 'ic_sales': 1050, 'sales': 400}, 'mismatches': [['S1', 'P', 'ic_sales', 400], ['S2', 'P', 'ic_sales', 250]]}], ['control 5', [['P', 'ic_purchases', 'P', 400], ['P', 'sales', None, -1000], ['P', 'cash', None, 400]], {'consolidated': {'cash': 400, 'ic_purchases': 400, 'sales': -1000}, 'mismatches': []}], ['control 6', [['S1', 'sales', None, 1000], ['S1', 'ic_purchases', 'S1', 400], ['S1', 'ic_loan', 'S2', 400]], {'consolidated': {'ic_loan': 400, 'ic_purchases': 400, 'sales': 1000}, 'mismatches': []}]], [['regression: counterparty lookup', [['S1', 'ic_sales', 'P', 400], ['S2', 'ic_sales', 'S1', 400], ['S2', 'ic_purchases', 'S1', 1000]], {'consolidated': {'ic_purchases': 1000, 'ic_sales': 800}, 'mismatches': [['S1', 'P', 'ic_sales', 400], ['S1', 'S2', 'ic_sales', -1000], ['S2', 'S1', 'ic_sales', 400]]}], ['control 1', [['S1', 'cash', None, 400], ['P', 'ic_receivable', 'S1', 100], ['S1', 'ic_sales', 'P', 100]], {'consolidated': {'cash': 400, 'ic_receivable': 100, 'ic_sales': 100}, 'mismatches': [['P', 'S1', 'ic_receivable', 100], ['S1', 'P', 'ic_sales', 100]]}], ['control 2', [['S1', 'ic_loan', 'S2', 400], ['P', 'ic_receivable', 'P', 400], ['S2', 'sales', None, -250], ['S2', 'ic_sales', 'P', 100], ['P', 'ic_receivable', 'S1', 1000]], {'consolidated': {'ic_loan': 400, 'ic_receivable': 1400, 'ic_sales': 100, 'sales': -250}, 'mismatches': [['P', 'S1', 'ic_receivable', 1000], ['S2', 'P', 'ic_sales', 100]]}], ['control 3', [['S1', 'ic_sales', 'S2', 250], ['P', 'ic_receivable', 'S1', 400], ['S1', 'ic_loan', 'S2', 400]], {'consolidated': {'ic_loan': 400, 'ic_receivable': 400, 'ic_sales': 250}, 'mismatches': [['P', 'S1', 'ic_receivable', 400], ['S1', 'S2', 'ic_sales', 250]]}], ['control 4', [['P', 'ic_sales', 'P', 1000], ['S2', 'ic_purchases', 'S2', 400], ['P', 'ic_purchases', 'P', 100], ['P', 'ic_payable', 'P', 400], ['S1', 'ic_loan', 'S2', 250], ['S2', 'ic_sales', 'P', 250], ['S2', 'cash', None, -400]], {'consolidated': {'cash': -400, 'ic_loan': 250, 'ic_payable': 400, 'ic_purchases': 500, 'ic_sales': 1250}, 'mismatches': [['S2', 'P', 'ic_sales', 250]]}], ['control 5', [['P', 'sales', None, -1000], ['P', 'ic_loan', 'P', 400], ['P', 'ic_receivable', 'S1', 400], ['S2', 'cash', None, 400], ['S2', 'ic_loan', 'P', 400], ['S2', 'ic_loan', 'P', 1000], ['S2', 'ic_loan', 'S2', 100]], {'consolidated': {'cash': 400, 'ic_loan': 1900, 'ic_receivable': 400, 'sales': -1000}, 'mismatches': [['P', 'S1', 'ic_receivable', 400]]}], ['control 6', [['P', 'ic_receivable', None, 250], ['S2', 'ic_loan', 'S1', 400], ['S2', 'ic_receivable', 'S1', 250]], {'consolidated': {'ic_loan': 400, 'ic_receivable': 500}, 'mismatches': [['S2', 'S1', 'ic_receivable', 250]]}]], [['regression: counterparty lookup', [['S2', 'ic_payable', 'P', 250], ['S2', 'ic_loan', 'S2', 1000], ['P', 'ic_loan', 'P', 250], ['S1', 'ic_receivable', 'S2', 400], ['P', 'ic_receivable', 'S1', 250], ['S2', 'ic_sales', 'P', 1000]], {'consolidated': {'ic_loan': 1250, 'ic_payable': 250, 'ic_receivable': 650, 'ic_sales': 1000}, 'mismatches': [['P', 'S1', 'ic_receivable', 250], ['P', 'S2', 'ic_receivable', -250], ['S1', 'S2', 'ic_receivable', 400], ['S2', 'P', 'ic_sales', 1000]]}], ['control 1', [['S2', 'sales', None, -250], ['S2', 'ic_receivable', 'S1', 400], ['S2', 'cash', None, -400], ['P', 'ic_receivable', 'S1', 400], ['S2', 'ic_payable', 'S2', 400], ['S1', 'ic_sales', 'P', 400], ['S1', 'cash', None, 400]], {'consolidated': {'ic_payable': 400, 'ic_receivable': 800, 'ic_sales': 400, 'sales': -250}, 'mismatches': [['P', 'S1', 'ic_receivable', 400], ['S1', 'P', 'ic_sales', 400], ['S2', 'S1', 'ic_receivable', 400]]}], ['control 2', [['P', 'ic_receivable', None, -250], ['S1', 'sales', None, -250], ['S2', 'ic_sales', 'S1', 400]], {'consolidated': {'ic_receivable': -250, 'ic_sales': 400, 'sales': -250}, 'mismatches': [['S2', 'S1', 'ic_sales', 400]]}], ['control 3', [['P', 'ic_receivable', 'S1', 400], ['P', 'ic_purchases', 'P', 250], ['S1', 'ic_purchases', 'S1', 1000], ['S2', 'ic_receivable', 'P', 100], ['S2', 'ic_receivable', None, -400]], {'consolidated': {'ic_purchases': 1250, 'ic_receivable': 100}, 'mismatches': [['P', 'S1', 'ic_receivable', 400], ['S2', 'P', 'ic_receivable', 100]]}], ['control 4', [['S2', 'ic_receivable', 'P', 100], ['S1', 'ic_purchases', 'S2', 250], ['S2', 'ic_purchases', 'S1', 250]], {'consolidated': {'ic_purchases': 500, 'ic_receivable': 100}, 'mismatches': [['S1', 'S2', 'ic_sales', -250], ['S2', 'P', 'ic_receivable', 100], ['S2', 'S1', 'ic_sales', -250]]}], ['control 5', [['S1', 'ic_sales', 'S2', 400], ['S1', 'ic_loan', 'S2', 400], ['P', 'ic_receivable', 'S1', 1000], ['P', 'ic_receivable', 'S2', 400]], {'consolidated': {'ic_loan': 400, 'ic_receivable': 1400, 'ic_sales': 400}, 'mismatches': [['P', 'S1', 'ic_receivable', 1000], ['P', 'S2', 'ic_receivable', 400], ['S1', 'S2', 'ic_sales', 400]]}], ['control 6', [['S1', 'cash', None, 1000], ['P', 'ic_sales', 'P', 400], ['P', 'ic_receivable', 'P', 1000]], {'consolidated': {'cash': 1000, 'ic_receivable': 1000, 'ic_sales': 400}, 'mismatches': []}]], [['regression: counterparty lookup', [['P', 'ic_payable', 'S2', 400], ['S2', 'ic_purchases', 'S2', 400], ['S1', 'sales', None, -250], ['S1', 'ic_loan', 'S2', 100], ['P', 'ic_payable', 'S2', 400], ['P', 'ic_purchases', 'P', 100]], {'consolidated': {'ic_loan': 100, 'ic_payable': 800, 'ic_purchases': 500, 'sales': -250}, 'mismatches': [['S2', 'P', 'ic_receivable', -800]]}], ['control 1', [['S1', 'cash', None, 400], ['P', 'sales', None, -400], ['S1', 'ic_receivable', None, 1000]], {'consolidated': {'cash': 400, 'ic_receivable': 1000, 'sales': -400}, 'mismatches': []}], ['control 2', [['S2', 'ic_purchases', 'S2', 100], ['S1', 'ic_loan', 'P', 1000], ['P', 'ic_receivable', 'P', 100]], {'consolidated': {'ic_loan': 1000, 'ic_purchases': 100, 'ic_receivable': 100}, 'mismatches': []}], ['control 3', [['P', 'ic_sales', 'S2', 100], ['P', 'ic_loan', 'S2', 100], ['S1', 'ic_receivable', None, 400]], {'consolidated': {'ic_loan': 100, 'ic_receivable': 400, 'ic_sales': 100}, 'mismatches': [['P', 'S2', 'ic_sales', 100]]}], ['control 4', [['S1', 'ic_receivable', 'P', 400], ['P', 'ic_loan', 'S1', 1000], ['P', 'ic_receivable', None, 1000], ['S2', 'ic_loan', 'P', 400]], {'consolidated': {'ic_loan': 1400, 'ic_receivable': 1400}, 'mismatches': [['S1', 'P', 'ic_receivable', 400]]}], ['control 5', [['P', 'ic_sales', 'P', 1000], ['S2', 'ic_sales', 'P', 1000], ['S2', 'ic_sales', 'S2', 400], ['S2', 'ic_sales', 'P', 400]], {'consolidated': {'ic_sales': 2800}, 'mismatches': [['S2', 'P', 'ic_sales', 1400]]}], ['control 6', [['S1', 'ic_loan', 'P', 400], ['S2', 'ic_loan', 'P', 400], ['S2', 'ic_loan', 'P', 400], ['P', 'ic_sales', 'S1', 100], ['P', 'ic_loan', 'S2', 250], ['S2', 'ic_receivable', None, 250], ['S2', 'ic_loan', 'S1', 400]], {'consolidated': {'ic_loan': 1850, 'ic_receivable': 250, 'ic_sales': 100}, 'mismatches': [['P', 'S1', 'ic_sales', 100]]}]], [['regression: counterparty lookup', [['S2', 'ic_sales', 'P', 400], ['S2', 'ic_sales', 'P', 250], ['S2', 'ic_payable', 'S1', 400], ['S1', 'ic_purchases', 'P', 1000], ['P', 'ic_loan', 'S1', 100], ['S2', 'ic_receivable', 'P', 400], ['S2', 'cash', None, -1000]], {'consolidated': {'cash': -1000, 'ic_loan': 100, 'ic_payable': 400, 'ic_purchases': 1000, 'ic_receivable': 400, 'ic_sales': 650}, 'mismatches': [['P', 'S1', 'ic_sales', -1000], ['S1', 'S2', 'ic_receivable', -400], ['S2', 'P', 'ic_receivable', 400], ['S2', 'P', 'ic_sales', 650]]}], ['control 1', [['S1', 'ic_sales', 'S1', 1000], ['S1', 'ic_receivable', 'S2', 100], ['P', 'ic_sales', 'S2', 400], ['P', 'ic_sales', 'S1', 250]], {'consolidated': {'ic_receivable': 100, 'ic_sales': 1650}, 'mismatches': [['P', 'S1', 'ic_sales', 250], ['P', 'S2', 'ic_sales', 400], ['S1', 'S2', 'ic_receivable', 100]]}], ['control 2', [['P', 'ic_loan', 'P', 100], ['P', 'ic_loan', 'S2', 1000], ['S1', 'cash', None, -400], ['S2', 'ic_loan', 'P', 100], ['S2', 'ic_receivable', 'S1', 400], ['S1', 'ic_payable', 'S1', 400], ['P', 'sales', None, -1000]], {'consolidated': {'cash': -400, 'ic_loan': 1200, 'ic_payable': 400, 'ic_receivable': 400, 'sales': -1000}, 'mismatches': [['S2', 'S1', 'ic_receivable', 400]]}], ['control 3', [['P', 'sales', None, -100], ['P', 'ic_receivable', 'P', 1000], ['P', 'ic_sales', 'S1', 400], ['S2', 'ic_receivable', 'P', 250], ['P', 'cash', None, 250], ['P', 'ic_purchases', 'P', 400]], {'consolidated': {'cash': 250, 'ic_purchases': 400, 'ic_receivable': 1250, 'ic_sales': 400, 'sales': -100}, 'mismatches': [['P', 'S1', 'ic_sales', 400], ['S2', 'P', 'ic_receivable', 250]]}], ['control 4', [['P', 'ic_sales', 'S1', 1000], ['S2', 'ic_loan', 'P', 1000], ['S1', 'ic_payable', 'S1', 400], ['S1', 'ic_loan', 'P', 400], ['S1', 'ic_loan', 'S1', 400], ['S2', 'sales', None, 400]], {'consolidated': {'ic_loan': 1800, 'ic_payable': 400, 'ic_sales': 1000, 'sales': 400}, 'mismatches': [['P', 'S1', 'ic_sales', 1000]]}], ['control 5', [['S2', 'ic_loan', 'P', 100], ['S2', 'ic_receivable', 'S1', 100], ['P', 'ic_sales', 'P', 400], ['S1', 'ic_sales', 'S2', 400], ['S1', 'sales', None, 400]], {'consolidated': {'ic_loan': 100, 'ic_receivable': 100, 'ic_sales': 800, 'sales': 400}, 'mismatches': [['S1', 'S2', 'ic_sales', 400], ['S2', 'S1', 'ic_receivable', 100]]}], ['control 6', [['S2', 'ic_receivable', 'P', 400], ['P', 'ic_receivable', 'S2', 400], ['S2', 'ic_receivable', None, -1000]], {'consolidated': {'ic_receivable': -200}, 'mismatches': [['P', 'S2', 'ic_receivable', 400], ['S2', 'P', 'ic_receivable', 400]]}]]]
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:
Intercompany receivables are matched against the same entity payables.

x = [[entity, account, counterparty or None, amount]]. Rows with no counterparty, the entity itself as counterparty, or an account outside the pairs (ic_receivable/ic_payable, ic_sales/ic_purchases) are consolidated as-is. For each (entity, counterparty, pair) the left balance of entity toward counterparty is matched against the right balance of counterparty toward entity; min(left, right) is eliminated from both, residuals are consolidated and a mismatch [entity, counterparty, left account, left - right] is reported when they differ. Return {'consolidated': nonzero account totals, 'mismatches': in sorted key order}.

split: open-access


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

N = 1
observations = []
def solve(x):
    PAIRS = (('ic_receivable', 'ic_payable'), ('ic_sales', 'ic_purchases'))
    PAIRED = {a for p in PAIRS for a in p}
    cons = {}
    ic = {}
    for ent, acct, cp, amt in x:
        if cp is None or cp == ent or acct not in PAIRED:
            cons[acct] = cons.get(acct, 0) + amt
        else:
            ic[(ent, acct, cp)] = ic.get((ent, acct, cp), 0) + amt
    keys = set()
    for (ent, acct, cp) in ic:
        for left, right in PAIRS:
            if acct == left:
                keys.add((ent, cp, left, right))
            elif acct == right:
                keys.add((cp, ent, left, right))
    mism = []
    for ent, cp, left, right in sorted(keys):
        a = ic.get((ent, left, cp), 0)
        b = ic.get((cp, right, ent), 0)
        m = min(a, b)
        if a != b:
            mism.append([ent, cp, left, abs(a - b)])
        if a - m:
            cons[left] = cons.get(left, 0) + a - m
        if b - m:
            cons[right] = cons.get(right, 0) + b - m
    return {'consolidated': {k: v for k, v in sorted(cons.items()) if v}, 'mismatches': mism}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: mismatch direction', [['S1', 'ic_purchases', 'S2', 1000], ['S1', 'ic_loan', 'P', 250], ['S2', 'sales', None, -100]], {'consolidated': {'ic_loan': 250, 'ic_purchases': 1000, 'sales': -100}, 'mismatches': [['S2', 'S1', 'ic_sales', -1000]]}], ['control 1', [['P', 'ic_loan', 'S1', 250], ['S1', 'ic_payable', 'S1', 100], ['S2', 'sales', None, 1000], ['S1', 'ic_receivable', 'P', 250], ['P', 'ic_loan', 'P', 400], ['S1', 'ic_loan', 'P', 400]], {'consolidated': {'ic_loan': 1050, 'ic_payable': 100, 'ic_receivable': 250, 'sales': 1000}, 'mismatches': [['S1', 'P', 'ic_receivable', 250]]}], ['control 2', [['S2', 'cash', None, 400], ['S2', 'ic_receivable', 'S1', 250], ['S1', 'ic_loan', 'P', 400]], {'consolidated': {'cash': 400, 'ic_loan': 400, 'ic_receivable': 250}, 'mismatches': [['S2', 'S1', 'ic_receivable', 250]]}], ['control 3', [['S2', 'ic_sales', 'S2', 400], ['P', 'ic_receivable', 'S2', 100], ['S1', 'ic_payable', 'S1', 400]], {'consolidated': {'ic_payable': 400, 'ic_receivable': 100, 'ic_sales': 400}, 'mismatches': [['P', 'S2', 'ic_receivable', 100]]}], ['control 4', [['S2', 'ic_payable', 'S2', 100], ['S1', 'ic_sales', 'P', 400], ['P', 'ic_sales', 'P', 400], ['P', 'sales', None, 400], ['S2', 'ic_receivable', 'S2', 400], ['S2', 'ic_sales', 'P', 250], ['S1', 'ic_payable', 'S1', 400]], {'consolidated': {'ic_payable': 500, 'ic_receivable': 400, 'ic_sales': 1050, 'sales': 400}, 'mismatches': [['S1', 'P', 'ic_sales', 400], ['S2', 'P', 'ic_sales', 250]]}], ['control 5', [['P', 'ic_purchases', 'P', 400], ['P', 'sales', None, -1000], ['P', 'cash', None, 400]], {'consolidated': {'cash': 400, 'ic_purchases': 400, 'sales': -1000}, 'mismatches': []}], ['control 6', [['S1', 'sales', None, 1000], ['S1', 'ic_purchases', 'S1', 400], ['S1', 'ic_loan', 'S2', 400]], {'consolidated': {'ic_loan': 400, 'ic_purchases': 400, 'sales': 1000}, 'mismatches': []}]], [['regression: mismatch direction', [['S1', 'ic_sales', 'P', 400], ['S2', 'ic_sales', 'S1', 400], ['S2', 'ic_purchases', 'S1', 1000]], {'consolidated': {'ic_purchases': 1000, 'ic_sales': 800}, 'mismatches': [['S1', 'P', 'ic_sales', 400], ['S1', 'S2', 'ic_sales', -1000], ['S2', 'S1', 'ic_sales', 400]]}], ['control 1', [['S1', 'cash', None, 400], ['P', 'ic_receivable', 'S1', 100], ['S1', 'ic_sales', 'P', 100]], {'consolidated': {'cash': 400, 'ic_receivable': 100, 'ic_sales': 100}, 'mismatches': [['P', 'S1', 'ic_receivable', 100], ['S1', 'P', 'ic_sales', 100]]}], ['control 2', [['S1', 'ic_loan', 'S2', 400], ['P', 'ic_receivable', 'P', 400], ['S2', 'sales', None, -250], ['S2', 'ic_sales', 'P', 100], ['P', 'ic_receivable', 'S1', 1000]], {'consolidated': {'ic_loan': 400, 'ic_receivable': 1400, 'ic_sales': 100, 'sales': -250}, 'mismatches': [['P', 'S1', 'ic_receivable', 1000], ['S2', 'P', 'ic_sales', 100]]}], ['control 3', [['S1', 'ic_sales', 'S2', 250], ['P', 'ic_receivable', 'S1', 400], ['S1', 'ic_loan', 'S2', 400]], {'consolidated': {'ic_loan': 400, 'ic_receivable': 400, 'ic_sales': 250}, 'mismatches': [['P', 'S1', 'ic_receivable', 400], ['S1', 'S2', 'ic_sales', 250]]}], ['control 4', [['P', 'ic_sales', 'P', 1000], ['S2', 'ic_purchases', 'S2', 400], ['P', 'ic_purchases', 'P', 100], ['P', 'ic_payable', 'P', 400], ['S1', 'ic_loan', 'S2', 250], ['S2', 'ic_sales', 'P', 250], ['S2', 'cash', None, -400]], {'consolidated': {'cash': -400, 'ic_loan': 250, 'ic_payable': 400, 'ic_purchases': 500, 'ic_sales': 1250}, 'mismatches': [['S2', 'P', 'ic_sales', 250]]}], ['control 5', [['P', 'sales', None, -1000], ['P', 'ic_loan', 'P', 400], ['P', 'ic_receivable', 'S1', 400], ['S2', 'cash', None, 400], ['S2', 'ic_loan', 'P', 400], ['S2', 'ic_loan', 'P', 1000], ['S2', 'ic_loan', 'S2', 100]], {'consolidated': {'cash': 400, 'ic_loan': 1900, 'ic_receivable': 400, 'sales': -1000}, 'mismatches': [['P', 'S1', 'ic_receivable', 400]]}], ['control 6', [['P', 'ic_receivable', None, 250], ['S2', 'ic_loan', 'S1', 400], ['S2', 'ic_receivable', 'S1', 250]], {'consolidated': {'ic_loan': 400, 'ic_receivable': 500}, 'mismatches': [['S2', 'S1', 'ic_receivable', 250]]}]], [['regression: mismatch direction', [['S2', 'ic_payable', 'P', 250], ['S2', 'ic_loan', 'S2', 1000], ['P', 'ic_loan', 'P', 250], ['S1', 'ic_receivable', 'S2', 400], ['P', 'ic_receivable', 'S1', 250], ['S2', 'ic_sales', 'P', 1000]], {'consolidated': {'ic_loan': 1250, 'ic_payable': 250, 'ic_receivable': 650, 'ic_sales': 1000}, 'mismatches': [['P', 'S1', 'ic_receivable', 250], ['P', 'S2', 'ic_receivable', -250], ['S1', 'S2', 'ic_receivable', 400], ['S2', 'P', 'ic_sales', 1000]]}], ['control 1', [['P', 'ic_receivable', None, -1000], ['P', 'ic_payable', 'P', 100], ['S1', 'ic_sales', 'S1', 400], ['S1', 'ic_payable', 'S2', 250], ['P', 'ic_sales', 'P', 100], ['S2', 'ic_receivable', 'S1', 400]], {'consolidated': {'ic_payable': 100, 'ic_receivable': -850, 'ic_sales': 500}, 'mismatches': [['S2', 'S1', 'ic_receivable', 150]]}], ['control 2', [['S2', 'sales', None, -250], ['S2', 'ic_receivable', 'S1', 400], ['S2', 'cash', None, -400], ['P', 'ic_receivable', 'S1', 400], ['S2', 'ic_payable', 'S2', 400], ['S1', 'ic_sales', 'P', 400], ['S1', 'cash', None, 400]], {'consolidated': {'ic_payable': 400, 'ic_receivable': 800, 'ic_sales': 400, 'sales': -250}, 'mismatches': [['P', 'S1', 'ic_receivable', 400], ['S1', 'P', 'ic_sales', 400], ['S2', 'S1', 'ic_receivable', 400]]}], ['control 3', [['P', 'ic_receivable', None, -250], ['S1', 'sales', None, -250], ['S2', 'ic_sales', 'S1', 400]], {'consolidated': {'ic_receivable': -250, 'ic_sales': 400, 'sales': -250}, 'mismatches': [['S2', 'S1', 'ic_sales', 400]]}], ['control 4', [['P', 'ic_receivable', 'S1', 400], ['P', 'ic_purchases', 'P', 250], ['S1', 'ic_purchases', 'S1', 1000], ['S2', 'ic_receivable', 'P', 100], ['S2', 'ic_receivable', None, -400]], {'consolidated': {'ic_purchases': 1250, 'ic_receivable': 100}, 'mismatches': [['P', 'S1', 'ic_receivable', 400], ['S2', 'P', 'ic_receivable', 100]]}], ['control 5', [['S1', 'ic_sales', 'S2', 400], ['S1', 'ic_loan', 'S2', 400], ['P', 'ic_receivable', 'S1', 1000], ['P', 'ic_receivable', 'S2', 400]], {'consolidated': {'ic_loan': 400, 'ic_receivable': 1400, 'ic_sales': 400}, 'mismatches': [['P', 'S1', 'ic_receivable', 1000], ['P', 'S2', 'ic_receivable', 400], ['S1', 'S2', 'ic_sales', 400]]}], ['control 6', [['S1', 'cash', None, 1000], ['P', 'ic_sales', 'P', 400], ['P', 'ic_receivable', 'P', 1000]], {'consolidated': {'cash': 1000, 'ic_receivable': 1000, 'ic_sales': 400}, 'mismatches': []}]], [['regression: mismatch direction', [['P', 'ic_payable', 'S2', 400], ['S2', 'ic_purchases', 'S2', 400], ['S1', 'sales', None, -250], ['S1', 'ic_loan', 'S2', 100], ['P', 'ic_payable', 'S2', 400], ['P', 'ic_purchases', 'P', 100]], {'consolidated': {'ic_loan': 100, 'ic_payable': 800, 'ic_purchases': 500, 'sales': -250}, 'mismatches': [['S2', 'P', 'ic_receivable', -800]]}], ['control 1', [['S1', 'cash', None, 400], ['P', 'sales', None, -400], ['S1', 'ic_receivable', None, 1000]], {'consolidated': {'cash': 400, 'ic_receivable': 1000, 'sales': -400}, 'mismatches': []}], ['control 2', [['S2', 'ic_purchases', 'S2', 100], ['S1', 'ic_loan', 'P', 1000], ['P', 'ic_receivable', 'P', 100]], {'consolidated': {'ic_loan': 1000, 'ic_purchases': 100, 'ic_receivable': 100}, 'mismatches': []}], ['control 3', [['P', 'ic_sales', 'S2', 100], ['P', 'ic_loan', 'S2', 100], ['S1', 'ic_receivable', None, 400]], {'consolidated': {'ic_loan': 100, 'ic_receivable': 400, 'ic_sales': 100}, 'mismatches': [['P', 'S2', 'ic_sales', 100]]}], ['control 4', [['S1', 'ic_receivable', 'P', 400], ['P', 'ic_loan', 'S1', 1000], ['P', 'ic_receivable', None, 1000], ['S2', 'ic_loan', 'P', 400]], {'consolidated': {'ic_loan': 1400, 'ic_receivable': 1400}, 'mismatches': [['S1', 'P', 'ic_receivable', 400]]}], ['control 5', [['P', 'ic_sales', 'P', 1000], ['S2', 'ic_sales', 'P', 1000], ['S2', 'ic_sales', 'S2', 400], ['S2', 'ic_sales', 'P', 400]], {'consolidated': {'ic_sales': 2800}, 'mismatches': [['S2', 'P', 'ic_sales', 1400]]}], ['control 6', [['S1', 'ic_loan', 'P', 400], ['S2', 'ic_loan', 'P', 400], ['S2', 'ic_loan', 'P', 400], ['P', 'ic_sales', 'S1', 100], ['P', 'ic_loan', 'S2', 250], ['S2', 'ic_receivable', None, 250], ['S2', 'ic_loan', 'S1', 400]], {'consolidated': {'ic_loan': 1850, 'ic_receivable': 250, 'ic_sales': 100}, 'mismatches': [['P', 'S1', 'ic_sales', 100]]}]], [['regression: mismatch direction', [['S2', 'ic_sales', 'P', 400], ['S2', 'ic_sales', 'P', 250], ['S2', 'ic_payable', 'S1', 400], ['S1', 'ic_purchases', 'P', 1000], ['P', 'ic_loan', 'S1', 100], ['S2', 'ic_receivable', 'P', 400], ['S2', 'cash', None, -1000]], {'consolidated': {'cash': -1000, 'ic_loan': 100, 'ic_payable': 400, 'ic_purchases': 1000, 'ic_receivable': 400, 'ic_sales': 650}, 'mismatches': [['P', 'S1', 'ic_sales', -1000], ['S1', 'S2', 'ic_receivable', -400], ['S2', 'P', 'ic_receivable', 400], ['S2', 'P', 'ic_sales', 650]]}], ['control 1', [['P', 'ic_purchases', 'S1', 100], ['S1', 'ic_sales', 'P', 400], ['S2', 'ic_loan', 'S2', 1000], ['P', 'cash', None, 100]], {'consolidated': {'cash': 100, 'ic_loan': 1000, 'ic_sales': 300}, 'mismatches': [['S1', 'P', 'ic_sales', 300]]}], ['control 2', [['S1', 'ic_sales', 'S1', 1000], ['S1', 'ic_receivable', 'S2', 100], ['P', 'ic_sales', 'S2', 400], ['P', 'ic_sales', 'S1', 250]], {'consolidated': {'ic_receivable': 100, 'ic_sales': 1650}, 'mismatches': [['P', 'S1', 'ic_sales', 250], ['P', 'S2', 'ic_sales', 400], ['S1', 'S2', 'ic_receivable', 100]]}], ['control 3', [['P', 'ic_loan', 'P', 100], ['P', 'ic_loan', 'S2', 1000], ['S1', 'cash', None, -400], ['S2', 'ic_loan', 'P', 100], ['S2', 'ic_receivable', 'S1', 400], ['S1', 'ic_payable', 'S1', 400], ['P', 'sales', None, -1000]], {'consolidated': {'cash': -400, 'ic_loan': 1200, 'ic_payable': 400, 'ic_receivable': 400, 'sales': -1000}, 'mismatches': [['S2', 'S1', 'ic_receivable', 400]]}], ['control 4', [['P', 'sales', None, -100], ['P', 'ic_receivable', 'P', 1000], ['P', 'ic_sales', 'S1', 400], ['S2', 'ic_receivable', 'P', 250], ['P', 'cash', None, 250], ['P', 'ic_purchases', 'P', 400]], {'consolidated': {'cash': 250, 'ic_purchases': 400, 'ic_receivable': 1250, 'ic_sales': 400, 'sales': -100}, 'mismatches': [['P', 'S1', 'ic_sales', 400], ['S2', 'P', 'ic_receivable', 250]]}], ['control 5', [['P', 'ic_sales', 'S1', 1000], ['S2', 'ic_loan', 'P', 1000], ['S1', 'ic_payable', 'S1', 400], ['S1', 'ic_loan', 'P', 400], ['S1', 'ic_loan', 'S1', 400], ['S2', 'sales', None, 400]], {'consolidated': {'ic_loan': 1800, 'ic_payable': 400, 'ic_sales': 1000, 'sales': 400}, 'mismatches': [['P', 'S1', 'ic_sales', 1000]]}], ['control 6', [['S2', 'ic_loan', 'P', 100], ['S2', 'ic_receivable', 'S1', 100], ['P', 'ic_sales', 'P', 400], ['S1', 'ic_sales', 'S2', 400], ['S1', 'sales', None, 400]], {'consolidated': {'ic_loan': 100, 'ic_receivable': 100, 'ic_sales': 800, 'sales': 400}, 'mismatches': [['S1', 'S2', 'ic_sales', 400], ['S2', 'S1', 'ic_receivable', 100]]}]]]
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):
    PAIRS = (('ic_receivable', 'ic_payable'), ('ic_sales', 'ic_purchases'))
    PAIRED = {a for p in PAIRS for a in p}
    cons = {}
    ic = {}
    for ent, acct, cp, amt in x:
        if cp is None or cp == ent or acct not in PAIRED:
            cons[acct] = cons.get(acct, 0) + amt
        else:
            ic[(ent, acct, cp)] = ic.get((ent, acct, cp), 0) + amt
    keys = set()
    for (ent, acct, cp) in ic:
        for left, right in PAIRS:
            if acct == left:
                keys.add((ent, cp, left, right))
            elif acct == right:
                keys.add((cp, ent, left, right))
    mism = []
    for ent, cp, left, right in sorted(keys):
        a = ic.get((ent, left, cp), 0)
        b = ic.get((cp, right, ent), 0)
        m = min(a, b)
        if a != b:
            mism.append([ent, cp, left, b - a])
        if a - m:
            cons[left] = cons.get(left, 0) + a - m
        if b - m:
            cons[right] = cons.get(right, 0) + b - m
    return {'consolidated': {k: v for k, v in sorted(cons.items()) if v}, 'mismatches': mism}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: mismatch direction', [['S1', 'ic_purchases', 'S2', 1000], ['S1', 'ic_loan', 'P', 250], ['S2', 'sales', None, -100]], {'consolidated': {'ic_loan': 250, 'ic_purchases': 1000, 'sales': -100}, 'mismatches': [['S2', 'S1', 'ic_sales', -1000]]}], ['control 1', [['P', 'ic_loan', 'S1', 250], ['S1', 'ic_payable', 'S1', 100], ['S2', 'sales', None, 1000], ['S1', 'ic_receivable', 'P', 250], ['P', 'ic_loan', 'P', 400], ['S1', 'ic_loan', 'P', 400]], {'consolidated': {'ic_loan': 1050, 'ic_payable': 100, 'ic_receivable': 250, 'sales': 1000}, 'mismatches': [['S1', 'P', 'ic_receivable', 250]]}], ['control 2', [['S2', 'cash', None, 400], ['S2', 'ic_receivable', 'S1', 250], ['S1', 'ic_loan', 'P', 400]], {'consolidated': {'cash': 400, 'ic_loan': 400, 'ic_receivable': 250}, 'mismatches': [['S2', 'S1', 'ic_receivable', 250]]}], ['control 3', [['S2', 'ic_sales', 'S2', 400], ['P', 'ic_receivable', 'S2', 100], ['S1', 'ic_payable', 'S1', 400]], {'consolidated': {'ic_payable': 400, 'ic_receivable': 100, 'ic_sales': 400}, 'mismatches': [['P', 'S2', 'ic_receivable', 100]]}], ['control 4', [['S2', 'ic_payable', 'S2', 100], ['S1', 'ic_sales', 'P', 400], ['P', 'ic_sales', 'P', 400], ['P', 'sales', None, 400], ['S2', 'ic_receivable', 'S2', 400], ['S2', 'ic_sales', 'P', 250], ['S1', 'ic_payable', 'S1', 400]], {'consolidated': {'ic_payable': 500, 'ic_receivable': 400, 'ic_sales': 1050, 'sales': 400}, 'mismatches': [['S1', 'P', 'ic_sales', 400], ['S2', 'P', 'ic_sales', 250]]}], ['control 5', [['P', 'ic_purchases', 'P', 400], ['P', 'sales', None, -1000], ['P', 'cash', None, 400]], {'consolidated': {'cash': 400, 'ic_purchases': 400, 'sales': -1000}, 'mismatches': []}], ['control 6', [['S1', 'sales', None, 1000], ['S1', 'ic_purchases', 'S1', 400], ['S1', 'ic_loan', 'S2', 400]], {'consolidated': {'ic_loan': 400, 'ic_purchases': 400, 'sales': 1000}, 'mismatches': []}]], [['regression: mismatch direction', [['S1', 'ic_sales', 'P', 400], ['S2', 'ic_sales', 'S1', 400], ['S2', 'ic_purchases', 'S1', 1000]], {'consolidated': {'ic_purchases': 1000, 'ic_sales': 800}, 'mismatches': [['S1', 'P', 'ic_sales', 400], ['S1', 'S2', 'ic_sales', -1000], ['S2', 'S1', 'ic_sales', 400]]}], ['control 1', [['S1', 'cash', None, 400], ['P', 'ic_receivable', 'S1', 100], ['S1', 'ic_sales', 'P', 100]], {'consolidated': {'cash': 400, 'ic_receivable': 100, 'ic_sales': 100}, 'mismatches': [['P', 'S1', 'ic_receivable', 100], ['S1', 'P', 'ic_sales', 100]]}], ['control 2', [['S1', 'ic_loan', 'S2', 400], ['P', 'ic_receivable', 'P', 400], ['S2', 'sales', None, -250], ['S2', 'ic_sales', 'P', 100], ['P', 'ic_receivable', 'S1', 1000]], {'consolidated': {'ic_loan': 400, 'ic_receivable': 1400, 'ic_sales': 100, 'sales': -250}, 'mismatches': [['P', 'S1', 'ic_receivable', 1000], ['S2', 'P', 'ic_sales', 100]]}], ['control 3', [['S1', 'ic_sales', 'S2', 250], ['P', 'ic_receivable', 'S1', 400], ['S1', 'ic_loan', 'S2', 400]], {'consolidated': {'ic_loan': 400, 'ic_receivable': 400, 'ic_sales': 250}, 'mismatches': [['P', 'S1', 'ic_receivable', 400], ['S1', 'S2', 'ic_sales', 250]]}], ['control 4', [['P', 'ic_sales', 'P', 1000], ['S2', 'ic_purchases', 'S2', 400], ['P', 'ic_purchases', 'P', 100], ['P', 'ic_payable', 'P', 400], ['S1', 'ic_loan', 'S2', 250], ['S2', 'ic_sales', 'P', 250], ['S2', 'cash', None, -400]], {'consolidated': {'cash': -400, 'ic_loan': 250, 'ic_payable': 400, 'ic_purchases': 500, 'ic_sales': 1250}, 'mismatches': [['S2', 'P', 'ic_sales', 250]]}], ['control 5', [['P', 'sales', None, -1000], ['P', 'ic_loan', 'P', 400], ['P', 'ic_receivable', 'S1', 400], ['S2', 'cash', None, 400], ['S2', 'ic_loan', 'P', 400], ['S2', 'ic_loan', 'P', 1000], ['S2', 'ic_loan', 'S2', 100]], {'consolidated': {'cash': 400, 'ic_loan': 1900, 'ic_receivable': 400, 'sales': -1000}, 'mismatches': [['P', 'S1', 'ic_receivable', 400]]}], ['control 6', [['P', 'ic_receivable', None, 250], ['S2', 'ic_loan', 'S1', 400], ['S2', 'ic_receivable', 'S1', 250]], {'consolidated': {'ic_loan': 400, 'ic_receivable': 500}, 'mismatches': [['S2', 'S1', 'ic_receivable', 250]]}]], [['regression: mismatch direction', [['S2', 'ic_payable', 'P', 250], ['S2', 'ic_loan', 'S2', 1000], ['P', 'ic_loan', 'P', 250], ['S1', 'ic_receivable', 'S2', 400], ['P', 'ic_receivable', 'S1', 250], ['S2', 'ic_sales', 'P', 1000]], {'consolidated': {'ic_loan': 1250, 'ic_payable': 250, 'ic_receivable': 650, 'ic_sales': 1000}, 'mismatches': [['P', 'S1', 'ic_receivable', 250], ['P', 'S2', 'ic_receivable', -250], ['S1', 'S2', 'ic_receivable', 400], ['S2', 'P', 'ic_sales', 1000]]}], ['control 1', [['P', 'ic_receivable', None, -1000], ['P', 'ic_payable', 'P', 100], ['S1', 'ic_sales', 'S1', 400], ['S1', 'ic_payable', 'S2', 250], ['P', 'ic_sales', 'P', 100], ['S2', 'ic_receivable', 'S1', 400]], {'consolidated': {'ic_payable': 100, 'ic_receivable': -850, 'ic_sales': 500}, 'mismatches': [['S2', 'S1', 'ic_receivable', 150]]}], ['control 2', [['S2', 'sales', None, -250], ['S2', 'ic_receivable', 'S1', 400], ['S2', 'cash', None, -400], ['P', 'ic_receivable', 'S1', 400], ['S2', 'ic_payable', 'S2', 400], ['S1', 'ic_sales', 'P', 400], ['S1', 'cash', None, 400]], {'consolidated': {'ic_payable': 400, 'ic_receivable': 800, 'ic_sales': 400, 'sales': -250}, 'mismatches': [['P', 'S1', 'ic_receivable', 400], ['S1', 'P', 'ic_sales', 400], ['S2', 'S1', 'ic_receivable', 400]]}], ['control 3', [['P', 'ic_receivable', None, -250], ['S1', 'sales', None, -250], ['S2', 'ic_sales', 'S1', 400]], {'consolidated': {'ic_receivable': -250, 'ic_sales': 400, 'sales': -250}, 'mismatches': [['S2', 'S1', 'ic_sales', 400]]}], ['control 4', [['P', 'ic_receivable', 'S1', 400], ['P', 'ic_purchases', 'P', 250], ['S1', 'ic_purchases', 'S1', 1000], ['S2', 'ic_receivable', 'P', 100], ['S2', 'ic_receivable', None, -400]], {'consolidated': {'ic_purchases': 1250, 'ic_receivable': 100}, 'mismatches': [['P', 'S1', 'ic_receivable', 400], ['S2', 'P', 'ic_receivable', 100]]}], ['control 5', [['S1', 'ic_sales', 'S2', 400], ['S1', 'ic_loan', 'S2', 400], ['P', 'ic_receivable', 'S1', 1000], ['P', 'ic_receivable', 'S2', 400]], {'consolidated': {'ic_loan': 400, 'ic_receivable': 1400, 'ic_sales': 400}, 'mismatches': [['P', 'S1', 'ic_receivable', 1000], ['P', 'S2', 'ic_receivable', 400], ['S1', 'S2', 'ic_sales', 400]]}], ['control 6', [['S1', 'cash', None, 1000], ['P', 'ic_sales', 'P', 400], ['P', 'ic_receivable', 'P', 1000]], {'consolidated': {'cash': 1000, 'ic_receivable': 1000, 'ic_sales': 400}, 'mismatches': []}]], [['regression: mismatch direction', [['P', 'ic_payable', 'S2', 400], ['S2', 'ic_purchases', 'S2', 400], ['S1', 'sales', None, -250], ['S1', 'ic_loan', 'S2', 100], ['P', 'ic_payable', 'S2', 400], ['P', 'ic_purchases', 'P', 100]], {'consolidated': {'ic_loan': 100, 'ic_payable': 800, 'ic_purchases': 500, 'sales': -250}, 'mismatches': [['S2', 'P', 'ic_receivable', -800]]}], ['control 1', [['S1', 'cash', None, 400], ['P', 'sales', None, -400], ['S1', 'ic_receivable', None, 1000]], {'consolidated': {'cash': 400, 'ic_receivable': 1000, 'sales': -400}, 'mismatches': []}], ['control 2', [['S2', 'ic_purchases', 'S2', 100], ['S1', 'ic_loan', 'P', 1000], ['P', 'ic_receivable', 'P', 100]], {'consolidated': {'ic_loan': 1000, 'ic_purchases': 100, 'ic_receivable': 100}, 'mismatches': []}], ['control 3', [['P', 'ic_sales', 'S2', 100], ['P', 'ic_loan', 'S2', 100], ['S1', 'ic_receivable', None, 400]], {'consolidated': {'ic_loan': 100, 'ic_receivable': 400, 'ic_sales': 100}, 'mismatches': [['P', 'S2', 'ic_sales', 100]]}], ['control 4', [['S1', 'ic_receivable', 'P', 400], ['P', 'ic_loan', 'S1', 1000], ['P', 'ic_receivable', None, 1000], ['S2', 'ic_loan', 'P', 400]], {'consolidated': {'ic_loan': 1400, 'ic_receivable': 1400}, 'mismatches': [['S1', 'P', 'ic_receivable', 400]]}], ['control 5', [['P', 'ic_sales', 'P', 1000], ['S2', 'ic_sales', 'P', 1000], ['S2', 'ic_sales', 'S2', 400], ['S2', 'ic_sales', 'P', 400]], {'consolidated': {'ic_sales': 2800}, 'mismatches': [['S2', 'P', 'ic_sales', 1400]]}], ['control 6', [['S1', 'ic_loan', 'P', 400], ['S2', 'ic_loan', 'P', 400], ['S2', 'ic_loan', 'P', 400], ['P', 'ic_sales', 'S1', 100], ['P', 'ic_loan', 'S2', 250], ['S2', 'ic_receivable', None, 250], ['S2', 'ic_loan', 'S1', 400]], {'consolidated': {'ic_loan': 1850, 'ic_receivable': 250, 'ic_sales': 100}, 'mismatches': [['P', 'S1', 'ic_sales', 100]]}]], [['regression: mismatch direction', [['S2', 'ic_sales', 'P', 400], ['S2', 'ic_sales', 'P', 250], ['S2', 'ic_payable', 'S1', 400], ['S1', 'ic_purchases', 'P', 1000], ['P', 'ic_loan', 'S1', 100], ['S2', 'ic_receivable', 'P', 400], ['S2', 'cash', None, -1000]], {'consolidated': {'cash': -1000, 'ic_loan': 100, 'ic_payable': 400, 'ic_purchases': 1000, 'ic_receivable': 400, 'ic_sales': 650}, 'mismatches': [['P', 'S1', 'ic_sales', -1000], ['S1', 'S2', 'ic_receivable', -400], ['S2', 'P', 'ic_receivable', 400], ['S2', 'P', 'ic_sales', 650]]}], ['control 1', [['P', 'ic_purchases', 'S1', 100], ['S1', 'ic_sales', 'P', 400], ['S2', 'ic_loan', 'S2', 1000], ['P', 'cash', None, 100]], {'consolidated': {'cash': 100, 'ic_loan': 1000, 'ic_sales': 300}, 'mismatches': [['S1', 'P', 'ic_sales', 300]]}], ['control 2', [['S1', 'ic_sales', 'S1', 1000], ['S1', 'ic_receivable', 'S2', 100], ['P', 'ic_sales', 'S2', 400], ['P', 'ic_sales', 'S1', 250]], {'consolidated': {'ic_receivable': 100, 'ic_sales': 1650}, 'mismatches': [['P', 'S1', 'ic_sales', 250], ['P', 'S2', 'ic_sales', 400], ['S1', 'S2', 'ic_receivable', 100]]}], ['control 3', [['P', 'ic_loan', 'P', 100], ['P', 'ic_loan', 'S2', 1000], ['S1', 'cash', None, -400], ['S2', 'ic_loan', 'P', 100], ['S2', 'ic_receivable', 'S1', 400], ['S1', 'ic_payable', 'S1', 400], ['P', 'sales', None, -1000]], {'consolidated': {'cash': -400, 'ic_loan': 1200, 'ic_payable': 400, 'ic_receivable': 400, 'sales': -1000}, 'mismatches': [['S2', 'S1', 'ic_receivable', 400]]}], ['control 4', [['P', 'sales', None, -100], ['P', 'ic_receivable', 'P', 1000], ['P', 'ic_sales', 'S1', 400], ['S2', 'ic_receivable', 'P', 250], ['P', 'cash', None, 250], ['P', 'ic_purchases', 'P', 400]], {'consolidated': {'cash': 250, 'ic_purchases': 400, 'ic_receivable': 1250, 'ic_sales': 400, 'sales': -100}, 'mismatches': [['P', 'S1', 'ic_sales', 400], ['S2', 'P', 'ic_receivable', 250]]}], ['control 5', [['P', 'ic_sales', 'S1', 1000], ['S2', 'ic_loan', 'P', 1000], ['S1', 'ic_payable', 'S1', 400], ['S1', 'ic_loan', 'P', 400], ['S1', 'ic_loan', 'S1', 400], ['S2', 'sales', None, 400]], {'consolidated': {'ic_loan': 1800, 'ic_payable': 400, 'ic_sales': 1000, 'sales': 400}, 'mismatches': [['P', 'S1', 'ic_sales', 1000]]}], ['control 6', [['S2', 'ic_loan', 'P', 100], ['S2', 'ic_receivable', 'S1', 100], ['P', 'ic_sales', 'P', 400], ['S1', 'ic_sales', 'S2', 400], ['S1', 'sales', None, 400]], {'consolidated': {'ic_loan': 100, 'ic_receivable': 100, 'ic_sales': 800, 'sales': 400}, 'mismatches': [['S1', 'S2', 'ic_sales', 400], ['S2', 'S1', 'ic_receivable', 100]]}]]]
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:
Mismatch reports never show which side is short.

x = [[entity, account, counterparty or None, amount]]. Rows with no counterparty, the entity itself as counterparty, or an account outside the pairs (ic_receivable/ic_payable, ic_sales/ic_purchases) are consolidated as-is. For each (entity, counterparty, pair) the left balance of entity toward counterparty is matched against the right balance of counterparty toward entity; min(left, right) is eliminated from both, residuals are consolidated and a mismatch [entity, counterparty, left account, left - right] is reported when they differ. Return {'consolidated': nonzero account totals, 'mismatches': in sorted key order}.

split: open-access