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

N = 1
observations = []
def solve(x):
    I = x['interval']
    B = x['bins']
    counts = [0] * B
    occ = [0] * B
    status = 'ok'
    for on, off in sorted(x['events']):
        b = on // I
        if 0 <= b < B:
            counts[b] += 1
        if off - on >= x['max_presence']:
            status = 'stuck-on'
        for k in range(B):
            lo, hi = k * I, (k + 1) * I
            occ[k] += max(0, min(off, hi) - max(on, lo))
    if not x['events'] and B * I >= x['no_activity']:
        status = 'no-activity'
    return {'counts': counts, 'occ_pct': [o // I * 100 for o in occ], 'status': status}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 30, 'bins': 5, 'events': [[336, 344], [10, 326], [5, 7], [370, 373]], 'max_presence': 100, 'no_activity': 240}, {'counts': [2, 0, 0, 0, 0], 'occ_pct': [73, 100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 30, 'bins': 5, 'events': [[-19, -16]], 'max_presence': 240, 'no_activity': 240}, {'counts': [0, 0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0, 0], 'status': 'ok'}), ({'interval': 30, 'bins': 5, 'events': [[89, 90], [67, 72], [123, 126], [-14, -9], [26, 34]], 'max_presence': 100, 'no_activity': 600}, {'counts': [1, 0, 2, 0, 1], 'occ_pct': [13, 13, 20, 0, 10], 'status': 'ok'}), ({'interval': 30, 'bins': 5, 'events': [[-5, 0], [39, 47], [68, 71], [75, 83], [88, 96], [111, 119], [121, 124], [126, 166]], 'max_presence': 180, 'no_activity': 240}, {'counts': [0, 1, 3, 1, 2], 'occ_pct': [0, 26, 43, 46, 90], 'status': 'ok'}), ({'interval': 60, 'bins': 5, 'events': [], 'max_presence': 240, 'no_activity': 60}, {'counts': [0, 0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0, 0], 'status': 'no-activity'})], [({'interval': 30, 'bins': 5, 'events': [[-16, -14], [26, 66], [101, 102], [103, 104], [112, 115]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 0, 0, 3, 0], 'occ_pct': [13, 100, 20, 16, 0], 'status': 'ok'}), ({'interval': 120, 'bins': 4, 'events': [], 'max_presence': 100, 'no_activity': 240}, {'counts': [0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 30, 'bins': 3, 'events': [[-4, -3]], 'max_presence': 100, 'no_activity': 600}, {'counts': [0, 0, 0], 'occ_pct': [0, 0, 0], 'status': 'ok'}), ({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'}), ({'interval': 120, 'bins': 2, 'events': [[6, 14], [70, 110], [123, 126], [24, 64], [152, 153], [177, 179]], 'max_presence': 100, 'no_activity': 120}, {'counts': [3, 3], 'occ_pct': [73, 5], 'status': 'ok'}), ({'interval': 60, 'bins': 4, 'events': [[4, 6], [34, 74]], 'max_presence': 180, 'no_activity': 60}, {'counts': [2, 0, 0, 0], 'occ_pct': [46, 23, 0, 0], 'status': 'ok'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'})], [({'interval': 30, 'bins': 2, 'events': [[-20, 20]], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [66, 0], 'status': 'ok'}), ({'interval': 60, 'bins': 4, 'events': [[3, 6], [29, 37], [42, 43], [47, 344], [357, 359], [392, 395], [426, 427], [436, 438]], 'max_presence': 100, 'no_activity': 240}, {'counts': [4, 0, 0, 0], 'occ_pct': [41, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 30, 'bins': 5, 'events': [[-13, 230], [264, 265], [303, 306], [342, 350]], 'max_presence': 100, 'no_activity': 600}, {'counts': [0, 0, 0, 0, 0], 'occ_pct': [100, 100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 30, 'bins': 3, 'events': [], 'max_presence': 180, 'no_activity': 240}, {'counts': [0, 0, 0], 'occ_pct': [0, 0, 0], 'status': 'ok'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 60, 'bins': 2, 'events': [[-9, -4], [26, 27], [47, 55]], 'max_presence': 240, 'no_activity': 600}, {'counts': [2, 0], 'occ_pct': [15, 0], 'status': 'ok'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'})], [({'interval': 60, 'bins': 4, 'events': [[-18, -15]], 'max_presence': 240, 'no_activity': 120}, {'counts': [0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0], 'status': 'ok'}), ({'interval': 60, 'bins': 4, 'events': [], 'max_presence': 240, 'no_activity': 600}, {'counts': [0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0], 'status': 'ok'}), ({'interval': 30, 'bins': 4, 'events': [[-10, -2], [26, 28], [54, 56], [73, 367], [392, 400], [406, 407], [439, 444]], 'max_presence': 240, 'no_activity': 120}, {'counts': [1, 1, 1, 0], 'occ_pct': [6, 6, 56, 100], 'status': 'stuck-on'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 120, 'bins': 5, 'events': [[10, 12], [52, 57], [59, 62], [69, 77]], 'max_presence': 180, 'no_activity': 600}, {'counts': [4, 0, 0, 0, 0], 'occ_pct': [15, 0, 0, 0, 0], 'status': 'ok'}), ({'interval': 30, 'bins': 3, 'events': [[-15, -10], [24, 380], [410, 415], [455, 495], [511, 516]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0], 'occ_pct': [20, 100, 100], 'status': 'stuck-on'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'})], [({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'}), ({'interval': 60, 'bins': 3, 'events': [], 'max_presence': 240, 'no_activity': 60}, {'counts': [0, 0, 0], 'occ_pct': [0, 0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 3, 'events': [[-3, 0], [13, 18]], 'max_presence': 180, 'no_activity': 600}, {'counts': [1, 0, 0], 'occ_pct': [8, 0, 0], 'status': 'ok'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 60, 'bins': 2, 'events': [[-19, 129], [148, 253], [263, 268], [288, 607], [646, 647]], 'max_presence': 180, 'no_activity': 60}, {'counts': [0, 0], 'occ_pct': [100, 100], 'status': 'stuck-on'}), ({'interval': 120, 'bins': 3, 'events': [[9, 14], [39, 41], [57, 97], [104, 144], [177, 182]], 'max_presence': 100, 'no_activity': 240}, {'counts': [4, 1, 0], 'occ_pct': [52, 24, 0], 'status': 'ok'}), ({'interval': 30, 'bins': 5, 'events': [[86, 88], [118, 121], [148, 150], [167, 169], [9, 49]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 0, 1, 1, 1], 'occ_pct': [70, 63, 6, 6, 10], 'status': 'ok'})]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check('timing oracle' + ' %d' % i, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

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

N = 1
observations = []
def solve(x):
    I = x['interval']
    B = x['bins']
    counts = [0] * B
    occ = [0] * B
    status = 'ok'
    for on, off in sorted(x['events']):
        b = on // I
        if 0 <= b < B:
            counts[b] += 1
        if off - on >= x['max_presence']:
            status = 'stuck-on'
        for k in range(B):
            lo, hi = k * I, (k + 1) * I
            occ[k] += max(0, min(off, hi) - max(on, lo))
    if not x['events'] and B * I >= x['no_activity']:
        status = 'no-activity'
    return {'counts': counts, 'occ_pct': [round(o * 100 / I) for o in occ], 'status': status}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 30, 'bins': 5, 'events': [[336, 344], [10, 326], [5, 7], [370, 373]], 'max_presence': 100, 'no_activity': 240}, {'counts': [2, 0, 0, 0, 0], 'occ_pct': [73, 100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 30, 'bins': 5, 'events': [[-19, -16]], 'max_presence': 240, 'no_activity': 240}, {'counts': [0, 0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0, 0], 'status': 'ok'}), ({'interval': 30, 'bins': 5, 'events': [[89, 90], [67, 72], [123, 126], [-14, -9], [26, 34]], 'max_presence': 100, 'no_activity': 600}, {'counts': [1, 0, 2, 0, 1], 'occ_pct': [13, 13, 20, 0, 10], 'status': 'ok'}), ({'interval': 30, 'bins': 5, 'events': [[-5, 0], [39, 47], [68, 71], [75, 83], [88, 96], [111, 119], [121, 124], [126, 166]], 'max_presence': 180, 'no_activity': 240}, {'counts': [0, 1, 3, 1, 2], 'occ_pct': [0, 26, 43, 46, 90], 'status': 'ok'}), ({'interval': 60, 'bins': 5, 'events': [], 'max_presence': 240, 'no_activity': 60}, {'counts': [0, 0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0, 0], 'status': 'no-activity'})], [({'interval': 30, 'bins': 5, 'events': [[-16, -14], [26, 66], [101, 102], [103, 104], [112, 115]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 0, 0, 3, 0], 'occ_pct': [13, 100, 20, 16, 0], 'status': 'ok'}), ({'interval': 120, 'bins': 4, 'events': [], 'max_presence': 100, 'no_activity': 240}, {'counts': [0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 30, 'bins': 3, 'events': [[-4, -3]], 'max_presence': 100, 'no_activity': 600}, {'counts': [0, 0, 0], 'occ_pct': [0, 0, 0], 'status': 'ok'}), ({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'}), ({'interval': 120, 'bins': 2, 'events': [[6, 14], [70, 110], [123, 126], [24, 64], [152, 153], [177, 179]], 'max_presence': 100, 'no_activity': 120}, {'counts': [3, 3], 'occ_pct': [73, 5], 'status': 'ok'}), ({'interval': 60, 'bins': 4, 'events': [[4, 6], [34, 74]], 'max_presence': 180, 'no_activity': 60}, {'counts': [2, 0, 0, 0], 'occ_pct': [46, 23, 0, 0], 'status': 'ok'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'})], [({'interval': 30, 'bins': 2, 'events': [[-20, 20]], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [66, 0], 'status': 'ok'}), ({'interval': 60, 'bins': 4, 'events': [[3, 6], [29, 37], [42, 43], [47, 344], [357, 359], [392, 395], [426, 427], [436, 438]], 'max_presence': 100, 'no_activity': 240}, {'counts': [4, 0, 0, 0], 'occ_pct': [41, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 30, 'bins': 5, 'events': [[-13, 230], [264, 265], [303, 306], [342, 350]], 'max_presence': 100, 'no_activity': 600}, {'counts': [0, 0, 0, 0, 0], 'occ_pct': [100, 100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 30, 'bins': 3, 'events': [], 'max_presence': 180, 'no_activity': 240}, {'counts': [0, 0, 0], 'occ_pct': [0, 0, 0], 'status': 'ok'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 60, 'bins': 2, 'events': [[-9, -4], [26, 27], [47, 55]], 'max_presence': 240, 'no_activity': 600}, {'counts': [2, 0], 'occ_pct': [15, 0], 'status': 'ok'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'})], [({'interval': 60, 'bins': 4, 'events': [[-18, -15]], 'max_presence': 240, 'no_activity': 120}, {'counts': [0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0], 'status': 'ok'}), ({'interval': 60, 'bins': 4, 'events': [], 'max_presence': 240, 'no_activity': 600}, {'counts': [0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0], 'status': 'ok'}), ({'interval': 30, 'bins': 4, 'events': [[-10, -2], [26, 28], [54, 56], [73, 367], [392, 400], [406, 407], [439, 444]], 'max_presence': 240, 'no_activity': 120}, {'counts': [1, 1, 1, 0], 'occ_pct': [6, 6, 56, 100], 'status': 'stuck-on'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 120, 'bins': 5, 'events': [[10, 12], [52, 57], [59, 62], [69, 77]], 'max_presence': 180, 'no_activity': 600}, {'counts': [4, 0, 0, 0, 0], 'occ_pct': [15, 0, 0, 0, 0], 'status': 'ok'}), ({'interval': 30, 'bins': 3, 'events': [[-15, -10], [24, 380], [410, 415], [455, 495], [511, 516]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0], 'occ_pct': [20, 100, 100], 'status': 'stuck-on'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'})], [({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'}), ({'interval': 60, 'bins': 3, 'events': [], 'max_presence': 240, 'no_activity': 60}, {'counts': [0, 0, 0], 'occ_pct': [0, 0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 3, 'events': [[-3, 0], [13, 18]], 'max_presence': 180, 'no_activity': 600}, {'counts': [1, 0, 0], 'occ_pct': [8, 0, 0], 'status': 'ok'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 60, 'bins': 2, 'events': [[-19, 129], [148, 253], [263, 268], [288, 607], [646, 647]], 'max_presence': 180, 'no_activity': 60}, {'counts': [0, 0], 'occ_pct': [100, 100], 'status': 'stuck-on'}), ({'interval': 120, 'bins': 3, 'events': [[9, 14], [39, 41], [57, 97], [104, 144], [177, 182]], 'max_presence': 100, 'no_activity': 240}, {'counts': [4, 1, 0], 'occ_pct': [52, 24, 0], 'status': 'ok'}), ({'interval': 30, 'bins': 5, 'events': [[86, 88], [118, 121], [148, 150], [167, 169], [9, 49]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 0, 1, 1, 1], 'occ_pct': [70, 63, 6, 6, 10], 'status': 'ok'})]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check('timing oracle' + ' %d' % i, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
Loop detector count and occupancy binning returns a wrong result when occupancy percent is scaled after integer division.

Input {interval s, bins, events: [[on, off]] seconds relative to period start (on may be negative), max_presence, no_activity}. A vehicle is counted in the bin of its on time if inside the period; occupied time is split across bins by overlap; occupancy percent is floor(occupied*100/interval). Status is 'stuck-on' if any presence lasts >= max_presence, 'no-activity' if there are no events and the period (bins*interval) is >= no_activity, else 'ok'. Return {counts, occ_pct, status}.

split: open-access


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

N = 1
observations = []
def solve(x):
    I = x['interval']
    B = x['bins']
    counts = [0] * B
    occ = [0] * B
    status = 'ok'
    for on, off in sorted(x['events']):
        b = on // I
        if 0 <= b < B:
            counts[b] += 1
        if off - on >= x['max_presence']:
            status = 'stuck-on'
        for k in range(B):
            lo, hi = k * I, (k + 1) * I
            occ[k] += max(0, min(off, hi) - max(on, lo))
    if not x['events'] and B * I > x['no_activity']:
        status = 'no-activity'
    return {'counts': counts, 'occ_pct': [o * 100 // I for o in occ], 'status': status}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'interval': 60, 'bins': 3, 'events': [[-14, -11], [-3, 37], [69, 71]], 'max_presence': 180, 'no_activity': 600}, {'counts': [0, 1, 0], 'occ_pct': [61, 3, 0], 'status': 'ok'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 30, 'bins': 2, 'events': [], 'max_presence': 240, 'no_activity': 60}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 120, 'bins': 2, 'events': [], 'max_presence': 240, 'no_activity': 240}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'}), ({'interval': 120, 'bins': 4, 'events': [], 'max_presence': 100, 'no_activity': 120}, {'counts': [0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [[3, 11], [30, 38], [70, 110]], 'max_presence': 240, 'no_activity': 120}, {'counts': [2, 1], 'occ_pct': [26, 66], 'status': 'ok'})], [({'interval': 120, 'bins': 4, 'events': [[5, 8], [18, 26], [35, 36]], 'max_presence': 180, 'no_activity': 60}, {'counts': [3, 0, 0, 0], 'occ_pct': [10, 0, 0, 0], 'status': 'ok'}), ({'interval': 120, 'bins': 5, 'events': [], 'max_presence': 240, 'no_activity': 120}, {'counts': [0, 0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0, 0], 'status': 'no-activity'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 120, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 240}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'}), ({'interval': 60, 'bins': 2, 'events': [[-3, 37]], 'max_presence': 100, 'no_activity': 60}, {'counts': [0, 0], 'occ_pct': [61, 0], 'status': 'ok'}), ({'interval': 60, 'bins': 4, 'events': [], 'max_presence': 240, 'no_activity': 240}, {'counts': [0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0], 'status': 'no-activity'})], [({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'}), ({'interval': 30, 'bins': 4, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0], 'status': 'no-activity'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 120, 'bins': 4, 'events': [[1, 3], [39, 41], [60, 100], [103, 108], [113, 115], [145, 148], [166, 206]], 'max_presence': 180, 'no_activity': 600}, {'counts': [5, 2, 0, 0], 'occ_pct': [42, 35, 0, 0], 'status': 'ok'}), ({'interval': 120, 'bins': 4, 'events': [[-13, 27], [39, 42], [62, 67], [86, 91], [99, 139]], 'max_presence': 100, 'no_activity': 240}, {'counts': [4, 0, 0, 0], 'occ_pct': [50, 15, 0, 0], 'status': 'ok'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 100, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 120, 'bins': 4, 'events': [], 'max_presence': 100, 'no_activity': 120}, {'counts': [0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'})], [({'interval': 120, 'bins': 2, 'events': [[47, 48], [125, 133], [10, 18], [-1, 4], [65, 105]], 'max_presence': 100, 'no_activity': 600}, {'counts': [3, 1], 'occ_pct': [44, 6], 'status': 'ok'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 4, 'events': [[-5, -4], [13, 16], [43, 48]], 'max_presence': 240, 'no_activity': 600}, {'counts': [2, 0, 0, 0], 'occ_pct': [13, 0, 0, 0], 'status': 'ok'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 120, 'bins': 2, 'events': [], 'max_presence': 240, 'no_activity': 240}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 120, 'bins': 4, 'events': [[-17, -15], [-6, -4], [15, 55], [93, 452], [482, 490], [491, 531]], 'max_presence': 240, 'no_activity': 120}, {'counts': [2, 0, 0, 0], 'occ_pct': [55, 100, 100, 76], 'status': 'stuck-on'}), ({'interval': 120, 'bins': 2, 'events': [], 'max_presence': 100, 'no_activity': 240}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'})], [({'interval': 60, 'bins': 5, 'events': [[-3, 385], [401, 554], [578, 618], [631, 671], [675, 677], [694, 702]], 'max_presence': 240, 'no_activity': 120}, {'counts': [0, 0, 0, 0, 0], 'occ_pct': [100, 100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 240, 'no_activity': 60}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 100, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 60, 'bins': 3, 'events': [[-15, -7], [33, 35], [38, 41]], 'max_presence': 100, 'no_activity': 240}, {'counts': [2, 0, 0], 'occ_pct': [8, 0, 0], 'status': 'ok'}), ({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'}), ({'interval': 120, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 240}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'})]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check('timing oracle' + ' %d' % i, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

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):
    I = x['interval']
    B = x['bins']
    counts = [0] * B
    occ = [0] * B
    status = 'ok'
    for on, off in sorted(x['events']):
        b = on // I
        if 0 <= b < B:
            counts[b] += 1
        if off - on >= x['max_presence']:
            status = 'stuck-on'
        for k in range(B):
            lo, hi = k * I, (k + 1) * I
            occ[k] += max(0, min(off, hi) - max(on, lo))
    if not x['events'] and B >= x['no_activity']:
        status = 'no-activity'
    return {'counts': counts, 'occ_pct': [o * 100 // I for o in occ], 'status': status}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'interval': 60, 'bins': 3, 'events': [[-14, -11], [-3, 37], [69, 71]], 'max_presence': 180, 'no_activity': 600}, {'counts': [0, 1, 0], 'occ_pct': [61, 3, 0], 'status': 'ok'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 30, 'bins': 2, 'events': [], 'max_presence': 240, 'no_activity': 60}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 120, 'bins': 2, 'events': [], 'max_presence': 240, 'no_activity': 240}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'}), ({'interval': 120, 'bins': 4, 'events': [], 'max_presence': 100, 'no_activity': 120}, {'counts': [0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [[3, 11], [30, 38], [70, 110]], 'max_presence': 240, 'no_activity': 120}, {'counts': [2, 1], 'occ_pct': [26, 66], 'status': 'ok'})], [({'interval': 120, 'bins': 4, 'events': [[5, 8], [18, 26], [35, 36]], 'max_presence': 180, 'no_activity': 60}, {'counts': [3, 0, 0, 0], 'occ_pct': [10, 0, 0, 0], 'status': 'ok'}), ({'interval': 120, 'bins': 5, 'events': [], 'max_presence': 240, 'no_activity': 120}, {'counts': [0, 0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0, 0], 'status': 'no-activity'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 120, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 240}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'}), ({'interval': 60, 'bins': 2, 'events': [[-3, 37]], 'max_presence': 100, 'no_activity': 60}, {'counts': [0, 0], 'occ_pct': [61, 0], 'status': 'ok'}), ({'interval': 60, 'bins': 4, 'events': [], 'max_presence': 240, 'no_activity': 240}, {'counts': [0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0], 'status': 'no-activity'})], [({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'}), ({'interval': 30, 'bins': 4, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0], 'status': 'no-activity'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 120, 'bins': 4, 'events': [[1, 3], [39, 41], [60, 100], [103, 108], [113, 115], [145, 148], [166, 206]], 'max_presence': 180, 'no_activity': 600}, {'counts': [5, 2, 0, 0], 'occ_pct': [42, 35, 0, 0], 'status': 'ok'}), ({'interval': 120, 'bins': 4, 'events': [[-13, 27], [39, 42], [62, 67], [86, 91], [99, 139]], 'max_presence': 100, 'no_activity': 240}, {'counts': [4, 0, 0, 0], 'occ_pct': [50, 15, 0, 0], 'status': 'ok'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 100, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 120, 'bins': 4, 'events': [], 'max_presence': 100, 'no_activity': 120}, {'counts': [0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'})], [({'interval': 120, 'bins': 2, 'events': [[47, 48], [125, 133], [10, 18], [-1, 4], [65, 105]], 'max_presence': 100, 'no_activity': 600}, {'counts': [3, 1], 'occ_pct': [44, 6], 'status': 'ok'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 4, 'events': [[-5, -4], [13, 16], [43, 48]], 'max_presence': 240, 'no_activity': 600}, {'counts': [2, 0, 0, 0], 'occ_pct': [13, 0, 0, 0], 'status': 'ok'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 120, 'bins': 2, 'events': [], 'max_presence': 240, 'no_activity': 240}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 120, 'bins': 4, 'events': [[-17, -15], [-6, -4], [15, 55], [93, 452], [482, 490], [491, 531]], 'max_presence': 240, 'no_activity': 120}, {'counts': [2, 0, 0, 0], 'occ_pct': [55, 100, 100, 76], 'status': 'stuck-on'}), ({'interval': 120, 'bins': 2, 'events': [], 'max_presence': 100, 'no_activity': 240}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'})], [({'interval': 60, 'bins': 5, 'events': [[-3, 385], [401, 554], [578, 618], [631, 671], [675, 677], [694, 702]], 'max_presence': 240, 'no_activity': 120}, {'counts': [0, 0, 0, 0, 0], 'occ_pct': [100, 100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 240, 'no_activity': 60}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 100, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 60, 'bins': 3, 'events': [[-15, -7], [33, 35], [38, 41]], 'max_presence': 100, 'no_activity': 240}, {'counts': [2, 0, 0], 'occ_pct': [8, 0, 0], 'status': 'ok'}), ({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'}), ({'interval': 120, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 240}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'})]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check('timing oracle' + ' %d' % i, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
Loop detector count and occupancy binning returns a wrong result when the no-activity limit is compared with the bin count.

Input {interval s, bins, events: [[on, off]] seconds relative to period start (on may be negative), max_presence, no_activity}. A vehicle is counted in the bin of its on time if inside the period; occupied time is split across bins by overlap; occupancy percent is floor(occupied*100/interval). Status is 'stuck-on' if any presence lasts >= max_presence, 'no-activity' if there are no events and the period (bins*interval) is >= no_activity, else 'ok'. Return {counts, occ_pct, status}.

split: open-access


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

N = 1
observations = []
def solve(x):
    I = x['interval']
    B = x['bins']
    counts = [0] * B
    occ = [0] * B
    status = 'ok'
    for on, off in sorted(x['events']):
        b = on // I
        if b < B:
            counts[b] += 1
        if off - on >= x['max_presence']:
            status = 'stuck-on'
        for k in range(B):
            lo, hi = k * I, (k + 1) * I
            occ[k] += max(0, min(off, hi) - max(on, lo))
    if not x['events'] and B * I >= x['no_activity']:
        status = 'no-activity'
    return {'counts': counts, 'occ_pct': [o * 100 // I for o in occ], 'status': status}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 3, 'events': [], 'max_presence': 100, 'no_activity': 60}, {'counts': [0, 0, 0], 'occ_pct': [0, 0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 4, 'events': [], 'max_presence': 100, 'no_activity': 240}, {'counts': [0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'}), ({'interval': 120, 'bins': 3, 'events': [], 'max_presence': 240, 'no_activity': 60}, {'counts': [0, 0, 0], 'occ_pct': [0, 0, 0], 'status': 'no-activity'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 60, 'bins': 3, 'events': [[-15, -14], [11, 19]], 'max_presence': 180, 'no_activity': 600}, {'counts': [1, 0, 0], 'occ_pct': [13, 0, 0], 'status': 'ok'}), ({'interval': 120, 'bins': 5, 'events': [[-14, 26], [43, 46], [71, 73]], 'max_presence': 180, 'no_activity': 240}, {'counts': [2, 0, 0, 0, 0], 'occ_pct': [25, 0, 0, 0, 0], 'status': 'ok'})], [({'interval': 60, 'bins': 5, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'}), ({'interval': 120, 'bins': 3, 'events': [[-2, 1], [37, 77], [91, 99], [130, 135]], 'max_presence': 180, 'no_activity': 60}, {'counts': [2, 1, 0], 'occ_pct': [40, 4, 0], 'status': 'ok'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 60, 'bins': 3, 'events': [], 'max_presence': 100, 'no_activity': 120}, {'counts': [0, 0, 0], 'occ_pct': [0, 0, 0], 'status': 'no-activity'}), ({'interval': 30, 'bins': 5, 'events': [], 'max_presence': 240, 'no_activity': 240}, {'counts': [0, 0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0, 0], 'status': 'ok'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 3, 'events': [[-2, 0], [1, 2], [36, 44], [74, 114], [143, 183], [203, 208], [246, 251]], 'max_presence': 100, 'no_activity': 240}, {'counts': [2, 1, 1], 'occ_pct': [15, 66, 61], 'status': 'ok'})], [({'interval': 120, 'bins': 2, 'events': [], 'max_presence': 240, 'no_activity': 60}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 3, 'events': [], 'max_presence': 180, 'no_activity': 600}, {'counts': [0, 0, 0], 'occ_pct': [0, 0, 0], 'status': 'ok'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 30, 'bins': 3, 'events': [], 'max_presence': 240, 'no_activity': 120}, {'counts': [0, 0, 0], 'occ_pct': [0, 0, 0], 'status': 'ok'}), ({'interval': 60, 'bins': 3, 'events': [[-10, 30], [34, 35], [51, 52]], 'max_presence': 240, 'no_activity': 120}, {'counts': [2, 0, 0], 'occ_pct': [53, 0, 0], 'status': 'ok'}), ({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'}), ({'interval': 60, 'bins': 4, 'events': [[-14, 26], [34, 37], [49, 446], [455, 458], [489, 490]], 'max_presence': 100, 'no_activity': 120}, {'counts': [2, 0, 0, 0], 'occ_pct': [66, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'})], [({'interval': 60, 'bins': 3, 'events': [], 'max_presence': 100, 'no_activity': 240}, {'counts': [0, 0, 0], 'occ_pct': [0, 0, 0], 'status': 'ok'}), ({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'}), ({'interval': 60, 'bins': 3, 'events': [], 'max_presence': 240, 'no_activity': 240}, {'counts': [0, 0, 0], 'occ_pct': [0, 0, 0], 'status': 'ok'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 30, 'bins': 4, 'events': [[-4, -3], [34, 39], [74, 114], [136, 141], [164, 169], [183, 191], [224, 229]], 'max_presence': 240, 'no_activity': 60}, {'counts': [0, 1, 1, 0], 'occ_pct': [0, 16, 53, 80], 'status': 'ok'}), ({'interval': 120, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 240}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 30, 'bins': 2, 'events': [[-8, 32], [68, 69], [90, 130], [132, 134], [165, 205], [216, 219], [243, 246], [269, 274]], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [100, 6], 'status': 'ok'})], [({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'}), ({'interval': 30, 'bins': 4, 'events': [], 'max_presence': 240, 'no_activity': 600}, {'counts': [0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0], 'status': 'ok'}), ({'interval': 30, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'ok'}), ({'interval': 60, 'bins': 3, 'events': [[-1, 7], [39, 79], [101, 103], [118, 121], [157, 158], [173, 178], [208, 248], [288, 293]], 'max_presence': 180, 'no_activity': 600}, {'counts': [1, 2, 2], 'occ_pct': [46, 38, 11], 'status': 'ok'}), ({'interval': 30, 'bins': 2, 'events': [], 'max_presence': 240, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'ok'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 3, 'events': [[-10, 114], [147, 152], [-18, -16]], 'max_presence': 100, 'no_activity': 60}, {'counts': [0, 0, 1], 'occ_pct': [100, 90, 8], 'status': 'stuck-on'})]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check('timing oracle' + ' %d' % i, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

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

N = 1
observations = []
def solve(x):
    I = x['interval']
    B = x['bins']
    counts = [0] * B
    occ = [0] * B
    status = 'ok'
    for on, off in sorted(x['events']):
        b = on // I
        if 0 < b < B:
            counts[b] += 1
        if off - on >= x['max_presence']:
            status = 'stuck-on'
        for k in range(B):
            lo, hi = k * I, (k + 1) * I
            occ[k] += max(0, min(off, hi) - max(on, lo))
    if not x['events'] and B * I >= x['no_activity']:
        status = 'no-activity'
    return {'counts': counts, 'occ_pct': [o * 100 // I for o in occ], 'status': status}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 3, 'events': [], 'max_presence': 100, 'no_activity': 60}, {'counts': [0, 0, 0], 'occ_pct': [0, 0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 4, 'events': [], 'max_presence': 100, 'no_activity': 240}, {'counts': [0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'}), ({'interval': 120, 'bins': 3, 'events': [], 'max_presence': 240, 'no_activity': 60}, {'counts': [0, 0, 0], 'occ_pct': [0, 0, 0], 'status': 'no-activity'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 60, 'bins': 3, 'events': [[-15, -14], [11, 19]], 'max_presence': 180, 'no_activity': 600}, {'counts': [1, 0, 0], 'occ_pct': [13, 0, 0], 'status': 'ok'}), ({'interval': 120, 'bins': 5, 'events': [[-14, 26], [43, 46], [71, 73]], 'max_presence': 180, 'no_activity': 240}, {'counts': [2, 0, 0, 0, 0], 'occ_pct': [25, 0, 0, 0, 0], 'status': 'ok'})], [({'interval': 60, 'bins': 5, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'}), ({'interval': 120, 'bins': 3, 'events': [[-2, 1], [37, 77], [91, 99], [130, 135]], 'max_presence': 180, 'no_activity': 60}, {'counts': [2, 1, 0], 'occ_pct': [40, 4, 0], 'status': 'ok'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 60, 'bins': 3, 'events': [], 'max_presence': 100, 'no_activity': 120}, {'counts': [0, 0, 0], 'occ_pct': [0, 0, 0], 'status': 'no-activity'}), ({'interval': 30, 'bins': 5, 'events': [], 'max_presence': 240, 'no_activity': 240}, {'counts': [0, 0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0, 0], 'status': 'ok'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 3, 'events': [[-2, 0], [1, 2], [36, 44], [74, 114], [143, 183], [203, 208], [246, 251]], 'max_presence': 100, 'no_activity': 240}, {'counts': [2, 1, 1], 'occ_pct': [15, 66, 61], 'status': 'ok'})], [({'interval': 120, 'bins': 2, 'events': [], 'max_presence': 240, 'no_activity': 60}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 3, 'events': [], 'max_presence': 180, 'no_activity': 600}, {'counts': [0, 0, 0], 'occ_pct': [0, 0, 0], 'status': 'ok'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 30, 'bins': 3, 'events': [], 'max_presence': 240, 'no_activity': 120}, {'counts': [0, 0, 0], 'occ_pct': [0, 0, 0], 'status': 'ok'}), ({'interval': 60, 'bins': 3, 'events': [[-10, 30], [34, 35], [51, 52]], 'max_presence': 240, 'no_activity': 120}, {'counts': [2, 0, 0], 'occ_pct': [53, 0, 0], 'status': 'ok'}), ({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'}), ({'interval': 60, 'bins': 4, 'events': [[-14, 26], [34, 37], [49, 446], [455, 458], [489, 490]], 'max_presence': 100, 'no_activity': 120}, {'counts': [2, 0, 0, 0], 'occ_pct': [66, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'})], [({'interval': 60, 'bins': 3, 'events': [], 'max_presence': 100, 'no_activity': 240}, {'counts': [0, 0, 0], 'occ_pct': [0, 0, 0], 'status': 'ok'}), ({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'}), ({'interval': 60, 'bins': 3, 'events': [], 'max_presence': 240, 'no_activity': 240}, {'counts': [0, 0, 0], 'occ_pct': [0, 0, 0], 'status': 'ok'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 30, 'bins': 4, 'events': [[-4, -3], [34, 39], [74, 114], [136, 141], [164, 169], [183, 191], [224, 229]], 'max_presence': 240, 'no_activity': 60}, {'counts': [0, 1, 1, 0], 'occ_pct': [0, 16, 53, 80], 'status': 'ok'}), ({'interval': 120, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 240}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 30, 'bins': 2, 'events': [[-8, 32], [68, 69], [90, 130], [132, 134], [165, 205], [216, 219], [243, 246], [269, 274]], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [100, 6], 'status': 'ok'})], [({'interval': 60, 'bins': 2, 'events': [[-5, 3], [58, 63], [70, 71]], 'max_presence': 180, 'no_activity': 120}, {'counts': [1, 1], 'occ_pct': [8, 6], 'status': 'ok'}), ({'interval': 30, 'bins': 4, 'events': [], 'max_presence': 240, 'no_activity': 600}, {'counts': [0, 0, 0, 0], 'occ_pct': [0, 0, 0, 0], 'status': 'ok'}), ({'interval': 30, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'ok'}), ({'interval': 60, 'bins': 3, 'events': [[-1, 7], [39, 79], [101, 103], [118, 121], [157, 158], [173, 178], [208, 248], [288, 293]], 'max_presence': 180, 'no_activity': 600}, {'counts': [1, 2, 2], 'occ_pct': [46, 38, 11], 'status': 'ok'}), ({'interval': 30, 'bins': 2, 'events': [], 'max_presence': 240, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'ok'}), ({'interval': 30, 'bins': 4, 'events': [[0, 180]], 'max_presence': 180, 'no_activity': 60}, {'counts': [1, 0, 0, 0], 'occ_pct': [100, 100, 100, 100], 'status': 'stuck-on'}), ({'interval': 60, 'bins': 2, 'events': [], 'max_presence': 180, 'no_activity': 120}, {'counts': [0, 0], 'occ_pct': [0, 0], 'status': 'no-activity'}), ({'interval': 60, 'bins': 3, 'events': [[-10, 114], [147, 152], [-18, -16]], 'max_presence': 100, 'no_activity': 60}, {'counts': [0, 0, 1], 'occ_pct': [100, 90, 8], 'status': 'stuck-on'})]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check('timing oracle' + ' %d' % i, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
Loop detector count and occupancy binning returns a wrong result when vehicles present before period start are counted in the last bin.

Input {interval s, bins, events: [[on, off]] seconds relative to period start (on may be negative), max_presence, no_activity}. A vehicle is counted in the bin of its on time if inside the period; occupied time is split across bins by overlap; occupancy percent is floor(occupied*100/interval). Status is 'stuck-on' if any presence lasts >= max_presence, 'no-activity' if there are no events and the period (bins*interval) is >= no_activity, else 'ok'. Return {counts, occ_pct, status}.

split: open-access


prompt:
Split failure detection returns a wrong result when the red occupancy window starts at yellow onset.

Input {cycles: [{green: [start, end), red_start, occ: [[on, off]]}]} with at least one cycle. Green occupancy ratio GOR = occupied seconds in green / green length; red occupancy ratio ROR5 = occupied seconds in the first 5 s after red start / 5. A cycle is a split failure when GOR >= 0.8 and ROR5 >= 0.8. Return {fails: indices, pct: floor(100*fails/cycles)}.

split: open-access


prompt:
Split failure detection returns a wrong result when split failure requires strictly more than 80 percent.

Input {cycles: [{green: [start, end), red_start, occ: [[on, off]]}]} with at least one cycle. Green occupancy ratio GOR = occupied seconds in green / green length; red occupancy ratio ROR5 = occupied seconds in the first 5 s after red start / 5. A cycle is a split failure when GOR >= 0.8 and ROR5 >= 0.8. Return {fails: indices, pct: floor(100*fails/cycles)}.

split: open-access


prompt:
Split failure detection returns a wrong result when occupancy before the window start is credited.

Input {cycles: [{green: [start, end), red_start, occ: [[on, off]]}]} with at least one cycle. Green occupancy ratio GOR = occupied seconds in green / green length; red occupancy ratio ROR5 = occupied seconds in the first 5 s after red start / 5. A cycle is a split failure when GOR >= 0.8 and ROR5 >= 0.8. Return {fails: indices, pct: floor(100*fails/cycles)}.

split: open-access


prompt:
Split failure detection returns a wrong result when green occupancy includes the yellow interval.

Input {cycles: [{green: [start, end), red_start, occ: [[on, off]]}]} with at least one cycle. Green occupancy ratio GOR = occupied seconds in green / green length; red occupancy ratio ROR5 = occupied seconds in the first 5 s after red start / 5. A cycle is a split failure when GOR >= 0.8 and ROR5 >= 0.8. Return {fails: indices, pct: floor(100*fails/cycles)}.

split: open-access


prompt:
Split failure detection returns a wrong result when the failure percentage divides before scaling.

Input {cycles: [{green: [start, end), red_start, occ: [[on, off]]}]} with at least one cycle. Green occupancy ratio GOR = occupied seconds in green / green length; red occupancy ratio ROR5 = occupied seconds in the first 5 s after red start / 5. A cycle is a split failure when GOR >= 0.8 and ROR5 >= 0.8. Return {fails: indices, pct: floor(100*fails/cycles)}.

split: open-access


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

N = 1
observations = []
def solve(x):
    ok = {(a, b) for a, b in x['compat']}
    faults = []
    live = []
    for ch, col, en in x['channels']:
        if not en:
            continue
        if len(col) > 1:
            faults.append('multi:%d' % ch)
        if col == '':
            faults.append('red-fail:%d' % ch)
        if 'G' in col or 'Y' in col:
            live.append(ch)
    live.sort()
    for i in range(len(live)):
        for j in range(i + 1, len(live)):
            if (live[i], live[j]) not in ok:
                faults.append('conflict:%d-%d' % (live[i], live[j]))
    for ch, tenths in x['yellow_durations']:
        if tenths < 27:
            faults.append('short-yellow:%d' % ch)
    return sorted(faults)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'channels': [[1, 'G', True], [2, 'R', True], [3, 'Y', True], [4, 'G', False]], 'compat': [[3, 1]], 'yellow_durations': [[2, 27]]}, []), ({'channels': [[1, 'GY', False], [2, '', True], [3, 'Y', True], [4, 'R', True], [5, 'G', True], [6, 'R', True]], 'compat': [[1, 3], [1, 4], [1, 5], [2, 4], [3, 6], [4, 5], [6, 4], [5, 6]], 'yellow_durations': [[3, 30], [5, 28]]}, ['conflict:3-5', 'red-fail:2']), ({'channels': [[1, '', True], [2, 'R', True], [3, 'R', True], [4, 'G', True]], 'compat': [[2, 1], [1, 4], [4, 2]], 'yellow_durations': [[4, 26]]}, ['red-fail:1', 'short-yellow:4']), ({'channels': [[1, 'RG', True], [2, 'R', True], [3, 'R', False], [4, 'R', True], [5, 'GY', True], [6, 'Y', True]], 'compat': [[2, 1], [3, 1], [5, 1], [3, 4], [5, 3], [6, 3], [6, 5]], 'yellow_durations': [[5, 27]]}, ['conflict:1-6', 'multi:1', 'multi:5']), ({'channels': [[1, '', True], [2, 'GY', True], [3, 'RG', True], [4, 'G', True], [5, 'GY', True], [6, 'R', True]], 'compat': [[1, 3], [4, 1], [2, 3], [3, 5], [5, 4]], 'yellow_durations': [[1, 28], [6, 30]]}, ['conflict:2-4', 'conflict:2-5', 'conflict:3-4', 'multi:2', 'multi:3', 'multi:5', 'red-fail:1']), ({'channels': [[1, 'GY', True], [2, 'G', True], [3, '', True]], 'compat': [], 'yellow_durations': [[1, 26]]}, ['conflict:1-2', 'multi:1', 'red-fail:3', 'short-yellow:1']), ({'channels': [[1, '', True], [2, 'GY', True], [3, 'RY', True], [4, 'Y', True], [5, 'R', True]], 'compat': [[1, 2], [1, 4], [2, 4], [5, 2], [3, 4], [5, 3]], 'yellow_durations': [[3, 25], [4, 25]]}, ['conflict:2-3', 'multi:2', 'multi:3', 'red-fail:1', 'short-yellow:3', 'short-yellow:4']), ({'channels': [[1, 'R', True], [2, '', True], [3, 'RY', True], [4, 'RG', True]], 'compat': [[3, 1], [4, 1], [4, 2]], 'yellow_durations': [[1, 26], [2, 26]]}, ['conflict:3-4', 'multi:3', 'multi:4', 'red-fail:2', 'short-yellow:1', 'short-yellow:2'])], [({'channels': [[1, 'R', True], [2, 'Y', True], [3, '', True]], 'compat': [[1, 3]], 'yellow_durations': [[1, 26], [2, 26], [3, 26]]}, ['red-fail:3', 'short-yellow:1', 'short-yellow:2', 'short-yellow:3']), ({'channels': [[1, 'R', True], [2, 'Y', False], [3, 'GY', True], [4, 'GY', True], [5, 'GY', True]], 'compat': [[2, 3], [2, 5], [4, 5]], 'yellow_durations': [[3, 27], [5, 30]]}, ['conflict:3-4', 'conflict:3-5', 'multi:3', 'multi:4', 'multi:5']), ({'channels': [[1, 'R', True], [2, 'RG', False], [3, 'Y', True], [4, 'R', True], [5, 'Y', False], [6, 'RY', True]], 'compat': [[5, 1], [3, 4], [3, 5], [4, 5], [5, 6]], 'yellow_durations': [[5, 30]]}, ['conflict:3-6', 'multi:6']), ({'channels': [[1, 'G', True], [2, 'R', True], [3, 'Y', True], [4, 'G', False]], 'compat': [[3, 1]], 'yellow_durations': [[2, 27]]}, []), ({'channels': [[1, 'Y', True], [2, 'GY', True], [3, 'GY', True], [4, 'G', True], [5, 'G', True], [6, 'Y', True]], 'compat': [[1, 2], [1, 4], [5, 1], [4, 2], [5, 2], [5, 3], [4, 6], [5, 6]], 'yellow_durations': [[4, 30], [6, 25]]}, ['conflict:1-3', 'conflict:1-6', 'conflict:2-3', 'conflict:2-6', 'conflict:3-4', 'conflict:3-6', 'conflict:4-5', 'multi:2', 'multi:3', 'short-yellow:6']), ({'channels': [[1, '', True], [2, 'R', True], [3, 'R', True], [4, 'R', True], [5, 'R', True], [6, 'R', True]], 'compat': [[1, 3], [5, 3], [3, 6], [5, 4], [6, 4]], 'yellow_durations': [[2, 28]]}, ['red-fail:1']), ({'channels': [[1, 'Y', True], [2, 'GY', True], [3, 'Y', True], [4, 'GY', True], [5, 'GY', True], [6, 'R', True]], 'compat': [[1, 2], [4, 2], [6, 2], [4, 3], [3, 5], [3, 6], [6, 5]], 'yellow_durations': [[2, 35], [4, 28]]}, ['conflict:1-3', 'conflict:1-4', 'conflict:1-5', 'conflict:2-3', 'conflict:2-5', 'conflict:4-5', 'multi:2', 'multi:4', 'multi:5']), ({'channels': [[1, 'GY', True], [2, 'G', True], [3, '', True]], 'compat': [], 'yellow_durations': [[1, 26]]}, ['conflict:1-2', 'multi:1', 'red-fail:3', 'short-yellow:1'])], [({'channels': [[1, 'R', True], [2, 'GY', True], [3, 'Y', True], [4, '', True], [5, 'RY', True], [6, 'R', False]], 'compat': [[4, 1], [1, 6], [4, 2], [4, 3], [5, 4]], 'yellow_durations': [[1, 26], [2, 26]]}, ['conflict:2-3', 'conflict:2-5', 'conflict:3-5', 'multi:2', 'multi:5', 'red-fail:4', 'short-yellow:1', 'short-yellow:2']), ({'channels': [[1, 'Y', True], [2, '', True], [3, 'Y', True], [4, 'R', True]], 'compat': [[3, 1], [4, 1], [3, 2], [4, 2]], 'yellow_durations': []}, ['red-fail:2']), ({'channels': [[1, 'G', True], [2, 'R', True], [3, 'Y', True], [4, 'G', False]], 'compat': [[3, 1]], 'yellow_durations': [[2, 27]]}, []), ({'channels': [[1, 'RG', True], [2, 'R', True], [3, 'R', True], [4, '', True], [5, 'G', True], [6, 'RY', True]], 'compat': [[5, 3]], 'yellow_durations': []}, ['conflict:1-5', 'conflict:1-6', 'conflict:5-6', 'multi:1', 'multi:6', 'red-fail:4']), ({'channels': [[1, 'R', True], [2, 'R', True], [3, 'GY', False], [4, 'R', False], [5, 'R', True], [6, 'RY', True]], 'compat': [[3, 1], [5, 1], [4, 3], [6, 3], [4, 5]], 'yellow_durations': [[2, 28]]}, ['multi:6']), ({'channels': [[1, 'GY', True], [2, 'G', True], [3, '', True]], 'compat': [], 'yellow_durations': [[1, 26]]}, ['conflict:1-2', 'multi:1', 'red-fail:3', 'short-yellow:1']), ({'channels': [[1, 'R', True], [2, 'RG', True], [3, '', True], [4, 'R', True]], 'compat': [], 'yellow_durations': [[1, 28], [3, 26], [4, 25]]}, ['multi:2', 'red-fail:3', 'short-yellow:3', 'short-yellow:4']), ({'channels': [[1, 'R', True], [2, 'GY', True], [3, 'GY', True], [4, 'GY', True]], 'compat': [[4, 3]], 'yellow_durations': []}, ['conflict:2-3', 'conflict:2-4', 'multi:2', 'multi:3', 'multi:4'])], [({'channels': [[1, 'G', True], [2, 'R', True], [3, '', True], [4, 'G', True], [5, 'R', True]], 'compat': [[4, 1], [5, 1], [3, 2], [3, 4]], 'yellow_durations': [[5, 25]]}, ['red-fail:3', 'short-yellow:5']), ({'channels': [[1, '', True], [2, 'Y', True], [3, 'GY', True], [4, 'Y', False]], 'compat': [[1, 2], [3, 1], [4, 1], [3, 4]], 'yellow_durations': [[4, 25]]}, ['conflict:2-3', 'multi:3', 'red-fail:1', 'short-yellow:4']), ({'channels': [[1, 'GY', True], [2, 'G', True], [3, '', True]], 'compat': [], 'yellow_durations': [[1, 26]]}, ['conflict:1-2', 'multi:1', 'red-fail:3', 'short-yellow:1']), ({'channels': [[1, 'R', True], [2, 'RY', True], [3, 'GY', True], [4, 'G', False], [5, 'RG', False], [6, 'R', True]], 'compat': [[3, 1], [5, 1], [3, 2], [2, 5], [6, 2], [6, 3]], 'yellow_durations': [[2, 25], [5, 35]]}, ['multi:2', 'multi:3', 'short-yellow:2']), ({'channels': [[1, 'G', True], [2, 'R', True], [3, 'Y', True], [4, 'G', False]], 'compat': [[3, 1]], 'yellow_durations': [[2, 27]]}, []), ({'channels': [[1, 'G', True], [2, 'GY', True], [3, 'R', True], [4, 'R', True], [5, 'R', True], [6, 'R', True]], 'compat': [[4, 1], [2, 6], [3, 4], [6, 5]], 'yellow_durations': [[1, 26], [2, 28]]}, ['conflict:1-2', 'multi:2', 'short-yellow:1']), ({'channels': [[1, 'Y', False], [2, '', True], [3, '', True], [4, '', True], [5, 'RG', True]], 'compat': [[1, 3], [1, 4], [1, 5], [3, 4], [5, 3], [4, 5]], 'yellow_durations': [[4, 28]]}, ['multi:5', 'red-fail:2', 'red-fail:3', 'red-fail:4']), ({'channels': [[1, 'R', True], [2, 'G', True], [3, '', True]], 'compat': [[1, 3]], 'yellow_durations': []}, ['red-fail:3'])], [({'channels': [[1, 'G', True], [2, 'R', True], [3, 'Y', True], [4, 'G', False]], 'compat': [[3, 1]], 'yellow_durations': [[2, 27]]}, []), ({'channels': [[1, 'GY', True], [2, 'R', True], [3, 'RY', True], [4, 'RY', True], [5, 'R', True], [6, 'RY', False]], 'compat': [[2, 1], [1, 3], [4, 1], [5, 1], [2, 3], [4, 2], [2, 6], [4, 5], [4, 6]], 'yellow_durations': []}, ['conflict:3-4', 'multi:1', 'multi:3', 'multi:4']), ({'channels': [[1, 'R', True], [2, '', True], [3, 'G', True]], 'compat': [[1, 2], [3, 1], [2, 3]], 'yellow_durations': [[2, 35], [3, 25]]}, ['red-fail:2', 'short-yellow:3']), ({'channels': [[1, 'R', True], [2, 'GY', False], [3, 'R', True]], 'compat': [[3, 1], [2, 3]], 'yellow_durations': [[1, 35]]}, []), ({'channels': [[1, 'GY', True], [2, 'G', True], [3, '', True]], 'compat': [], 'yellow_durations': [[1, 26]]}, ['conflict:1-2', 'multi:1', 'red-fail:3', 'short-yellow:1']), ({'channels': [[1, 'RG', True], [2, 'R', True], [3, 'R', True], [4, '', True], [5, 'R', True], [6, 'RG', True]], 'compat': [[4, 1], [3, 2], [2, 4], [6, 2], [3, 6]], 'yellow_durations': []}, ['conflict:1-6', 'multi:1', 'multi:6', 'red-fail:4']), ({'channels': [[1, '', True], [2, 'GY', True], [3, 'R', False], [4, 'RY', True]], 'compat': [[3, 1], [4, 2]], 'yellow_durations': [[1, 26], [3, 25]]}, ['multi:2', 'multi:4', 'red-fail:1', 'short-yellow:1', 'short-yellow:3']), ({'channels': [[1, 'RG', True], [2, '', True], [3, 'Y', True]], 'compat': [[1, 2], [1, 3], [3, 2]], 'yellow_durations': [[2, 35], [3, 28]]}, ['multi:1', 'red-fail:2'])]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check('timing oracle' + ' %d' % i, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

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

N = 1
observations = []
def solve(x):
    ok = {(max(a, b), min(a, b)) for a, b in x['compat']}
    faults = []
    live = []
    for ch, col, en in x['channels']:
        if not en:
            continue
        if len(col) > 1:
            faults.append('multi:%d' % ch)
        if col == '':
            faults.append('red-fail:%d' % ch)
        if 'G' in col or 'Y' in col:
            live.append(ch)
    live.sort()
    for i in range(len(live)):
        for j in range(i + 1, len(live)):
            if (live[i], live[j]) not in ok:
                faults.append('conflict:%d-%d' % (live[i], live[j]))
    for ch, tenths in x['yellow_durations']:
        if tenths < 27:
            faults.append('short-yellow:%d' % ch)
    return sorted(faults)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'channels': [[1, 'G', True], [2, 'R', True], [3, 'Y', True], [4, 'G', False]], 'compat': [[3, 1]], 'yellow_durations': [[2, 27]]}, []), ({'channels': [[1, 'GY', False], [2, '', True], [3, 'Y', True], [4, 'R', True], [5, 'G', True], [6, 'R', True]], 'compat': [[1, 3], [1, 4], [1, 5], [2, 4], [3, 6], [4, 5], [6, 4], [5, 6]], 'yellow_durations': [[3, 30], [5, 28]]}, ['conflict:3-5', 'red-fail:2']), ({'channels': [[1, '', True], [2, 'R', True], [3, 'R', True], [4, 'G', True]], 'compat': [[2, 1], [1, 4], [4, 2]], 'yellow_durations': [[4, 26]]}, ['red-fail:1', 'short-yellow:4']), ({'channels': [[1, 'RG', True], [2, 'R', True], [3, 'R', False], [4, 'R', True], [5, 'GY', True], [6, 'Y', True]], 'compat': [[2, 1], [3, 1], [5, 1], [3, 4], [5, 3], [6, 3], [6, 5]], 'yellow_durations': [[5, 27]]}, ['conflict:1-6', 'multi:1', 'multi:5']), ({'channels': [[1, '', True], [2, 'GY', True], [3, 'RG', True], [4, 'G', True], [5, 'GY', True], [6, 'R', True]], 'compat': [[1, 3], [4, 1], [2, 3], [3, 5], [5, 4]], 'yellow_durations': [[1, 28], [6, 30]]}, ['conflict:2-4', 'conflict:2-5', 'conflict:3-4', 'multi:2', 'multi:3', 'multi:5', 'red-fail:1']), ({'channels': [[1, 'GY', True], [2, 'G', True], [3, '', True]], 'compat': [], 'yellow_durations': [[1, 26]]}, ['conflict:1-2', 'multi:1', 'red-fail:3', 'short-yellow:1']), ({'channels': [[1, '', True], [2, 'GY', True], [3, 'RY', True], [4, 'Y', True], [5, 'R', True]], 'compat': [[1, 2], [1, 4], [2, 4], [5, 2], [3, 4], [5, 3]], 'yellow_durations': [[3, 25], [4, 25]]}, ['conflict:2-3', 'multi:2', 'multi:3', 'red-fail:1', 'short-yellow:3', 'short-yellow:4']), ({'channels': [[1, 'R', True], [2, '', True], [3, 'RY', True], [4, 'RG', True]], 'compat': [[3, 1], [4, 1], [4, 2]], 'yellow_durations': [[1, 26], [2, 26]]}, ['conflict:3-4', 'multi:3', 'multi:4', 'red-fail:2', 'short-yellow:1', 'short-yellow:2'])], [({'channels': [[1, 'R', True], [2, 'Y', True], [3, '', True]], 'compat': [[1, 3]], 'yellow_durations': [[1, 26], [2, 26], [3, 26]]}, ['red-fail:3', 'short-yellow:1', 'short-yellow:2', 'short-yellow:3']), ({'channels': [[1, 'R', True], [2, 'Y', False], [3, 'GY', True], [4, 'GY', True], [5, 'GY', True]], 'compat': [[2, 3], [2, 5], [4, 5]], 'yellow_durations': [[3, 27], [5, 30]]}, ['conflict:3-4', 'conflict:3-5', 'multi:3', 'multi:4', 'multi:5']), ({'channels': [[1, 'R', True], [2, 'RG', False], [3, 'Y', True], [4, 'R', True], [5, 'Y', False], [6, 'RY', True]], 'compat': [[5, 1], [3, 4], [3, 5], [4, 5], [5, 6]], 'yellow_durations': [[5, 30]]}, ['conflict:3-6', 'multi:6']), ({'channels': [[1, 'G', True], [2, 'R', True], [3, 'Y', True], [4, 'G', False]], 'compat': [[3, 1]], 'yellow_durations': [[2, 27]]}, []), ({'channels': [[1, 'Y', True], [2, 'GY', True], [3, 'GY', True], [4, 'G', True], [5, 'G', True], [6, 'Y', True]], 'compat': [[1, 2], [1, 4], [5, 1], [4, 2], [5, 2], [5, 3], [4, 6], [5, 6]], 'yellow_durations': [[4, 30], [6, 25]]}, ['conflict:1-3', 'conflict:1-6', 'conflict:2-3', 'conflict:2-6', 'conflict:3-4', 'conflict:3-6', 'conflict:4-5', 'multi:2', 'multi:3', 'short-yellow:6']), ({'channels': [[1, '', True], [2, 'R', True], [3, 'R', True], [4, 'R', True], [5, 'R', True], [6, 'R', True]], 'compat': [[1, 3], [5, 3], [3, 6], [5, 4], [6, 4]], 'yellow_durations': [[2, 28]]}, ['red-fail:1']), ({'channels': [[1, 'Y', True], [2, 'GY', True], [3, 'Y', True], [4, 'GY', True], [5, 'GY', True], [6, 'R', True]], 'compat': [[1, 2], [4, 2], [6, 2], [4, 3], [3, 5], [3, 6], [6, 5]], 'yellow_durations': [[2, 35], [4, 28]]}, ['conflict:1-3', 'conflict:1-4', 'conflict:1-5', 'conflict:2-3', 'conflict:2-5', 'conflict:4-5', 'multi:2', 'multi:4', 'multi:5']), ({'channels': [[1, 'GY', True], [2, 'G', True], [3, '', True]], 'compat': [], 'yellow_durations': [[1, 26]]}, ['conflict:1-2', 'multi:1', 'red-fail:3', 'short-yellow:1'])], [({'channels': [[1, 'R', True], [2, 'GY', True], [3, 'Y', True], [4, '', True], [5, 'RY', True], [6, 'R', False]], 'compat': [[4, 1], [1, 6], [4, 2], [4, 3], [5, 4]], 'yellow_durations': [[1, 26], [2, 26]]}, ['conflict:2-3', 'conflict:2-5', 'conflict:3-5', 'multi:2', 'multi:5', 'red-fail:4', 'short-yellow:1', 'short-yellow:2']), ({'channels': [[1, 'Y', True], [2, '', True], [3, 'Y', True], [4, 'R', True]], 'compat': [[3, 1], [4, 1], [3, 2], [4, 2]], 'yellow_durations': []}, ['red-fail:2']), ({'channels': [[1, 'G', True], [2, 'R', True], [3, 'Y', True], [4, 'G', False]], 'compat': [[3, 1]], 'yellow_durations': [[2, 27]]}, []), ({'channels': [[1, 'RG', True], [2, 'R', True], [3, 'R', True], [4, '', True], [5, 'G', True], [6, 'RY', True]], 'compat': [[5, 3]], 'yellow_durations': []}, ['conflict:1-5', 'conflict:1-6', 'conflict:5-6', 'multi:1', 'multi:6', 'red-fail:4']), ({'channels': [[1, 'R', True], [2, 'R', True], [3, 'GY', False], [4, 'R', False], [5, 'R', True], [6, 'RY', True]], 'compat': [[3, 1], [5, 1], [4, 3], [6, 3], [4, 5]], 'yellow_durations': [[2, 28]]}, ['multi:6']), ({'channels': [[1, 'GY', True], [2, 'G', True], [3, '', True]], 'compat': [], 'yellow_durations': [[1, 26]]}, ['conflict:1-2', 'multi:1', 'red-fail:3', 'short-yellow:1']), ({'channels': [[1, 'R', True], [2, 'RG', True], [3, '', True], [4, 'R', True]], 'compat': [], 'yellow_durations': [[1, 28], [3, 26], [4, 25]]}, ['multi:2', 'red-fail:3', 'short-yellow:3', 'short-yellow:4']), ({'channels': [[1, 'R', True], [2, 'GY', True], [3, 'GY', True], [4, 'GY', True]], 'compat': [[4, 3]], 'yellow_durations': []}, ['conflict:2-3', 'conflict:2-4', 'multi:2', 'multi:3', 'multi:4'])], [({'channels': [[1, 'G', True], [2, 'R', True], [3, '', True], [4, 'G', True], [5, 'R', True]], 'compat': [[4, 1], [5, 1], [3, 2], [3, 4]], 'yellow_durations': [[5, 25]]}, ['red-fail:3', 'short-yellow:5']), ({'channels': [[1, '', True], [2, 'Y', True], [3, 'GY', True], [4, 'Y', False]], 'compat': [[1, 2], [3, 1], [4, 1], [3, 4]], 'yellow_durations': [[4, 25]]}, ['conflict:2-3', 'multi:3', 'red-fail:1', 'short-yellow:4']), ({'channels': [[1, 'GY', True], [2, 'G', True], [3, '', True]], 'compat': [], 'yellow_durations': [[1, 26]]}, ['conflict:1-2', 'multi:1', 'red-fail:3', 'short-yellow:1']), ({'channels': [[1, 'R', True], [2, 'RY', True], [3, 'GY', True], [4, 'G', False], [5, 'RG', False], [6, 'R', True]], 'compat': [[3, 1], [5, 1], [3, 2], [2, 5], [6, 2], [6, 3]], 'yellow_durations': [[2, 25], [5, 35]]}, ['multi:2', 'multi:3', 'short-yellow:2']), ({'channels': [[1, 'G', True], [2, 'R', True], [3, 'Y', True], [4, 'G', False]], 'compat': [[3, 1]], 'yellow_durations': [[2, 27]]}, []), ({'channels': [[1, 'G', True], [2, 'GY', True], [3, 'R', True], [4, 'R', True], [5, 'R', True], [6, 'R', True]], 'compat': [[4, 1], [2, 6], [3, 4], [6, 5]], 'yellow_durations': [[1, 26], [2, 28]]}, ['conflict:1-2', 'multi:2', 'short-yellow:1']), ({'channels': [[1, 'Y', False], [2, '', True], [3, '', True], [4, '', True], [5, 'RG', True]], 'compat': [[1, 3], [1, 4], [1, 5], [3, 4], [5, 3], [4, 5]], 'yellow_durations': [[4, 28]]}, ['multi:5', 'red-fail:2', 'red-fail:3', 'red-fail:4']), ({'channels': [[1, 'R', True], [2, 'G', True], [3, '', True]], 'compat': [[1, 3]], 'yellow_durations': []}, ['red-fail:3'])], [({'channels': [[1, 'G', True], [2, 'R', True], [3, 'Y', True], [4, 'G', False]], 'compat': [[3, 1]], 'yellow_durations': [[2, 27]]}, []), ({'channels': [[1, 'GY', True], [2, 'R', True], [3, 'RY', True], [4, 'RY', True], [5, 'R', True], [6, 'RY', False]], 'compat': [[2, 1], [1, 3], [4, 1], [5, 1], [2, 3], [4, 2], [2, 6], [4, 5], [4, 6]], 'yellow_durations': []}, ['conflict:3-4', 'multi:1', 'multi:3', 'multi:4']), ({'channels': [[1, 'R', True], [2, '', True], [3, 'G', True]], 'compat': [[1, 2], [3, 1], [2, 3]], 'yellow_durations': [[2, 35], [3, 25]]}, ['red-fail:2', 'short-yellow:3']), ({'channels': [[1, 'R', True], [2, 'GY', False], [3, 'R', True]], 'compat': [[3, 1], [2, 3]], 'yellow_durations': [[1, 35]]}, []), ({'channels': [[1, 'GY', True], [2, 'G', True], [3, '', True]], 'compat': [], 'yellow_durations': [[1, 26]]}, ['conflict:1-2', 'multi:1', 'red-fail:3', 'short-yellow:1']), ({'channels': [[1, 'RG', True], [2, 'R', True], [3, 'R', True], [4, '', True], [5, 'R', True], [6, 'RG', True]], 'compat': [[4, 1], [3, 2], [2, 4], [6, 2], [3, 6]], 'yellow_durations': []}, ['conflict:1-6', 'multi:1', 'multi:6', 'red-fail:4']), ({'channels': [[1, '', True], [2, 'GY', True], [3, 'R', False], [4, 'RY', True]], 'compat': [[3, 1], [4, 2]], 'yellow_durations': [[1, 26], [3, 25]]}, ['multi:2', 'multi:4', 'red-fail:1', 'short-yellow:1', 'short-yellow:3']), ({'channels': [[1, 'RG', True], [2, '', True], [3, 'Y', True]], 'compat': [[1, 2], [1, 3], [3, 2]], 'yellow_durations': [[2, 35], [3, 28]]}, ['multi:1', 'red-fail:2'])]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check('timing oracle' + ' %d' % i, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
Conflict monitor fault scan returns a wrong result when compatible pairs are stored in the order given.

Input {channels: [[channel, lit colors string over R/Y/G, enabled]], compat: unordered compatible pairs, yellow_durations: [[channel, tenths]]}. Disabled channels are ignored entirely. A channel with more than one lit color is 'multi'; with none lit is 'red-fail'; any channel showing G or Y takes part in the conflict check, and every live pair not listed as compatible is 'conflict:a-b' (a<b). A completed yellow shorter than 2.7 s is 'short-yellow'. Return the sorted fault strings.

split: open-access


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

N = 1
observations = []
def solve(x):
    ok = {(min(a, b), max(a, b)) for a, b in x['compat']}
    faults = []
    live = []
    for ch, col, en in x['channels']:
        if not en:
            continue
        if len(col) > 1:
            faults.append('multi:%d' % ch)
        if col == '':
            faults.append('red-fail:%d' % ch)
        if 'G' in col:
            live.append(ch)
    live.sort()
    for i in range(len(live)):
        for j in range(i + 1, len(live)):
            if (live[i], live[j]) not in ok:
                faults.append('conflict:%d-%d' % (live[i], live[j]))
    for ch, tenths in x['yellow_durations']:
        if tenths < 27:
            faults.append('short-yellow:%d' % ch)
    return sorted(faults)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'channels': [[1, 'R', True], [2, 'R', True], [3, 'Y', True], [4, 'RY', False], [5, 'RY', True]], 'compat': [[1, 2], [1, 4], [2, 3], [2, 4], [4, 3], [5, 4]], 'yellow_durations': [[1, 25]]}, ['conflict:3-5', 'multi:5', 'short-yellow:1']), ({'channels': [[1, 'R', True], [2, '', True], [3, 'G', True], [4, 'G', True]], 'compat': [[2, 1], [1, 3], [3, 2]], 'yellow_durations': [[2, 25]]}, ['conflict:3-4', 'red-fail:2', 'short-yellow:2']), ({'channels': [[1, 'G', True], [2, 'R', True], [3, 'Y', True], [4, 'G', False]], 'compat': [[3, 1]], 'yellow_durations': [[2, 27]]}, []), ({'channels': [[1, 'RG', True], [2, 'Y', True], [3, 'RG', True], [4, 'GY', True], [5, '', False], [6, 'R', True]], 'compat': [[2, 1], [1, 4], [5, 2], [4, 3], [6, 3], [6, 5]], 'yellow_durations': [[2, 26], [5, 26]]}, ['conflict:1-3', 'conflict:2-3', 'conflict:2-4', 'multi:1', 'multi:3', 'multi:4', 'short-yellow:2', 'short-yellow:5']), ({'channels': [[1, 'R', True], [2, 'R', True], [3, 'R', False]], 'compat': [[2, 3]], 'yellow_durations': [[2, 26]]}, ['short-yellow:2']), ({'channels': [[1, 'GY', True], [2, 'Y', True], [3, 'R', True], [4, 'G', True], [5, 'R', True]], 'compat': [[4, 1], [4, 2], [5, 3]], 'yellow_durations': [[1, 30]]}, ['conflict:1-2', 'multi:1']), ({'channels': [[1, 'GY', True], [2, 'G', True], [3, '', True]], 'compat': [], 'yellow_durations': [[1, 26]]}, ['conflict:1-2', 'multi:1', 'red-fail:3', 'short-yellow:1']), ({'channels': [[1, 'RG', True], [2, 'R', True], [3, 'R', True], [4, 'Y', True]], 'compat': [[4, 1], [2, 3]], 'yellow_durations': [[4, 35]]}, ['multi:1'])], [({'channels': [[1, 'R', True], [2, 'RY', True], [3, 'RG', True], [4, 'RG', True], [5, 'RG', False], [6, 'RG', False]], 'compat': [[1, 4], [3, 6], [4, 6], [6, 5]], 'yellow_durations': [[6, 28]]}, ['conflict:2-3', 'conflict:2-4', 'conflict:3-4', 'multi:2', 'multi:3', 'multi:4']), ({'channels': [[1, 'G', True], [2, 'RG', False], [3, 'GY', True], [4, 'Y', True], [5, 'R', True]], 'compat': [[1, 4], [1, 5], [2, 5]], 'yellow_durations': [[2, 27], [4, 28]]}, ['conflict:1-3', 'conflict:3-4', 'multi:3']), ({'channels': [[1, 'G', True], [2, 'R', True], [3, 'Y', True], [4, 'G', False]], 'compat': [[3, 1]], 'yellow_durations': [[2, 27]]}, []), ({'channels': [[1, 'RY', True], [2, 'G', True], [3, 'GY', True], [4, '', True]], 'compat': [[4, 1], [3, 4]], 'yellow_durations': [[3, 27]]}, ['conflict:1-2', 'conflict:1-3', 'conflict:2-3', 'multi:1', 'multi:3', 'red-fail:4']), ({'channels': [[1, '', True], [2, 'G', False], [3, 'RG', True]], 'compat': [[2, 3]], 'yellow_durations': [[2, 27], [3, 30]]}, ['multi:3', 'red-fail:1']), ({'channels': [[1, 'GY', True], [2, 'G', True], [3, '', True]], 'compat': [], 'yellow_durations': [[1, 26]]}, ['conflict:1-2', 'multi:1', 'red-fail:3', 'short-yellow:1']), ({'channels': [[1, 'RY', False], [2, 'RY', True], [3, 'Y', True]], 'compat': [[2, 3]], 'yellow_durations': [[2, 28], [3, 30]]}, ['multi:2']), ({'channels': [[1, 'G', True], [2, 'RY', True], [3, 'R', True], [4, 'R', True]], 'compat': [[2, 1], [4, 1], [3, 2], [4, 3]], 'yellow_durations': [[2, 30], [4, 27]]}, ['multi:2'])], [({'channels': [[1, 'G', True], [2, 'R', True], [3, 'Y', True], [4, 'G', False]], 'compat': [[3, 1]], 'yellow_durations': [[2, 27]]}, []), ({'channels': [[1, 'RG', True], [2, 'R', True], [3, 'R', True], [4, 'R', True], [5, 'R', True]], 'compat': [[2, 3], [5, 2], [5, 4]], 'yellow_durations': [[3, 27], [4, 26], [5, 25]]}, ['multi:1', 'short-yellow:4', 'short-yellow:5']), ({'channels': [[1, 'R', True], [2, 'Y', False], [3, 'G', True], [4, 'G', True]], 'compat': [[1, 3], [1, 4], [2, 3], [2, 4]], 'yellow_durations': [[4, 28]]}, ['conflict:3-4']), ({'channels': [[1, 'G', True], [2, 'R', False], [3, 'RY', True], [4, 'RG', True]], 'compat': [[3, 2], [2, 4]], 'yellow_durations': [[3, 30]]}, ['conflict:1-3', 'conflict:1-4', 'conflict:3-4', 'multi:3', 'multi:4']), ({'channels': [[1, 'R', True], [2, 'GY', True], [3, 'R', True], [4, 'Y', True], [5, 'GY', True], [6, 'RG', True]], 'compat': [[1, 3], [1, 5], [6, 2], [4, 3], [6, 3], [4, 5], [6, 4], [5, 6]], 'yellow_durations': [[1, 28], [3, 27]]}, ['conflict:2-4', 'conflict:2-5', 'multi:2', 'multi:5', 'multi:6']), ({'channels': [[1, 'R', True], [2, 'R', False], [3, 'R', True], [4, '', False]], 'compat': [[4, 1], [4, 2], [3, 4]], 'yellow_durations': [[1, 25], [2, 28]]}, ['short-yellow:1']), ({'channels': [[1, 'GY', True], [2, 'G', True], [3, '', True]], 'compat': [], 'yellow_durations': [[1, 26]]}, ['conflict:1-2', 'multi:1', 'red-fail:3', 'short-yellow:1']), ({'channels': [[1, 'R', True], [2, 'GY', True], [3, 'Y', True], [4, 'R', True], [5, 'Y', True], [6, 'R', True]], 'compat': [[1, 2], [1, 4], [2, 3], [2, 5], [4, 5], [6, 4], [5, 6]], 'yellow_durations': [[5, 27]]}, ['conflict:3-5', 'multi:2'])], [({'channels': [[1, 'G', True], [2, 'R', True], [3, 'Y', True], [4, 'G', False]], 'compat': [[3, 1]], 'yellow_durations': [[2, 27]]}, []), ({'channels': [[1, 'GY', True], [2, 'G', True], [3, '', True]], 'compat': [], 'yellow_durations': [[1, 26]]}, ['conflict:1-2', 'multi:1', 'red-fail:3', 'short-yellow:1']), ({'channels': [[1, 'G', True], [2, 'Y', True], [3, '', True], [4, '', True]], 'compat': [[2, 1], [1, 3], [4, 1]], 'yellow_durations': [[4, 35]]}, ['red-fail:3', 'red-fail:4']), ({'channels': [[1, 'G', True], [2, 'R', True], [3, 'RG', True]], 'compat': [[1, 3]], 'yellow_durations': [[3, 27]]}, ['multi:3']), ({'channels': [[1, 'Y', True], [2, 'RG', True], [3, 'Y', True], [4, '', True]], 'compat': [[1, 2], [3, 4]], 'yellow_durations': [[3, 35]]}, ['conflict:1-3', 'conflict:2-3', 'multi:2', 'red-fail:4']), ({'channels': [[1, 'GY', True], [2, '', True], [3, 'R', True], [4, 'G', True], [5, 'R', False]], 'compat': [[1, 4], [5, 3]], 'yellow_durations': [[3, 30], [5, 27]]}, ['multi:1', 'red-fail:2']), ({'channels': [[1, 'G', False], [2, 'R', True], [3, 'RG', True], [4, 'R', True], [5, 'RY', True], [6, 'RY', True]], 'compat': [[2, 1], [1, 4], [5, 1], [4, 2], [5, 2], [4, 3], [5, 3], [4, 5]], 'yellow_durations': [[3, 25], [6, 35]]}, ['conflict:3-6', 'conflict:5-6', 'multi:3', 'multi:5', 'multi:6', 'short-yellow:3']), ({'channels': [[1, 'RY', True], [2, 'RG', False], [3, 'RY', True], [4, 'R', True]], 'compat': [[4, 1]], 'yellow_durations': [[2, 35]]}, ['conflict:1-3', 'multi:1', 'multi:3'])], [({'channels': [[1, 'G', True], [2, 'R', True], [3, 'Y', True], [4, 'G', False]], 'compat': [[3, 1]], 'yellow_durations': [[2, 27]]}, []), ({'channels': [[1, 'R', True], [2, 'Y', False], [3, 'R', True]], 'compat': [[2, 1]], 'yellow_durations': [[3, 25]]}, ['short-yellow:3']), ({'channels': [[1, 'GY', True], [2, 'R', False], [3, 'R', True]], 'compat': [[3, 1], [3, 2]], 'yellow_durations': [[1, 28]]}, ['multi:1']), ({'channels': [[1, 'RY', True], [2, 'R', True], [3, 'G', True]], 'compat': [[2, 1]], 'yellow_durations': [[2, 27]]}, ['conflict:1-3', 'multi:1']), ({'channels': [[1, 'GY', True], [2, 'G', True], [3, '', True]], 'compat': [], 'yellow_durations': [[1, 26]]}, ['conflict:1-2', 'multi:1', 'red-fail:3', 'short-yellow:1']), ({'channels': [[1, 'GY', True], [2, 'R', True], [3, '', True], [4, 'GY', True], [5, 'Y', True], [6, 'Y', False]], 'compat': [[4, 1], [5, 3], [5, 4]], 'yellow_durations': [[1, 30], [5, 28]]}, ['conflict:1-5', 'multi:1', 'multi:4', 'red-fail:3']), ({'channels': [[1, 'RY', True], [2, 'G', True], [3, 'R', True], [4, 'GY', True], [5, 'Y', True]], 'compat': [[1, 2], [3, 2]], 'yellow_durations': [[5, 28]]}, ['conflict:1-4', 'conflict:1-5', 'conflict:2-4', 'conflict:2-5', 'conflict:4-5', 'multi:1', 'multi:4']), ({'channels': [[1, 'RG', True], [2, '', True], [3, 'GY', True]], 'compat': [[2, 3]], 'yellow_durations': [[3, 26]]}, ['conflict:1-3', 'multi:1', 'multi:3', 'red-fail:2', 'short-yellow:3'])]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check('timing oracle' + ' %d' % i, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

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

N = 1
observations = []
def solve(x):
    ok = {(min(a, b), max(a, b)) for a, b in x['compat']}
    faults = []
    live = []
    for ch, col, en in x['channels']:
        if not en:
            continue
        if len(col) > 1:
            faults.append('multi:%d' % ch)
        if col == '':
            faults.append('red-fail:%d' % ch)
        if col in ('G', 'Y'):
            live.append(ch)
    live.sort()
    for i in range(len(live)):
        for j in range(i + 1, len(live)):
            if (live[i], live[j]) not in ok:
                faults.append('conflict:%d-%d' % (live[i], live[j]))
    for ch, tenths in x['yellow_durations']:
        if tenths < 27:
            faults.append('short-yellow:%d' % ch)
    return sorted(faults)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'channels': [[1, 'R', True], [2, 'R', True], [3, 'Y', True], [4, 'RY', False], [5, 'RY', True]], 'compat': [[1, 2], [1, 4], [2, 3], [2, 4], [4, 3], [5, 4]], 'yellow_durations': [[1, 25]]}, ['conflict:3-5', 'multi:5', 'short-yellow:1']), ({'channels': [[1, 'R', True], [2, '', True], [3, 'G', True], [4, 'G', True]], 'compat': [[2, 1], [1, 3], [3, 2]], 'yellow_durations': [[2, 25]]}, ['conflict:3-4', 'red-fail:2', 'short-yellow:2']), ({'channels': [[1, 'G', True], [2, 'R', True], [3, 'Y', True], [4, 'G', False]], 'compat': [[3, 1]], 'yellow_durations': [[2, 27]]}, []), ({'channels': [[1, 'RG', True], [2, 'Y', True], [3, 'RG', True], [4, 'GY', True], [5, '', False], [6, 'R', True]], 'compat': [[2, 1], [1, 4], [5, 2], [4, 3], [6, 3], [6, 5]], 'yellow_durations': [[2, 26], [5, 26]]}, ['conflict:1-3', 'conflict:2-3', 'conflict:2-4', 'multi:1', 'multi:3', 'multi:4', 'short-yellow:2', 'short-yellow:5']), ({'channels': [[1, 'R', True], [2, 'R', True], [3, 'R', False]], 'compat': [[2, 3]], 'yellow_durations': [[2, 26]]}, ['short-yellow:2']), ({'channels': [[1, 'GY', True], [2, 'Y', True], [3, 'R', True], [4, 'G', True], [5, 'R', True]], 'compat': [[4, 1], [4, 2], [5, 3]], 'yellow_durations': [[1, 30]]}, ['conflict:1-2', 'multi:1']), ({'channels': [[1, 'GY', True], [2, 'G', True], [3, '', True]], 'compat': [], 'yellow_durations': [[1, 26]]}, ['conflict:1-2', 'multi:1', 'red-fail:3', 'short-yellow:1']), ({'channels': [[1, 'RG', True], [2, 'R', True], [3, 'R', True], [4, 'Y', True]], 'compat': [[4, 1], [2, 3]], 'yellow_durations': [[4, 35]]}, ['multi:1'])], [({'channels': [[1, 'R', True], [2, 'RY', True], [3, 'RG', True], [4, 'RG', True], [5, 'RG', False], [6, 'RG', False]], 'compat': [[1, 4], [3, 6], [4, 6], [6, 5]], 'yellow_durations': [[6, 28]]}, ['conflict:2-3', 'conflict:2-4', 'conflict:3-4', 'multi:2', 'multi:3', 'multi:4']), ({'channels': [[1, 'G', True], [2, 'RG', False], [3, 'GY', True], [4, 'Y', True], [5, 'R', True]], 'compat': [[1, 4], [1, 5], [2, 5]], 'yellow_durations': [[2, 27], [4, 28]]}, ['conflict:1-3', 'conflict:3-4', 'multi:3']), ({'channels': [[1, 'G', True], [2, 'R', True], [3, 'Y', True], [4, 'G', False]], 'compat': [[3, 1]], 'yellow_durations': [[2, 27]]}, []), ({'channels': [[1, 'RY', True], [2, 'G', True], [3, 'GY', True], [4, '', True]], 'compat': [[4, 1], [3, 4]], 'yellow_durations': [[3, 27]]}, ['conflict:1-2', 'conflict:1-3', 'conflict:2-3', 'multi:1', 'multi:3', 'red-fail:4']), ({'channels': [[1, '', True], [2, 'G', False], [3, 'RG', True]], 'compat': [[2, 3]], 'yellow_durations': [[2, 27], [3, 30]]}, ['multi:3', 'red-fail:1']), ({'channels': [[1, 'GY', True], [2, 'G', True], [3, '', True]], 'compat': [], 'yellow_durations': [[1, 26]]}, ['conflict:1-2', 'multi:1', 'red-fail:3', 'short-yellow:1']), ({'channels': [[1, 'RY', False], [2, 'RY', True], [3, 'Y', True]], 'compat': [[2, 3]], 'yellow_durations': [[2, 28], [3, 30]]}, ['multi:2']), ({'channels': [[1, 'G', True], [2, 'RY', True], [3, 'R', True], [4, 'R', True]], 'compat': [[2, 1], [4, 1], [3, 2], [4, 3]], 'yellow_durations': [[2, 30], [4, 27]]}, ['multi:2'])], [({'channels': [[1, 'G', True], [2, 'R', True], [3, 'Y', True], [4, 'G', False]], 'compat': [[3, 1]], 'yellow_durations': [[2, 27]]}, []), ({'channels': [[1, 'RG', True], [2, 'R', True], [3, 'R', True], [4, 'R', True], [5, 'R', True]], 'compat': [[2, 3], [5, 2], [5, 4]], 'yellow_durations': [[3, 27], [4, 26], [5, 25]]}, ['multi:1', 'short-yellow:4', 'short-yellow:5']), ({'channels': [[1, 'R', True], [2, 'Y', False], [3, 'G', True], [4, 'G', True]], 'compat': [[1, 3], [1, 4], [2, 3], [2, 4]], 'yellow_durations': [[4, 28]]}, ['conflict:3-4']), ({'channels': [[1, 'G', True], [2, 'R', False], [3, 'RY', True], [4, 'RG', True]], 'compat': [[3, 2], [2, 4]], 'yellow_durations': [[3, 30]]}, ['conflict:1-3', 'conflict:1-4', 'conflict:3-4', 'multi:3', 'multi:4']), ({'channels': [[1, 'R', True], [2, 'GY', True], [3, 'R', True], [4, 'Y', True], [5, 'GY', True], [6, 'RG', True]], 'compat': [[1, 3], [1, 5], [6, 2], [4, 3], [6, 3], [4, 5], [6, 4], [5, 6]], 'yellow_durations': [[1, 28], [3, 27]]}, ['conflict:2-4', 'conflict:2-5', 'multi:2', 'multi:5', 'multi:6']), ({'channels': [[1, 'R', True], [2, 'R', False], [3, 'R', True], [4, '', False]], 'compat': [[4, 1], [4, 2], [3, 4]], 'yellow_durations': [[1, 25], [2, 28]]}, ['short-yellow:1']), ({'channels': [[1, 'GY', True], [2, 'G', True], [3, '', True]], 'compat': [], 'yellow_durations': [[1, 26]]}, ['conflict:1-2', 'multi:1', 'red-fail:3', 'short-yellow:1']), ({'channels': [[1, 'R', True], [2, 'GY', True], [3, 'Y', True], [4, 'R', True], [5, 'Y', True], [6, 'R', True]], 'compat': [[1, 2], [1, 4], [2, 3], [2, 5], [4, 5], [6, 4], [5, 6]], 'yellow_durations': [[5, 27]]}, ['conflict:3-5', 'multi:2'])], [({'channels': [[1, 'G', True], [2, 'R', True], [3, 'Y', True], [4, 'G', False]], 'compat': [[3, 1]], 'yellow_durations': [[2, 27]]}, []), ({'channels': [[1, 'GY', True], [2, 'G', True], [3, '', True]], 'compat': [], 'yellow_durations': [[1, 26]]}, ['conflict:1-2', 'multi:1', 'red-fail:3', 'short-yellow:1']), ({'channels': [[1, 'G', True], [2, 'Y', True], [3, '', True], [4, '', True]], 'compat': [[2, 1], [1, 3], [4, 1]], 'yellow_durations': [[4, 35]]}, ['red-fail:3', 'red-fail:4']), ({'channels': [[1, 'G', True], [2, 'R', True], [3, 'RG', True]], 'compat': [[1, 3]], 'yellow_durations': [[3, 27]]}, ['multi:3']), ({'channels': [[1, 'Y', True], [2, 'RG', True], [3, 'Y', True], [4, '', True]], 'compat': [[1, 2], [3, 4]], 'yellow_durations': [[3, 35]]}, ['conflict:1-3', 'conflict:2-3', 'multi:2', 'red-fail:4']), ({'channels': [[1, 'GY', True], [2, '', True], [3, 'R', True], [4, 'G', True], [5, 'R', False]], 'compat': [[1, 4], [5, 3]], 'yellow_durations': [[3, 30], [5, 27]]}, ['multi:1', 'red-fail:2']), ({'channels': [[1, 'G', False], [2, 'R', True], [3, 'RG', True], [4, 'R', True], [5, 'RY', True], [6, 'RY', True]], 'compat': [[2, 1], [1, 4], [5, 1], [4, 2], [5, 2], [4, 3], [5, 3], [4, 5]], 'yellow_durations': [[3, 25], [6, 35]]}, ['conflict:3-6', 'conflict:5-6', 'multi:3', 'multi:5', 'multi:6', 'short-yellow:3']), ({'channels': [[1, 'RY', True], [2, 'RG', False], [3, 'RY', True], [4, 'R', True]], 'compat': [[4, 1]], 'yellow_durations': [[2, 35]]}, ['conflict:1-3', 'multi:1', 'multi:3'])], [({'channels': [[1, 'G', True], [2, 'R', True], [3, 'Y', True], [4, 'G', False]], 'compat': [[3, 1]], 'yellow_durations': [[2, 27]]}, []), ({'channels': [[1, 'R', True], [2, 'Y', False], [3, 'R', True]], 'compat': [[2, 1]], 'yellow_durations': [[3, 25]]}, ['short-yellow:3']), ({'channels': [[1, 'GY', True], [2, 'R', False], [3, 'R', True]], 'compat': [[3, 1], [3, 2]], 'yellow_durations': [[1, 28]]}, ['multi:1']), ({'channels': [[1, 'RY', True], [2, 'R', True], [3, 'G', True]], 'compat': [[2, 1]], 'yellow_durations': [[2, 27]]}, ['conflict:1-3', 'multi:1']), ({'channels': [[1, 'GY', True], [2, 'G', True], [3, '', True]], 'compat': [], 'yellow_durations': [[1, 26]]}, ['conflict:1-2', 'multi:1', 'red-fail:3', 'short-yellow:1']), ({'channels': [[1, 'GY', True], [2, 'R', True], [3, '', True], [4, 'GY', True], [5, 'Y', True], [6, 'Y', False]], 'compat': [[4, 1], [5, 3], [5, 4]], 'yellow_durations': [[1, 30], [5, 28]]}, ['conflict:1-5', 'multi:1', 'multi:4', 'red-fail:3']), ({'channels': [[1, 'RY', True], [2, 'G', True], [3, 'R', True], [4, 'GY', True], [5, 'Y', True]], 'compat': [[1, 2], [3, 2]], 'yellow_durations': [[5, 28]]}, ['conflict:1-4', 'conflict:1-5', 'conflict:2-4', 'conflict:2-5', 'conflict:4-5', 'multi:1', 'multi:4']), ({'channels': [[1, 'RG', True], [2, '', True], [3, 'GY', True]], 'compat': [[2, 3]], 'yellow_durations': [[3, 26]]}, ['conflict:1-3', 'multi:1', 'multi:3', 'red-fail:2', 'short-yellow:3'])]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check('timing oracle' + ' %d' % i, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
Conflict monitor fault scan returns a wrong result when yellow indications are left out of the conflict check.

Input {channels: [[channel, lit colors string over R/Y/G, enabled]], compat: unordered compatible pairs, yellow_durations: [[channel, tenths]]}. Disabled channels are ignored entirely. A channel with more than one lit color is 'multi'; with none lit is 'red-fail'; any channel showing G or Y takes part in the conflict check, and every live pair not listed as compatible is 'conflict:a-b' (a<b). A completed yellow shorter than 2.7 s is 'short-yellow'. Return the sorted fault strings.

split: open-access