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

N = 1
observations = []
def solve(x):
    now = x['now']
    cand = [t for t in x['trains'] if t['eta'] - now <= x['lookahead_s']]
    cand.sort(key=lambda t: (t['cls'], t['sched'], t['id']))
    pairs = set()
    for a, b in x['conflicts']:
        pairs.add((a, b))
        pairs.add((b, a))
    granted = []
    routes = []
    for t in cand:
        if any(t['route'] == r or (t['route'], r) in pairs for r in routes[:1]):
            continue
        granted.append(t['id'])
        routes.append(t['route'])
    return granted
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('sampled regression 3', {'now': 100, 'lookahead_s': 60, 'trains': [{'id': '3A00', 'cls': 1, 'sched': 150, 'eta': 160, 'route': 'R1'}, {'id': '2A01', 'cls': 2, 'sched': 100, 'eta': 160, 'route': 'R4'}, {'id': '6A02', 'cls': 1, 'sched': 120, 'eta': 100, 'route': 'R4'}, {'id': '1A03', 'cls': 3, 'sched': 150, 'eta': 80, 'route': 'R1'}, {'id': '9A04', 'cls': 3, 'sched': 100, 'eta': 220, 'route': 'R4'}, {'id': '7A05', 'cls': 3, 'sched': 120, 'eta': 220, 'route': 'R3'}], 'conflicts': [['R2', 'R1'], ['R1', 'R5'], ['R3', 'R4']]}, ['6A02', '3A00']), ('boundary: conflict with an earlier grant', {'now': 100, 'lookahead_s': 60, 'conflicts': [['R1', 'R5']], 'trains': [{'id': '1A01', 'cls': 1, 'sched': 100, 'eta': 110, 'route': 'R1'}, {'id': '1A02', 'cls': 1, 'sched': 110, 'eta': 120, 'route': 'R4'}, {'id': '1A03', 'cls': 1, 'sched': 130, 'eta': 130, 'route': 'R5'}]}, ['1A01', '1A02']), ('sampled regression 21', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '8A00', 'cls': 3, 'sched': 150, 'eta': 180, 'route': 'R2'}, {'id': '7A01', 'cls': 1, 'sched': 150, 'eta': 100, 'route': 'R5'}, {'id': '3A02', 'cls': 3, 'sched': 150, 'eta': 160, 'route': 'R2'}], 'conflicts': [['R5', 'R1'], ['R4', 'R3'], ['R5', 'R4'], ['R1', 'R2']]}, ['7A01', '3A02']), ('boundary: eta exactly at the lookahead', {'now': 100, 'lookahead_s': 60, 'conflicts': [], 'trains': [{'id': '1A01', 'cls': 1, 'sched': 100, 'eta': 160, 'route': 'R1'}]}, ['1A01']), ('boundary: overdue train', {'now': 100, 'lookahead_s': 60, 'conflicts': [], 'trains': [{'id': '2A01', 'cls': 2, 'sched': 60, 'eta': 70, 'route': 'R2'}]}, ['2A01']), ('control 1', {'now': 100, 'lookahead_s': 60, 'trains': [{'id': '6A00', 'cls': 1, 'sched': 120, 'eta': 400, 'route': 'R1'}, {'id': '7A01', 'cls': 1, 'sched': 120, 'eta': 220, 'route': 'R2'}], 'conflicts': [['R4', 'R3'], ['R2', 'R3'], ['R4', 'R5'], ['R2', 'R1']]}, []), ('sampled regression 4', {'now': 100, 'lookahead_s': 120, 'trains': [{'id': '2A00', 'cls': 2, 'sched': 200, 'eta': 220, 'route': 'R3'}, {'id': '8A01', 'cls': 1, 'sched': 100, 'eta': 80, 'route': 'R5'}, {'id': '7A02', 'cls': 3, 'sched': 100, 'eta': 80, 'route': 'R2'}], 'conflicts': [['R1', 'R5'], ['R1', 'R2'], ['R3', 'R2'], ['R4', 'R5']]}, ['8A01', '2A00']), ('control 7', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '2A00', 'cls': 1, 'sched': 150, 'eta': 220, 'route': 'R5'}, {'id': '9A01', 'cls': 3, 'sched': 100, 'eta': 160, 'route': 'R1'}], 'conflicts': [['R3', 'R2']]}, ['9A01'])], [('sampled regression 4', {'now': 100, 'lookahead_s': 120, 'trains': [{'id': '2A00', 'cls': 2, 'sched': 200, 'eta': 220, 'route': 'R3'}, {'id': '8A01', 'cls': 1, 'sched': 100, 'eta': 80, 'route': 'R5'}, {'id': '7A02', 'cls': 3, 'sched': 100, 'eta': 80, 'route': 'R2'}], 'conflicts': [['R1', 'R5'], ['R1', 'R2'], ['R3', 'R2'], ['R4', 'R5']]}, ['8A01', '2A00']), ('boundary: conflict with an earlier grant', {'now': 100, 'lookahead_s': 60, 'conflicts': [['R1', 'R5']], 'trains': [{'id': '1A01', 'cls': 1, 'sched': 100, 'eta': 110, 'route': 'R1'}, {'id': '1A02', 'cls': 1, 'sched': 110, 'eta': 120, 'route': 'R4'}, {'id': '1A03', 'cls': 1, 'sched': 130, 'eta': 130, 'route': 'R5'}]}, ['1A01', '1A02']), ('sampled regression 45', {'now': 100, 'lookahead_s': 60, 'trains': [{'id': '6A00', 'cls': 3, 'sched': 150, 'eta': 180, 'route': 'R1'}, {'id': '2A01', 'cls': 3, 'sched': 120, 'eta': 80, 'route': 'R1'}, {'id': '2A02', 'cls': 1, 'sched': 120, 'eta': 400, 'route': 'R1'}, {'id': '5A03', 'cls': 1, 'sched': 120, 'eta': 160, 'route': 'R2'}, {'id': '9A04', 'cls': 3, 'sched': 200, 'eta': 130, 'route': 'R1'}, {'id': '5A05', 'cls': 1, 'sched': 120, 'eta': 130, 'route': 'R1'}], 'conflicts': [['R5', 'R4'], ['R3', 'R2'], ['R1', 'R5'], ['R3', 'R4']]}, ['5A03', '5A05']), ('control 30', {'now': 100, 'lookahead_s': 120, 'trains': [{'id': '8A00', 'cls': 2, 'sched': 120, 'eta': 400, 'route': 'R2'}, {'id': '5A01', 'cls': 2, 'sched': 200, 'eta': 100, 'route': 'R2'}, {'id': '9A02', 'cls': 2, 'sched': 120, 'eta': 220, 'route': 'R2'}, {'id': '7A03', 'cls': 2, 'sched': 150, 'eta': 180, 'route': 'R3'}, {'id': '3A04', 'cls': 2, 'sched': 100, 'eta': 180, 'route': 'R1'}, {'id': '9A05', 'cls': 2, 'sched': 150, 'eta': 130, 'route': 'R2'}], 'conflicts': [['R2', 'R1'], ['R4', 'R5'], ['R4', 'R3'], ['R1', 'R5']]}, ['3A04', '7A03']), ('boundary: class beats schedule', {'now': 100, 'lookahead_s': 60, 'conflicts': [['R1', 'R2']], 'trains': [{'id': '2A01', 'cls': 2, 'sched': 100, 'eta': 110, 'route': 'R1'}, {'id': '1A02', 'cls': 1, 'sched': 150, 'eta': 150, 'route': 'R2'}]}, ['1A02']), ('control 12', {'now': 100, 'lookahead_s': 120, 'trains': [{'id': '8A00', 'cls': 1, 'sched': 100, 'eta': 180, 'route': 'R3'}, {'id': '8A01', 'cls': 2, 'sched': 100, 'eta': 220, 'route': 'R2'}], 'conflicts': [['R3', 'R4']]}, ['8A00', '8A01']), ('control 15', {'now': 100, 'lookahead_s': 60, 'trains': [{'id': '2A00', 'cls': 2, 'sched': 200, 'eta': 180, 'route': 'R5'}, {'id': '6A01', 'cls': 3, 'sched': 150, 'eta': 80, 'route': 'R2'}, {'id': '7A02', 'cls': 3, 'sched': 100, 'eta': 130, 'route': 'R5'}, {'id': '5A03', 'cls': 3, 'sched': 120, 'eta': 160, 'route': 'R1'}], 'conflicts': [['R2', 'R1'], ['R4', 'R5'], ['R1', 'R5']]}, ['7A02', '6A01']), ('control 18', {'now': 100, 'lookahead_s': 120, 'trains': [{'id': '9A00', 'cls': 1, 'sched': 150, 'eta': 220, 'route': 'R4'}, {'id': '8A01', 'cls': 2, 'sched': 100, 'eta': 80, 'route': 'R3'}], 'conflicts': [['R5', 'R4'], ['R1', 'R2'], ['R4', 'R3']]}, ['9A00'])], [('sampled regression 6', {'now': 100, 'lookahead_s': 120, 'trains': [{'id': '2A00', 'cls': 3, 'sched': 120, 'eta': 130, 'route': 'R5'}, {'id': '5A01', 'cls': 3, 'sched': 150, 'eta': 160, 'route': 'R3'}, {'id': '6A02', 'cls': 1, 'sched': 120, 'eta': 100, 'route': 'R3'}, {'id': '5A03', 'cls': 1, 'sched': 120, 'eta': 180, 'route': 'R5'}, {'id': '2A04', 'cls': 1, 'sched': 200, 'eta': 130, 'route': 'R4'}, {'id': '6A05', 'cls': 2, 'sched': 200, 'eta': 220, 'route': 'R1'}], 'conflicts': [['R4', 'R3'], ['R2', 'R1'], ['R5', 'R1'], ['R3', 'R2']]}, ['5A03', '6A02']), ('boundary: conflict with an earlier grant', {'now': 100, 'lookahead_s': 60, 'conflicts': [['R1', 'R5']], 'trains': [{'id': '1A01', 'cls': 1, 'sched': 100, 'eta': 110, 'route': 'R1'}, {'id': '1A02', 'cls': 1, 'sched': 110, 'eta': 120, 'route': 'R4'}, {'id': '1A03', 'cls': 1, 'sched': 130, 'eta': 130, 'route': 'R5'}]}, ['1A01', '1A02']), ('sampled regression 21', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '8A00', 'cls': 3, 'sched': 150, 'eta': 180, 'route': 'R2'}, {'id': '7A01', 'cls': 1, 'sched': 150, 'eta': 100, 'route': 'R5'}, {'id': '3A02', 'cls': 3, 'sched': 150, 'eta': 160, 'route': 'R2'}], 'conflicts': [['R5', 'R1'], ['R4', 'R3'], ['R5', 'R4'], ['R1', 'R2']]}, ['7A01', '3A02']), ('control 53', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '1A00', 'cls': 3, 'sched': 120, 'eta': 100, 'route': 'R5'}, {'id': '9A01', 'cls': 2, 'sched': 200, 'eta': 100, 'route': 'R2'}, {'id': '3A02', 'cls': 1, 'sched': 150, 'eta': 400, 'route': 'R5'}, {'id': '5A03', 'cls': 1, 'sched': 200, 'eta': 80, 'route': 'R5'}], 'conflicts': [['R4', 'R5'], ['R4', 'R3'], ['R1', 'R2']]}, ['5A03', '9A01']), ('boundary: reverse-listed conflict granted in reverse', {'now': 100, 'lookahead_s': 60, 'conflicts': [['R3', 'R2']], 'trains': [{'id': '1A01', 'cls': 1, 'sched': 100, 'eta': 110, 'route': 'R3'}, {'id': '1A02', 'cls': 1, 'sched': 120, 'eta': 120, 'route': 'R2'}]}, ['1A01']), ('control 23', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '9A00', 'cls': 1, 'sched': 200, 'eta': 180, 'route': 'R4'}, {'id': '1A01', 'cls': 2, 'sched': 200, 'eta': 220, 'route': 'R2'}, {'id': '5A02', 'cls': 2, 'sched': 120, 'eta': 160, 'route': 'R5'}, {'id': '2A03', 'cls': 2, 'sched': 150, 'eta': 80, 'route': 'R2'}], 'conflicts': [['R1', 'R5'], ['R2', 'R1']]}, ['9A00', '5A02', '2A03']), ('sampled regression 26', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '9A00', 'cls': 1, 'sched': 120, 'eta': 160, 'route': 'R2'}, {'id': '7A01', 'cls': 2, 'sched': 100, 'eta': 220, 'route': 'R4'}, {'id': '2A02', 'cls': 1, 'sched': 150, 'eta': 180, 'route': 'R2'}, {'id': '1A03', 'cls': 3, 'sched': 150, 'eta': 130, 'route': 'R1'}, {'id': '7A04', 'cls': 2, 'sched': 120, 'eta': 100, 'route': 'R1'}, {'id': '1A05', 'cls': 2, 'sched': 150, 'eta': 400, 'route': 'R3'}], 'conflicts': [['R1', 'R5']]}, ['9A00', '7A04']), ('control 29', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '6A00', 'cls': 2, 'sched': 200, 'eta': 80, 'route': 'R5'}, {'id': '8A01', 'cls': 2, 'sched': 120, 'eta': 220, 'route': 'R1'}, {'id': '6A02', 'cls': 1, 'sched': 120, 'eta': 400, 'route': 'R1'}, {'id': '2A03', 'cls': 1, 'sched': 200, 'eta': 400, 'route': 'R3'}], 'conflicts': [['R5', 'R4'], ['R4', 'R3'], ['R2', 'R1'], ['R3', 'R2']]}, ['6A00'])], [('sampled regression 21', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '8A00', 'cls': 3, 'sched': 150, 'eta': 180, 'route': 'R2'}, {'id': '7A01', 'cls': 1, 'sched': 150, 'eta': 100, 'route': 'R5'}, {'id': '3A02', 'cls': 3, 'sched': 150, 'eta': 160, 'route': 'R2'}], 'conflicts': [['R5', 'R1'], ['R4', 'R3'], ['R5', 'R4'], ['R1', 'R2']]}, ['7A01', '3A02']), ('boundary: conflict with an earlier grant', {'now': 100, 'lookahead_s': 60, 'conflicts': [['R1', 'R5']], 'trains': [{'id': '1A01', 'cls': 1, 'sched': 100, 'eta': 110, 'route': 'R1'}, {'id': '1A02', 'cls': 1, 'sched': 110, 'eta': 120, 'route': 'R4'}, {'id': '1A03', 'cls': 1, 'sched': 130, 'eta': 130, 'route': 'R5'}]}, ['1A01', '1A02']), ('sampled regression 45', {'now': 100, 'lookahead_s': 60, 'trains': [{'id': '6A00', 'cls': 3, 'sched': 150, 'eta': 180, 'route': 'R1'}, {'id': '2A01', 'cls': 3, 'sched': 120, 'eta': 80, 'route': 'R1'}, {'id': '2A02', 'cls': 1, 'sched': 120, 'eta': 400, 'route': 'R1'}, {'id': '5A03', 'cls': 1, 'sched': 120, 'eta': 160, 'route': 'R2'}, {'id': '9A04', 'cls': 3, 'sched': 200, 'eta': 130, 'route': 'R1'}, {'id': '5A05', 'cls': 1, 'sched': 120, 'eta': 130, 'route': 'R1'}], 'conflicts': [['R5', 'R4'], ['R3', 'R2'], ['R1', 'R5'], ['R3', 'R4']]}, ['5A03', '5A05']), ('boundary: late running train keeps schedule order', {'now': 100, 'lookahead_s': 60, 'conflicts': [['R1', 'R2']], 'trains': [{'id': '1A01', 'cls': 1, 'sched': 100, 'eta': 150, 'route': 'R1'}, {'id': '1A02', 'cls': 1, 'sched': 120, 'eta': 105, 'route': 'R2'}]}, ['1A01']), ('boundary: eta exactly at the lookahead', {'now': 100, 'lookahead_s': 60, 'conflicts': [], 'trains': [{'id': '1A01', 'cls': 1, 'sched': 100, 'eta': 160, 'route': 'R1'}]}, ['1A01']), ('control 34', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '2A00', 'cls': 2, 'sched': 150, 'eta': 160, 'route': 'R5'}, {'id': '6A01', 'cls': 2, 'sched': 200, 'eta': 130, 'route': 'R5'}], 'conflicts': [['R4', 'R3']]}, ['2A00']), ('control 37', {'now': 100, 'lookahead_s': 60, 'trains': [{'id': '4A00', 'cls': 3, 'sched': 120, 'eta': 400, 'route': 'R4'}, {'id': '1A01', 'cls': 1, 'sched': 150, 'eta': 100, 'route': 'R4'}, {'id': '6A02', 'cls': 2, 'sched': 100, 'eta': 130, 'route': 'R4'}, {'id': '3A03', 'cls': 2, 'sched': 150, 'eta': 220, 'route': 'R5'}, {'id': '1A04', 'cls': 3, 'sched': 120, 'eta': 220, 'route': 'R2'}, {'id': '6A05', 'cls': 3, 'sched': 120, 'eta': 180, 'route': 'R1'}], 'conflicts': [['R1', 'R5'], ['R2', 'R1'], ['R3', 'R4']]}, ['1A01']), ('control 40', {'now': 100, 'lookahead_s': 60, 'trains': [{'id': '2A00', 'cls': 2, 'sched': 120, 'eta': 180, 'route': 'R4'}, {'id': '2A01', 'cls': 1, 'sched': 100, 'eta': 400, 'route': 'R4'}, {'id': '8A02', 'cls': 1, 'sched': 150, 'eta': 100, 'route': 'R3'}, {'id': '1A03', 'cls': 2, 'sched': 200, 'eta': 100, 'route': 'R3'}, {'id': '8A04', 'cls': 2, 'sched': 100, 'eta': 130, 'route': 'R4'}, {'id': '3A05', 'cls': 3, 'sched': 120, 'eta': 130, 'route': 'R5'}], 'conflicts': [['R1', 'R5'], ['R2', 'R3'], ['R1', 'R2'], ['R3', 'R4']]}, ['8A02', '3A05'])], [('sampled regression 25', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '2A00', 'cls': 1, 'sched': 150, 'eta': 160, 'route': 'R1'}, {'id': '7A01', 'cls': 1, 'sched': 150, 'eta': 80, 'route': 'R2'}, {'id': '2A02', 'cls': 1, 'sched': 150, 'eta': 160, 'route': 'R2'}, {'id': '7A03', 'cls': 1, 'sched': 200, 'eta': 400, 'route': 'R2'}, {'id': '1A04', 'cls': 2, 'sched': 120, 'eta': 100, 'route': 'R3'}], 'conflicts': [['R2', 'R3'], ['R4', 'R3']]}, ['2A00', '2A02']), ('boundary: conflict with an earlier grant', {'now': 100, 'lookahead_s': 60, 'conflicts': [['R1', 'R5']], 'trains': [{'id': '1A01', 'cls': 1, 'sched': 100, 'eta': 110, 'route': 'R1'}, {'id': '1A02', 'cls': 1, 'sched': 110, 'eta': 120, 'route': 'R4'}, {'id': '1A03', 'cls': 1, 'sched': 130, 'eta': 130, 'route': 'R5'}]}, ['1A01', '1A02']), ('sampled regression 21', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '8A00', 'cls': 3, 'sched': 150, 'eta': 180, 'route': 'R2'}, {'id': '7A01', 'cls': 1, 'sched': 150, 'eta': 100, 'route': 'R5'}, {'id': '3A02', 'cls': 3, 'sched': 150, 'eta': 160, 'route': 'R2'}], 'conflicts': [['R5', 'R1'], ['R4', 'R3'], ['R5', 'R4'], ['R1', 'R2']]}, ['7A01', '3A02']), ('control 19', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '2A00', 'cls': 2, 'sched': 150, 'eta': 80, 'route': 'R3'}, {'id': '8A01', 'cls': 1, 'sched': 120, 'eta': 160, 'route': 'R3'}, {'id': '7A02', 'cls': 2, 'sched': 120, 'eta': 220, 'route': 'R1'}, {'id': '8A03', 'cls': 1, 'sched': 200, 'eta': 80, 'route': 'R5'}], 'conflicts': [['R1', 'R2'], ['R2', 'R3'], ['R4', 'R5'], ['R3', 'R4']]}, ['8A01', '8A03']), ('boundary: eta exactly at the lookahead', {'now': 100, 'lookahead_s': 60, 'conflicts': [], 'trains': [{'id': '1A01', 'cls': 1, 'sched': 100, 'eta': 160, 'route': 'R1'}]}, ['1A01']), ('sampled regression 45', {'now': 100, 'lookahead_s': 60, 'trains': [{'id': '6A00', 'cls': 3, 'sched': 150, 'eta': 180, 'route': 'R1'}, {'id': '2A01', 'cls': 3, 'sched': 120, 'eta': 80, 'route': 'R1'}, {'id': '2A02', 'cls': 1, 'sched': 120, 'eta': 400, 'route': 'R1'}, {'id': '5A03', 'cls': 1, 'sched': 120, 'eta': 160, 'route': 'R2'}, {'id': '9A04', 'cls': 3, 'sched': 200, 'eta': 130, 'route': 'R1'}, {'id': '5A05', 'cls': 1, 'sched': 120, 'eta': 130, 'route': 'R1'}], 'conflicts': [['R5', 'R4'], ['R3', 'R2'], ['R1', 'R5'], ['R3', 'R4']]}, ['5A03', '5A05']), ('control 48', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '5A00', 'cls': 2, 'sched': 120, 'eta': 100, 'route': 'R1'}, {'id': '2A01', 'cls': 3, 'sched': 100, 'eta': 100, 'route': 'R3'}], 'conflicts': [['R4', 'R5'], ['R3', 'R4'], ['R1', 'R2']]}, ['5A00', '2A01']), ('control 51', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '5A00', 'cls': 3, 'sched': 150, 'eta': 220, 'route': 'R4'}, {'id': '6A01', 'cls': 1, 'sched': 120, 'eta': 400, 'route': 'R2'}, {'id': '3A02', 'cls': 2, 'sched': 120, 'eta': 160, 'route': 'R4'}, {'id': '6A03', 'cls': 2, 'sched': 100, 'eta': 400, 'route': 'R2'}], 'conflicts': [['R3', 'R2'], ['R4', 'R5']]}, ['3A02'])]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

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

N = 1
observations = []
def solve(x):
    now = x['now']
    cand = [t for t in x['trains'] if t['eta'] - now <= x['lookahead_s']]
    cand.sort(key=lambda t: (t['cls'], t['sched'], t['id']))
    pairs = set()
    for a, b in x['conflicts']:
        pairs.add((a, b))
        pairs.add((b, a))
    granted = []
    routes = []
    for t in cand:
        if any(t['route'] == r or (t['route'], r) in pairs for r in routes[-1:]):
            continue
        granted.append(t['id'])
        routes.append(t['route'])
    return granted
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('sampled regression 3', {'now': 100, 'lookahead_s': 60, 'trains': [{'id': '3A00', 'cls': 1, 'sched': 150, 'eta': 160, 'route': 'R1'}, {'id': '2A01', 'cls': 2, 'sched': 100, 'eta': 160, 'route': 'R4'}, {'id': '6A02', 'cls': 1, 'sched': 120, 'eta': 100, 'route': 'R4'}, {'id': '1A03', 'cls': 3, 'sched': 150, 'eta': 80, 'route': 'R1'}, {'id': '9A04', 'cls': 3, 'sched': 100, 'eta': 220, 'route': 'R4'}, {'id': '7A05', 'cls': 3, 'sched': 120, 'eta': 220, 'route': 'R3'}], 'conflicts': [['R2', 'R1'], ['R1', 'R5'], ['R3', 'R4']]}, ['6A02', '3A00']), ('boundary: conflict with an earlier grant', {'now': 100, 'lookahead_s': 60, 'conflicts': [['R1', 'R5']], 'trains': [{'id': '1A01', 'cls': 1, 'sched': 100, 'eta': 110, 'route': 'R1'}, {'id': '1A02', 'cls': 1, 'sched': 110, 'eta': 120, 'route': 'R4'}, {'id': '1A03', 'cls': 1, 'sched': 130, 'eta': 130, 'route': 'R5'}]}, ['1A01', '1A02']), ('sampled regression 21', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '8A00', 'cls': 3, 'sched': 150, 'eta': 180, 'route': 'R2'}, {'id': '7A01', 'cls': 1, 'sched': 150, 'eta': 100, 'route': 'R5'}, {'id': '3A02', 'cls': 3, 'sched': 150, 'eta': 160, 'route': 'R2'}], 'conflicts': [['R5', 'R1'], ['R4', 'R3'], ['R5', 'R4'], ['R1', 'R2']]}, ['7A01', '3A02']), ('boundary: eta exactly at the lookahead', {'now': 100, 'lookahead_s': 60, 'conflicts': [], 'trains': [{'id': '1A01', 'cls': 1, 'sched': 100, 'eta': 160, 'route': 'R1'}]}, ['1A01']), ('boundary: overdue train', {'now': 100, 'lookahead_s': 60, 'conflicts': [], 'trains': [{'id': '2A01', 'cls': 2, 'sched': 60, 'eta': 70, 'route': 'R2'}]}, ['2A01']), ('control 1', {'now': 100, 'lookahead_s': 60, 'trains': [{'id': '6A00', 'cls': 1, 'sched': 120, 'eta': 400, 'route': 'R1'}, {'id': '7A01', 'cls': 1, 'sched': 120, 'eta': 220, 'route': 'R2'}], 'conflicts': [['R4', 'R3'], ['R2', 'R3'], ['R4', 'R5'], ['R2', 'R1']]}, []), ('sampled regression 4', {'now': 100, 'lookahead_s': 120, 'trains': [{'id': '2A00', 'cls': 2, 'sched': 200, 'eta': 220, 'route': 'R3'}, {'id': '8A01', 'cls': 1, 'sched': 100, 'eta': 80, 'route': 'R5'}, {'id': '7A02', 'cls': 3, 'sched': 100, 'eta': 80, 'route': 'R2'}], 'conflicts': [['R1', 'R5'], ['R1', 'R2'], ['R3', 'R2'], ['R4', 'R5']]}, ['8A01', '2A00']), ('control 7', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '2A00', 'cls': 1, 'sched': 150, 'eta': 220, 'route': 'R5'}, {'id': '9A01', 'cls': 3, 'sched': 100, 'eta': 160, 'route': 'R1'}], 'conflicts': [['R3', 'R2']]}, ['9A01'])], [('sampled regression 4', {'now': 100, 'lookahead_s': 120, 'trains': [{'id': '2A00', 'cls': 2, 'sched': 200, 'eta': 220, 'route': 'R3'}, {'id': '8A01', 'cls': 1, 'sched': 100, 'eta': 80, 'route': 'R5'}, {'id': '7A02', 'cls': 3, 'sched': 100, 'eta': 80, 'route': 'R2'}], 'conflicts': [['R1', 'R5'], ['R1', 'R2'], ['R3', 'R2'], ['R4', 'R5']]}, ['8A01', '2A00']), ('boundary: conflict with an earlier grant', {'now': 100, 'lookahead_s': 60, 'conflicts': [['R1', 'R5']], 'trains': [{'id': '1A01', 'cls': 1, 'sched': 100, 'eta': 110, 'route': 'R1'}, {'id': '1A02', 'cls': 1, 'sched': 110, 'eta': 120, 'route': 'R4'}, {'id': '1A03', 'cls': 1, 'sched': 130, 'eta': 130, 'route': 'R5'}]}, ['1A01', '1A02']), ('sampled regression 45', {'now': 100, 'lookahead_s': 60, 'trains': [{'id': '6A00', 'cls': 3, 'sched': 150, 'eta': 180, 'route': 'R1'}, {'id': '2A01', 'cls': 3, 'sched': 120, 'eta': 80, 'route': 'R1'}, {'id': '2A02', 'cls': 1, 'sched': 120, 'eta': 400, 'route': 'R1'}, {'id': '5A03', 'cls': 1, 'sched': 120, 'eta': 160, 'route': 'R2'}, {'id': '9A04', 'cls': 3, 'sched': 200, 'eta': 130, 'route': 'R1'}, {'id': '5A05', 'cls': 1, 'sched': 120, 'eta': 130, 'route': 'R1'}], 'conflicts': [['R5', 'R4'], ['R3', 'R2'], ['R1', 'R5'], ['R3', 'R4']]}, ['5A03', '5A05']), ('control 30', {'now': 100, 'lookahead_s': 120, 'trains': [{'id': '8A00', 'cls': 2, 'sched': 120, 'eta': 400, 'route': 'R2'}, {'id': '5A01', 'cls': 2, 'sched': 200, 'eta': 100, 'route': 'R2'}, {'id': '9A02', 'cls': 2, 'sched': 120, 'eta': 220, 'route': 'R2'}, {'id': '7A03', 'cls': 2, 'sched': 150, 'eta': 180, 'route': 'R3'}, {'id': '3A04', 'cls': 2, 'sched': 100, 'eta': 180, 'route': 'R1'}, {'id': '9A05', 'cls': 2, 'sched': 150, 'eta': 130, 'route': 'R2'}], 'conflicts': [['R2', 'R1'], ['R4', 'R5'], ['R4', 'R3'], ['R1', 'R5']]}, ['3A04', '7A03']), ('boundary: class beats schedule', {'now': 100, 'lookahead_s': 60, 'conflicts': [['R1', 'R2']], 'trains': [{'id': '2A01', 'cls': 2, 'sched': 100, 'eta': 110, 'route': 'R1'}, {'id': '1A02', 'cls': 1, 'sched': 150, 'eta': 150, 'route': 'R2'}]}, ['1A02']), ('control 12', {'now': 100, 'lookahead_s': 120, 'trains': [{'id': '8A00', 'cls': 1, 'sched': 100, 'eta': 180, 'route': 'R3'}, {'id': '8A01', 'cls': 2, 'sched': 100, 'eta': 220, 'route': 'R2'}], 'conflicts': [['R3', 'R4']]}, ['8A00', '8A01']), ('control 15', {'now': 100, 'lookahead_s': 60, 'trains': [{'id': '2A00', 'cls': 2, 'sched': 200, 'eta': 180, 'route': 'R5'}, {'id': '6A01', 'cls': 3, 'sched': 150, 'eta': 80, 'route': 'R2'}, {'id': '7A02', 'cls': 3, 'sched': 100, 'eta': 130, 'route': 'R5'}, {'id': '5A03', 'cls': 3, 'sched': 120, 'eta': 160, 'route': 'R1'}], 'conflicts': [['R2', 'R1'], ['R4', 'R5'], ['R1', 'R5']]}, ['7A02', '6A01']), ('control 18', {'now': 100, 'lookahead_s': 120, 'trains': [{'id': '9A00', 'cls': 1, 'sched': 150, 'eta': 220, 'route': 'R4'}, {'id': '8A01', 'cls': 2, 'sched': 100, 'eta': 80, 'route': 'R3'}], 'conflicts': [['R5', 'R4'], ['R1', 'R2'], ['R4', 'R3']]}, ['9A00'])], [('sampled regression 6', {'now': 100, 'lookahead_s': 120, 'trains': [{'id': '2A00', 'cls': 3, 'sched': 120, 'eta': 130, 'route': 'R5'}, {'id': '5A01', 'cls': 3, 'sched': 150, 'eta': 160, 'route': 'R3'}, {'id': '6A02', 'cls': 1, 'sched': 120, 'eta': 100, 'route': 'R3'}, {'id': '5A03', 'cls': 1, 'sched': 120, 'eta': 180, 'route': 'R5'}, {'id': '2A04', 'cls': 1, 'sched': 200, 'eta': 130, 'route': 'R4'}, {'id': '6A05', 'cls': 2, 'sched': 200, 'eta': 220, 'route': 'R1'}], 'conflicts': [['R4', 'R3'], ['R2', 'R1'], ['R5', 'R1'], ['R3', 'R2']]}, ['5A03', '6A02']), ('boundary: conflict with an earlier grant', {'now': 100, 'lookahead_s': 60, 'conflicts': [['R1', 'R5']], 'trains': [{'id': '1A01', 'cls': 1, 'sched': 100, 'eta': 110, 'route': 'R1'}, {'id': '1A02', 'cls': 1, 'sched': 110, 'eta': 120, 'route': 'R4'}, {'id': '1A03', 'cls': 1, 'sched': 130, 'eta': 130, 'route': 'R5'}]}, ['1A01', '1A02']), ('sampled regression 21', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '8A00', 'cls': 3, 'sched': 150, 'eta': 180, 'route': 'R2'}, {'id': '7A01', 'cls': 1, 'sched': 150, 'eta': 100, 'route': 'R5'}, {'id': '3A02', 'cls': 3, 'sched': 150, 'eta': 160, 'route': 'R2'}], 'conflicts': [['R5', 'R1'], ['R4', 'R3'], ['R5', 'R4'], ['R1', 'R2']]}, ['7A01', '3A02']), ('control 53', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '1A00', 'cls': 3, 'sched': 120, 'eta': 100, 'route': 'R5'}, {'id': '9A01', 'cls': 2, 'sched': 200, 'eta': 100, 'route': 'R2'}, {'id': '3A02', 'cls': 1, 'sched': 150, 'eta': 400, 'route': 'R5'}, {'id': '5A03', 'cls': 1, 'sched': 200, 'eta': 80, 'route': 'R5'}], 'conflicts': [['R4', 'R5'], ['R4', 'R3'], ['R1', 'R2']]}, ['5A03', '9A01']), ('boundary: reverse-listed conflict granted in reverse', {'now': 100, 'lookahead_s': 60, 'conflicts': [['R3', 'R2']], 'trains': [{'id': '1A01', 'cls': 1, 'sched': 100, 'eta': 110, 'route': 'R3'}, {'id': '1A02', 'cls': 1, 'sched': 120, 'eta': 120, 'route': 'R2'}]}, ['1A01']), ('control 23', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '9A00', 'cls': 1, 'sched': 200, 'eta': 180, 'route': 'R4'}, {'id': '1A01', 'cls': 2, 'sched': 200, 'eta': 220, 'route': 'R2'}, {'id': '5A02', 'cls': 2, 'sched': 120, 'eta': 160, 'route': 'R5'}, {'id': '2A03', 'cls': 2, 'sched': 150, 'eta': 80, 'route': 'R2'}], 'conflicts': [['R1', 'R5'], ['R2', 'R1']]}, ['9A00', '5A02', '2A03']), ('sampled regression 26', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '9A00', 'cls': 1, 'sched': 120, 'eta': 160, 'route': 'R2'}, {'id': '7A01', 'cls': 2, 'sched': 100, 'eta': 220, 'route': 'R4'}, {'id': '2A02', 'cls': 1, 'sched': 150, 'eta': 180, 'route': 'R2'}, {'id': '1A03', 'cls': 3, 'sched': 150, 'eta': 130, 'route': 'R1'}, {'id': '7A04', 'cls': 2, 'sched': 120, 'eta': 100, 'route': 'R1'}, {'id': '1A05', 'cls': 2, 'sched': 150, 'eta': 400, 'route': 'R3'}], 'conflicts': [['R1', 'R5']]}, ['9A00', '7A04']), ('control 29', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '6A00', 'cls': 2, 'sched': 200, 'eta': 80, 'route': 'R5'}, {'id': '8A01', 'cls': 2, 'sched': 120, 'eta': 220, 'route': 'R1'}, {'id': '6A02', 'cls': 1, 'sched': 120, 'eta': 400, 'route': 'R1'}, {'id': '2A03', 'cls': 1, 'sched': 200, 'eta': 400, 'route': 'R3'}], 'conflicts': [['R5', 'R4'], ['R4', 'R3'], ['R2', 'R1'], ['R3', 'R2']]}, ['6A00'])], [('sampled regression 21', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '8A00', 'cls': 3, 'sched': 150, 'eta': 180, 'route': 'R2'}, {'id': '7A01', 'cls': 1, 'sched': 150, 'eta': 100, 'route': 'R5'}, {'id': '3A02', 'cls': 3, 'sched': 150, 'eta': 160, 'route': 'R2'}], 'conflicts': [['R5', 'R1'], ['R4', 'R3'], ['R5', 'R4'], ['R1', 'R2']]}, ['7A01', '3A02']), ('boundary: conflict with an earlier grant', {'now': 100, 'lookahead_s': 60, 'conflicts': [['R1', 'R5']], 'trains': [{'id': '1A01', 'cls': 1, 'sched': 100, 'eta': 110, 'route': 'R1'}, {'id': '1A02', 'cls': 1, 'sched': 110, 'eta': 120, 'route': 'R4'}, {'id': '1A03', 'cls': 1, 'sched': 130, 'eta': 130, 'route': 'R5'}]}, ['1A01', '1A02']), ('sampled regression 45', {'now': 100, 'lookahead_s': 60, 'trains': [{'id': '6A00', 'cls': 3, 'sched': 150, 'eta': 180, 'route': 'R1'}, {'id': '2A01', 'cls': 3, 'sched': 120, 'eta': 80, 'route': 'R1'}, {'id': '2A02', 'cls': 1, 'sched': 120, 'eta': 400, 'route': 'R1'}, {'id': '5A03', 'cls': 1, 'sched': 120, 'eta': 160, 'route': 'R2'}, {'id': '9A04', 'cls': 3, 'sched': 200, 'eta': 130, 'route': 'R1'}, {'id': '5A05', 'cls': 1, 'sched': 120, 'eta': 130, 'route': 'R1'}], 'conflicts': [['R5', 'R4'], ['R3', 'R2'], ['R1', 'R5'], ['R3', 'R4']]}, ['5A03', '5A05']), ('boundary: late running train keeps schedule order', {'now': 100, 'lookahead_s': 60, 'conflicts': [['R1', 'R2']], 'trains': [{'id': '1A01', 'cls': 1, 'sched': 100, 'eta': 150, 'route': 'R1'}, {'id': '1A02', 'cls': 1, 'sched': 120, 'eta': 105, 'route': 'R2'}]}, ['1A01']), ('boundary: eta exactly at the lookahead', {'now': 100, 'lookahead_s': 60, 'conflicts': [], 'trains': [{'id': '1A01', 'cls': 1, 'sched': 100, 'eta': 160, 'route': 'R1'}]}, ['1A01']), ('control 34', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '2A00', 'cls': 2, 'sched': 150, 'eta': 160, 'route': 'R5'}, {'id': '6A01', 'cls': 2, 'sched': 200, 'eta': 130, 'route': 'R5'}], 'conflicts': [['R4', 'R3']]}, ['2A00']), ('control 37', {'now': 100, 'lookahead_s': 60, 'trains': [{'id': '4A00', 'cls': 3, 'sched': 120, 'eta': 400, 'route': 'R4'}, {'id': '1A01', 'cls': 1, 'sched': 150, 'eta': 100, 'route': 'R4'}, {'id': '6A02', 'cls': 2, 'sched': 100, 'eta': 130, 'route': 'R4'}, {'id': '3A03', 'cls': 2, 'sched': 150, 'eta': 220, 'route': 'R5'}, {'id': '1A04', 'cls': 3, 'sched': 120, 'eta': 220, 'route': 'R2'}, {'id': '6A05', 'cls': 3, 'sched': 120, 'eta': 180, 'route': 'R1'}], 'conflicts': [['R1', 'R5'], ['R2', 'R1'], ['R3', 'R4']]}, ['1A01']), ('control 40', {'now': 100, 'lookahead_s': 60, 'trains': [{'id': '2A00', 'cls': 2, 'sched': 120, 'eta': 180, 'route': 'R4'}, {'id': '2A01', 'cls': 1, 'sched': 100, 'eta': 400, 'route': 'R4'}, {'id': '8A02', 'cls': 1, 'sched': 150, 'eta': 100, 'route': 'R3'}, {'id': '1A03', 'cls': 2, 'sched': 200, 'eta': 100, 'route': 'R3'}, {'id': '8A04', 'cls': 2, 'sched': 100, 'eta': 130, 'route': 'R4'}, {'id': '3A05', 'cls': 3, 'sched': 120, 'eta': 130, 'route': 'R5'}], 'conflicts': [['R1', 'R5'], ['R2', 'R3'], ['R1', 'R2'], ['R3', 'R4']]}, ['8A02', '3A05'])], [('sampled regression 25', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '2A00', 'cls': 1, 'sched': 150, 'eta': 160, 'route': 'R1'}, {'id': '7A01', 'cls': 1, 'sched': 150, 'eta': 80, 'route': 'R2'}, {'id': '2A02', 'cls': 1, 'sched': 150, 'eta': 160, 'route': 'R2'}, {'id': '7A03', 'cls': 1, 'sched': 200, 'eta': 400, 'route': 'R2'}, {'id': '1A04', 'cls': 2, 'sched': 120, 'eta': 100, 'route': 'R3'}], 'conflicts': [['R2', 'R3'], ['R4', 'R3']]}, ['2A00', '2A02']), ('boundary: conflict with an earlier grant', {'now': 100, 'lookahead_s': 60, 'conflicts': [['R1', 'R5']], 'trains': [{'id': '1A01', 'cls': 1, 'sched': 100, 'eta': 110, 'route': 'R1'}, {'id': '1A02', 'cls': 1, 'sched': 110, 'eta': 120, 'route': 'R4'}, {'id': '1A03', 'cls': 1, 'sched': 130, 'eta': 130, 'route': 'R5'}]}, ['1A01', '1A02']), ('sampled regression 21', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '8A00', 'cls': 3, 'sched': 150, 'eta': 180, 'route': 'R2'}, {'id': '7A01', 'cls': 1, 'sched': 150, 'eta': 100, 'route': 'R5'}, {'id': '3A02', 'cls': 3, 'sched': 150, 'eta': 160, 'route': 'R2'}], 'conflicts': [['R5', 'R1'], ['R4', 'R3'], ['R5', 'R4'], ['R1', 'R2']]}, ['7A01', '3A02']), ('control 19', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '2A00', 'cls': 2, 'sched': 150, 'eta': 80, 'route': 'R3'}, {'id': '8A01', 'cls': 1, 'sched': 120, 'eta': 160, 'route': 'R3'}, {'id': '7A02', 'cls': 2, 'sched': 120, 'eta': 220, 'route': 'R1'}, {'id': '8A03', 'cls': 1, 'sched': 200, 'eta': 80, 'route': 'R5'}], 'conflicts': [['R1', 'R2'], ['R2', 'R3'], ['R4', 'R5'], ['R3', 'R4']]}, ['8A01', '8A03']), ('boundary: eta exactly at the lookahead', {'now': 100, 'lookahead_s': 60, 'conflicts': [], 'trains': [{'id': '1A01', 'cls': 1, 'sched': 100, 'eta': 160, 'route': 'R1'}]}, ['1A01']), ('sampled regression 45', {'now': 100, 'lookahead_s': 60, 'trains': [{'id': '6A00', 'cls': 3, 'sched': 150, 'eta': 180, 'route': 'R1'}, {'id': '2A01', 'cls': 3, 'sched': 120, 'eta': 80, 'route': 'R1'}, {'id': '2A02', 'cls': 1, 'sched': 120, 'eta': 400, 'route': 'R1'}, {'id': '5A03', 'cls': 1, 'sched': 120, 'eta': 160, 'route': 'R2'}, {'id': '9A04', 'cls': 3, 'sched': 200, 'eta': 130, 'route': 'R1'}, {'id': '5A05', 'cls': 1, 'sched': 120, 'eta': 130, 'route': 'R1'}], 'conflicts': [['R5', 'R4'], ['R3', 'R2'], ['R1', 'R5'], ['R3', 'R4']]}, ['5A03', '5A05']), ('control 48', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '5A00', 'cls': 2, 'sched': 120, 'eta': 100, 'route': 'R1'}, {'id': '2A01', 'cls': 3, 'sched': 100, 'eta': 100, 'route': 'R3'}], 'conflicts': [['R4', 'R5'], ['R3', 'R4'], ['R1', 'R2']]}, ['5A00', '2A01']), ('control 51', {'now': 100, 'lookahead_s': 80, 'trains': [{'id': '5A00', 'cls': 3, 'sched': 150, 'eta': 220, 'route': 'R4'}, {'id': '6A01', 'cls': 1, 'sched': 120, 'eta': 400, 'route': 'R2'}, {'id': '3A02', 'cls': 2, 'sched': 120, 'eta': 160, 'route': 'R4'}, {'id': '6A03', 'cls': 2, 'sched': 100, 'eta': 400, 'route': 'R2'}], 'conflicts': [['R3', 'R2'], ['R4', 'R5']]}, ['3A02'])]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
A candidate conflicting with a later grant is still granted.

Trains whose eta is at most lookahead_s after now are candidates, including overdue trains (eta before now). Candidates are ordered by class (1 highest), then scheduled time, then id. Routes are granted greedily in that order; a candidate is skipped if its route equals or conflicts with (conflict pairs are unordered) any route already granted. Return granted train ids in grant order.

split: open-access


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

N = 1
observations = []
def solve(x):
    front = x['front_m']
    rear = front - x['length_m']
    limit = x['line_kmh']
    for s in x['tsr']:
        if s['from_m'] <= front and s['to_m'] > front:
            limit = min(limit, s['kmh'])
    ahead = [s for s in x['tsr'] if s['from_m'] > front and s['from_m'] - front <= x['sight_m'] and s['kmh'] < limit]
    nxt = min(ahead, key=lambda s: s['from_m'])['from_m'] if ahead else None
    return {'limit': limit, 'next_m': nxt}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: rear still inside the restriction', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('boundary: rear exactly at the restriction end', {'front_m': 800, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('sampled regression 6', {'front_m': 700, 'length_m': 400, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 0, 'to_m': 600, 'kmh': 20}, {'from_m': 1000, 'to_m': 1600, 'kmh': 80}]}, {'limit': 20, 'next_m': None}), ('boundary: restriction just behind the rear', {'front_m': 1000, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 900, 'kmh': 20}]}, {'limit': 100, 'next_m': None}), ('boundary: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('sampled regression 1', {'front_m': 1100, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1500, 'to_m': 2100, 'kmh': 40}, {'from_m': 800, 'to_m': 1100, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('sampled regression 4', {'front_m': 700, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1100, 'kmh': 40}, {'from_m': 1000, 'to_m': 1600, 'kmh': 20}, {'from_m': 800, 'to_m': 900, 'kmh': 20}, {'from_m': 500, 'to_m': 600, 'kmh': 20}]}, {'limit': 20, 'next_m': None}), ('control 7', {'front_m': 1100, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 800, 'kmh': 40}, {'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 60, 'next_m': None})], [('regression: rear still inside the restriction', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('boundary: restriction just behind the rear', {'front_m': 1000, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 900, 'kmh': 20}]}, {'limit': 100, 'next_m': None}), ('sampled regression 38', {'front_m': 700, 'length_m': 400, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 200, 'to_m': 500, 'kmh': 80}, {'from_m': 0, 'to_m': 100, 'kmh': 60}, {'from_m': 1500, 'to_m': 1600, 'kmh': 20}]}, {'limit': 80, 'next_m': None}), ('control 37', {'front_m': 500, 'length_m': 400, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1600, 'kmh': 60}, {'from_m': 200, 'to_m': 800, 'kmh': 40}, {'from_m': 0, 'to_m': 100, 'kmh': 20}, {'from_m': 1500, 'to_m': 1800, 'kmh': 20}]}, {'limit': 40, 'next_m': None}), ('boundary: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('sampled regression 12', {'front_m': 1300, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 500, 'to_m': 1100, 'kmh': 20}, {'from_m': 1500, 'to_m': 1600, 'kmh': 20}, {'from_m': 200, 'to_m': 300, 'kmh': 40}]}, {'limit': 20, 'next_m': None}), ('control 15', {'front_m': 100, 'length_m': 400, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 1500, 'to_m': 2100, 'kmh': 60}, {'from_m': 800, 'to_m': 900, 'kmh': 20}, {'from_m': 200, 'to_m': 300, 'kmh': 40}]}, {'limit': 120, 'next_m': 200}), ('control 18', {'front_m': 700, 'length_m': 400, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 120, 'next_m': 1000})], [('regression: rear still inside the restriction', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('boundary: rear exactly at the restriction end', {'front_m': 800, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('sampled regression 68', {'front_m': 250, 'length_m': 400, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 200, 'to_m': 500, 'kmh': 80}, {'from_m': 0, 'to_m': 100, 'kmh': 60}, {'from_m': 1500, 'to_m': 2100, 'kmh': 40}, {'from_m': 1500, 'to_m': 1800, 'kmh': 80}]}, {'limit': 60, 'next_m': None}), ('control 72', {'front_m': 700, 'length_m': 100, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 200, 'to_m': 300, 'kmh': 20}, {'from_m': 500, 'to_m': 600, 'kmh': 80}, {'from_m': 0, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('boundary: two restrictions ahead listed far first', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}, {'from_m': 300, 'to_m': 400, 'kmh': 60}]}, {'limit': 100, 'next_m': 300}), ('control 23', {'front_m': 700, 'length_m': 100, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 200, 'to_m': 300, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 80}]}, {'limit': 120, 'next_m': 800}), ('control 26', {'front_m': 500, 'length_m': 100, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 800, 'to_m': 1100, 'kmh': 40}]}, {'limit': 120, 'next_m': 800}), ('control 29', {'front_m': 100, 'length_m': 200, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 0, 'to_m': 300, 'kmh': 20}, {'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 0, 'to_m': 100, 'kmh': 20}]}, {'limit': 20, 'next_m': None})], [('regression: rear still inside the restriction', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('boundary: restriction just behind the rear', {'front_m': 1000, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 900, 'kmh': 20}]}, {'limit': 100, 'next_m': None}), ('sampled regression 27', {'front_m': 1100, 'length_m': 200, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1500, 'to_m': 1600, 'kmh': 60}, {'from_m': 1000, 'to_m': 1100, 'kmh': 20}, {'from_m': 500, 'to_m': 600, 'kmh': 80}, {'from_m': 1500, 'to_m': 1800, 'kmh': 60}]}, {'limit': 20, 'next_m': None}), ('control 8', {'front_m': 500, 'length_m': 200, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1500, 'to_m': 2100, 'kmh': 80}, {'from_m': 200, 'to_m': 300, 'kmh': 40}]}, {'limit': 120, 'next_m': None}), ('boundary: rear exactly at the restriction end', {'front_m': 800, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('control 34', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1300, 'kmh': 80}, {'from_m': 0, 'to_m': 300, 'kmh': 20}, {'from_m': 1000, 'to_m': 1600, 'kmh': 80}, {'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 100, 'next_m': 1000}), ('control 37', {'front_m': 500, 'length_m': 400, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1600, 'kmh': 60}, {'from_m': 200, 'to_m': 800, 'kmh': 40}, {'from_m': 0, 'to_m': 100, 'kmh': 20}, {'from_m': 1500, 'to_m': 1800, 'kmh': 20}]}, {'limit': 40, 'next_m': None}), ('control 40', {'front_m': 1300, 'length_m': 200, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 1000, 'to_m': 1100, 'kmh': 60}, {'from_m': 1500, 'to_m': 2100, 'kmh': 20}]}, {'limit': 120, 'next_m': 1500})], [('regression: rear still inside the restriction', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('boundary: rear exactly at the restriction end', {'front_m': 800, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('sampled regression 50', {'front_m': 1100, 'length_m': 400, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 200, 'to_m': 800, 'kmh': 40}, {'from_m': 500, 'to_m': 800, 'kmh': 60}, {'from_m': 800, 'to_m': 1100, 'kmh': 60}, {'from_m': 500, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('control 42', {'front_m': 1300, 'length_m': 200, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 800, 'to_m': 1100, 'kmh': 20}, {'from_m': 800, 'to_m': 900, 'kmh': 60}, {'from_m': 500, 'to_m': 600, 'kmh': 40}, {'from_m': 200, 'to_m': 300, 'kmh': 80}]}, {'limit': 100, 'next_m': None}), ('boundary: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('control 45', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 0, 'to_m': 300, 'kmh': 60}, {'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 800, 'to_m': 1100, 'kmh': 40}, {'from_m': 200, 'to_m': 500, 'kmh': 60}]}, {'limit': 80, 'next_m': 800}), ('sampled regression 48', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 800, 'to_m': 1400, 'kmh': 80}, {'from_m': 1000, 'to_m': 1100, 'kmh': 40}, {'from_m': 0, 'to_m': 100, 'kmh': 20}]}, {'limit': 20, 'next_m': None}), ('control 51', {'front_m': 900, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None})]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

meaning: Fixture-count band, not measured model difficulty

deps: stdlib

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

N = 1
observations = []
def solve(x):
    front = x['front_m']
    rear = front - x['length_m']
    limit = x['line_kmh']
    for s in x['tsr']:
        if s['from_m'] <= front and s['to_m'] >= rear:
            limit = min(limit, s['kmh'])
    ahead = [s for s in x['tsr'] if s['from_m'] > front and s['from_m'] - front <= x['sight_m'] and s['kmh'] < limit]
    nxt = min(ahead, key=lambda s: s['from_m'])['from_m'] if ahead else None
    return {'limit': limit, 'next_m': nxt}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: rear still inside the restriction', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('boundary: rear exactly at the restriction end', {'front_m': 800, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('sampled regression 6', {'front_m': 700, 'length_m': 400, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 0, 'to_m': 600, 'kmh': 20}, {'from_m': 1000, 'to_m': 1600, 'kmh': 80}]}, {'limit': 20, 'next_m': None}), ('boundary: restriction just behind the rear', {'front_m': 1000, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 900, 'kmh': 20}]}, {'limit': 100, 'next_m': None}), ('boundary: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('sampled regression 1', {'front_m': 1100, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1500, 'to_m': 2100, 'kmh': 40}, {'from_m': 800, 'to_m': 1100, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('sampled regression 4', {'front_m': 700, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1100, 'kmh': 40}, {'from_m': 1000, 'to_m': 1600, 'kmh': 20}, {'from_m': 800, 'to_m': 900, 'kmh': 20}, {'from_m': 500, 'to_m': 600, 'kmh': 20}]}, {'limit': 20, 'next_m': None}), ('control 7', {'front_m': 1100, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 800, 'kmh': 40}, {'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 60, 'next_m': None})], [('regression: rear still inside the restriction', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('boundary: restriction just behind the rear', {'front_m': 1000, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 900, 'kmh': 20}]}, {'limit': 100, 'next_m': None}), ('sampled regression 38', {'front_m': 700, 'length_m': 400, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 200, 'to_m': 500, 'kmh': 80}, {'from_m': 0, 'to_m': 100, 'kmh': 60}, {'from_m': 1500, 'to_m': 1600, 'kmh': 20}]}, {'limit': 80, 'next_m': None}), ('control 37', {'front_m': 500, 'length_m': 400, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1600, 'kmh': 60}, {'from_m': 200, 'to_m': 800, 'kmh': 40}, {'from_m': 0, 'to_m': 100, 'kmh': 20}, {'from_m': 1500, 'to_m': 1800, 'kmh': 20}]}, {'limit': 40, 'next_m': None}), ('boundary: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('sampled regression 12', {'front_m': 1300, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 500, 'to_m': 1100, 'kmh': 20}, {'from_m': 1500, 'to_m': 1600, 'kmh': 20}, {'from_m': 200, 'to_m': 300, 'kmh': 40}]}, {'limit': 20, 'next_m': None}), ('control 15', {'front_m': 100, 'length_m': 400, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 1500, 'to_m': 2100, 'kmh': 60}, {'from_m': 800, 'to_m': 900, 'kmh': 20}, {'from_m': 200, 'to_m': 300, 'kmh': 40}]}, {'limit': 120, 'next_m': 200}), ('control 18', {'front_m': 700, 'length_m': 400, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 120, 'next_m': 1000})], [('regression: rear still inside the restriction', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('boundary: rear exactly at the restriction end', {'front_m': 800, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('sampled regression 68', {'front_m': 250, 'length_m': 400, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 200, 'to_m': 500, 'kmh': 80}, {'from_m': 0, 'to_m': 100, 'kmh': 60}, {'from_m': 1500, 'to_m': 2100, 'kmh': 40}, {'from_m': 1500, 'to_m': 1800, 'kmh': 80}]}, {'limit': 60, 'next_m': None}), ('control 72', {'front_m': 700, 'length_m': 100, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 200, 'to_m': 300, 'kmh': 20}, {'from_m': 500, 'to_m': 600, 'kmh': 80}, {'from_m': 0, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('boundary: two restrictions ahead listed far first', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}, {'from_m': 300, 'to_m': 400, 'kmh': 60}]}, {'limit': 100, 'next_m': 300}), ('control 23', {'front_m': 700, 'length_m': 100, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 200, 'to_m': 300, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 80}]}, {'limit': 120, 'next_m': 800}), ('control 26', {'front_m': 500, 'length_m': 100, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 800, 'to_m': 1100, 'kmh': 40}]}, {'limit': 120, 'next_m': 800}), ('control 29', {'front_m': 100, 'length_m': 200, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 0, 'to_m': 300, 'kmh': 20}, {'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 0, 'to_m': 100, 'kmh': 20}]}, {'limit': 20, 'next_m': None})], [('regression: rear still inside the restriction', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('boundary: restriction just behind the rear', {'front_m': 1000, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 900, 'kmh': 20}]}, {'limit': 100, 'next_m': None}), ('sampled regression 27', {'front_m': 1100, 'length_m': 200, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1500, 'to_m': 1600, 'kmh': 60}, {'from_m': 1000, 'to_m': 1100, 'kmh': 20}, {'from_m': 500, 'to_m': 600, 'kmh': 80}, {'from_m': 1500, 'to_m': 1800, 'kmh': 60}]}, {'limit': 20, 'next_m': None}), ('control 8', {'front_m': 500, 'length_m': 200, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1500, 'to_m': 2100, 'kmh': 80}, {'from_m': 200, 'to_m': 300, 'kmh': 40}]}, {'limit': 120, 'next_m': None}), ('boundary: rear exactly at the restriction end', {'front_m': 800, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('control 34', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1300, 'kmh': 80}, {'from_m': 0, 'to_m': 300, 'kmh': 20}, {'from_m': 1000, 'to_m': 1600, 'kmh': 80}, {'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 100, 'next_m': 1000}), ('control 37', {'front_m': 500, 'length_m': 400, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1600, 'kmh': 60}, {'from_m': 200, 'to_m': 800, 'kmh': 40}, {'from_m': 0, 'to_m': 100, 'kmh': 20}, {'from_m': 1500, 'to_m': 1800, 'kmh': 20}]}, {'limit': 40, 'next_m': None}), ('control 40', {'front_m': 1300, 'length_m': 200, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 1000, 'to_m': 1100, 'kmh': 60}, {'from_m': 1500, 'to_m': 2100, 'kmh': 20}]}, {'limit': 120, 'next_m': 1500})], [('regression: rear still inside the restriction', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('boundary: rear exactly at the restriction end', {'front_m': 800, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('sampled regression 50', {'front_m': 1100, 'length_m': 400, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 200, 'to_m': 800, 'kmh': 40}, {'from_m': 500, 'to_m': 800, 'kmh': 60}, {'from_m': 800, 'to_m': 1100, 'kmh': 60}, {'from_m': 500, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('control 42', {'front_m': 1300, 'length_m': 200, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 800, 'to_m': 1100, 'kmh': 20}, {'from_m': 800, 'to_m': 900, 'kmh': 60}, {'from_m': 500, 'to_m': 600, 'kmh': 40}, {'from_m': 200, 'to_m': 300, 'kmh': 80}]}, {'limit': 100, 'next_m': None}), ('boundary: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('control 45', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 0, 'to_m': 300, 'kmh': 60}, {'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 800, 'to_m': 1100, 'kmh': 40}, {'from_m': 200, 'to_m': 500, 'kmh': 60}]}, {'limit': 80, 'next_m': 800}), ('sampled regression 48', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 800, 'to_m': 1400, 'kmh': 80}, {'from_m': 1000, 'to_m': 1100, 'kmh': 40}, {'from_m': 0, 'to_m': 100, 'kmh': 20}]}, {'limit': 20, 'next_m': None}), ('control 51', {'front_m': 900, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None})]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
The train accelerates when its front leaves the restriction while its rear is still inside.

A restriction [from_m, to_m) applies while any part of the train (rear = front - length) is inside it: from <= front and to > rear. The limit is the minimum of the line speed and applicable restrictions. next_m is the start of the nearest restriction ahead of the front (from > front) within sight_m of the front whose speed is below the current limit, else None.

split: open-access


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

N = 1
observations = []
def solve(x):
    front = x['front_m']
    rear = front - x['length_m']
    limit = x['line_kmh']
    for s in x['tsr']:
        if s['from_m'] <= front and s['to_m'] > rear:
            limit = min(limit, s['kmh'])
    ahead = [s for s in x['tsr'] if s['from_m'] > front and s['from_m'] - front <= x['sight_m'] ]
    nxt = min(ahead, key=lambda s: s['from_m'])['from_m'] if ahead else None
    return {'limit': limit, 'next_m': nxt}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('sampled regression 6', {'front_m': 700, 'length_m': 400, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 0, 'to_m': 600, 'kmh': 20}, {'from_m': 1000, 'to_m': 1600, 'kmh': 80}]}, {'limit': 20, 'next_m': None}), ('regression: restriction ahead slower than line speed only', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 450, 'to_m': 700, 'kmh': 30}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 30, 'next_m': None}), ('boundary: rear still inside the restriction', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('boundary: rear exactly at the restriction end', {'front_m': 800, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('control 1', {'front_m': 1100, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1500, 'to_m': 2100, 'kmh': 40}, {'from_m': 800, 'to_m': 1100, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('sampled regression 4', {'front_m': 700, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1100, 'kmh': 40}, {'from_m': 1000, 'to_m': 1600, 'kmh': 20}, {'from_m': 800, 'to_m': 900, 'kmh': 20}, {'from_m': 500, 'to_m': 600, 'kmh': 20}]}, {'limit': 20, 'next_m': None}), ('control 7', {'front_m': 1100, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 800, 'kmh': 40}, {'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 60, 'next_m': None})], [('regression: restriction ahead slower than line speed only', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 450, 'to_m': 700, 'kmh': 30}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 30, 'next_m': None}), ('sampled regression 56', {'front_m': 500, 'length_m': 200, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 200, 'to_m': 500, 'kmh': 60}, {'from_m': 800, 'to_m': 1400, 'kmh': 60}, {'from_m': 1000, 'to_m': 1600, 'kmh': 80}, {'from_m': 0, 'to_m': 100, 'kmh': 80}]}, {'limit': 60, 'next_m': None}), ('sampled regression 30', {'front_m': 500, 'length_m': 400, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1500, 'to_m': 1800, 'kmh': 40}, {'from_m': 200, 'to_m': 500, 'kmh': 20}, {'from_m': 800, 'to_m': 900, 'kmh': 40}, {'from_m': 1000, 'to_m': 1300, 'kmh': 80}]}, {'limit': 20, 'next_m': None}), ('regression: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('boundary: two restrictions ahead listed far first', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}, {'from_m': 300, 'to_m': 400, 'kmh': 60}]}, {'limit': 100, 'next_m': 300}), ('sampled regression 12', {'front_m': 1300, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 500, 'to_m': 1100, 'kmh': 20}, {'from_m': 1500, 'to_m': 1600, 'kmh': 20}, {'from_m': 200, 'to_m': 300, 'kmh': 40}]}, {'limit': 20, 'next_m': None}), ('control 15', {'front_m': 100, 'length_m': 400, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 1500, 'to_m': 2100, 'kmh': 60}, {'from_m': 800, 'to_m': 900, 'kmh': 20}, {'from_m': 200, 'to_m': 300, 'kmh': 40}]}, {'limit': 120, 'next_m': 200}), ('control 18', {'front_m': 700, 'length_m': 400, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 120, 'next_m': 1000})], [('regression: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('sampled regression 30', {'front_m': 500, 'length_m': 400, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1500, 'to_m': 1800, 'kmh': 40}, {'from_m': 200, 'to_m': 500, 'kmh': 20}, {'from_m': 800, 'to_m': 900, 'kmh': 40}, {'from_m': 1000, 'to_m': 1300, 'kmh': 80}]}, {'limit': 20, 'next_m': None}), ('boundary: two restrictions ahead listed far first', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}, {'from_m': 300, 'to_m': 400, 'kmh': 60}]}, {'limit': 100, 'next_m': 300}), ('boundary: restriction exactly at sighting distance', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 600, 'to_m': 700, 'kmh': 40}]}, {'limit': 100, 'next_m': 600}), ('boundary: restriction just behind the rear', {'front_m': 1000, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 900, 'kmh': 20}]}, {'limit': 100, 'next_m': None}), ('control 23', {'front_m': 700, 'length_m': 100, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 200, 'to_m': 300, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 80}]}, {'limit': 120, 'next_m': 800}), ('control 26', {'front_m': 500, 'length_m': 100, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 800, 'to_m': 1100, 'kmh': 40}]}, {'limit': 120, 'next_m': 800}), ('sampled regression 29', {'front_m': 100, 'length_m': 200, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 0, 'to_m': 300, 'kmh': 20}, {'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 0, 'to_m': 100, 'kmh': 20}]}, {'limit': 20, 'next_m': None})], [('regression: restriction ahead slower than line speed only', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 450, 'to_m': 700, 'kmh': 30}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 30, 'next_m': None}), ('sampled regression 4', {'front_m': 700, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1100, 'kmh': 40}, {'from_m': 1000, 'to_m': 1600, 'kmh': 20}, {'from_m': 800, 'to_m': 900, 'kmh': 20}, {'from_m': 500, 'to_m': 600, 'kmh': 20}]}, {'limit': 20, 'next_m': None}), ('sampled regression 29', {'front_m': 100, 'length_m': 200, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 0, 'to_m': 300, 'kmh': 20}, {'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 0, 'to_m': 100, 'kmh': 20}]}, {'limit': 20, 'next_m': None}), ('boundary: restriction just behind the rear', {'front_m': 1000, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 900, 'kmh': 20}]}, {'limit': 100, 'next_m': None}), ('boundary: rear still inside the restriction', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('control 34', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1300, 'kmh': 80}, {'from_m': 0, 'to_m': 300, 'kmh': 20}, {'from_m': 1000, 'to_m': 1600, 'kmh': 80}, {'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 100, 'next_m': 1000}), ('control 37', {'front_m': 500, 'length_m': 400, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1600, 'kmh': 60}, {'from_m': 200, 'to_m': 800, 'kmh': 40}, {'from_m': 0, 'to_m': 100, 'kmh': 20}, {'from_m': 1500, 'to_m': 1800, 'kmh': 20}]}, {'limit': 40, 'next_m': None}), ('control 40', {'front_m': 1300, 'length_m': 200, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 1000, 'to_m': 1100, 'kmh': 60}, {'from_m': 1500, 'to_m': 2100, 'kmh': 20}]}, {'limit': 120, 'next_m': 1500})], [('regression: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('sampled regression 48', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 800, 'to_m': 1400, 'kmh': 80}, {'from_m': 1000, 'to_m': 1100, 'kmh': 40}, {'from_m': 0, 'to_m': 100, 'kmh': 20}]}, {'limit': 20, 'next_m': None}), ('sampled regression 56', {'front_m': 500, 'length_m': 200, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 200, 'to_m': 500, 'kmh': 60}, {'from_m': 800, 'to_m': 1400, 'kmh': 60}, {'from_m': 1000, 'to_m': 1600, 'kmh': 80}, {'from_m': 0, 'to_m': 100, 'kmh': 80}]}, {'limit': 60, 'next_m': None}), ('boundary: rear exactly at the restriction end', {'front_m': 800, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('regression: restriction ahead slower than line speed only', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 450, 'to_m': 700, 'kmh': 30}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 30, 'next_m': None}), ('control 45', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 0, 'to_m': 300, 'kmh': 60}, {'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 800, 'to_m': 1100, 'kmh': 40}, {'from_m': 200, 'to_m': 500, 'kmh': 60}]}, {'limit': 80, 'next_m': 800}), ('control 51', {'front_m': 900, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('control 54', {'front_m': 900, 'length_m': 100, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1600, 'kmh': 40}]}, {'limit': 100, 'next_m': 1000})]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

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

N = 1
observations = []
def solve(x):
    front = x['front_m']
    rear = front - x['length_m']
    limit = x['line_kmh']
    for s in x['tsr']:
        if s['from_m'] <= front and s['to_m'] > rear:
            limit = min(limit, s['kmh'])
    ahead = [s for s in x['tsr'] if s['from_m'] > front and s['from_m'] - front <= x['sight_m'] and s['kmh'] < x['line_kmh']]
    nxt = min(ahead, key=lambda s: s['from_m'])['from_m'] if ahead else None
    return {'limit': limit, 'next_m': nxt}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('sampled regression 6', {'front_m': 700, 'length_m': 400, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 0, 'to_m': 600, 'kmh': 20}, {'from_m': 1000, 'to_m': 1600, 'kmh': 80}]}, {'limit': 20, 'next_m': None}), ('regression: restriction ahead slower than line speed only', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 450, 'to_m': 700, 'kmh': 30}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 30, 'next_m': None}), ('boundary: rear still inside the restriction', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('boundary: rear exactly at the restriction end', {'front_m': 800, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('control 1', {'front_m': 1100, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1500, 'to_m': 2100, 'kmh': 40}, {'from_m': 800, 'to_m': 1100, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('sampled regression 4', {'front_m': 700, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1100, 'kmh': 40}, {'from_m': 1000, 'to_m': 1600, 'kmh': 20}, {'from_m': 800, 'to_m': 900, 'kmh': 20}, {'from_m': 500, 'to_m': 600, 'kmh': 20}]}, {'limit': 20, 'next_m': None}), ('control 7', {'front_m': 1100, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 800, 'kmh': 40}, {'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 60, 'next_m': None})], [('regression: restriction ahead slower than line speed only', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 450, 'to_m': 700, 'kmh': 30}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 30, 'next_m': None}), ('sampled regression 56', {'front_m': 500, 'length_m': 200, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 200, 'to_m': 500, 'kmh': 60}, {'from_m': 800, 'to_m': 1400, 'kmh': 60}, {'from_m': 1000, 'to_m': 1600, 'kmh': 80}, {'from_m': 0, 'to_m': 100, 'kmh': 80}]}, {'limit': 60, 'next_m': None}), ('sampled regression 30', {'front_m': 500, 'length_m': 400, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1500, 'to_m': 1800, 'kmh': 40}, {'from_m': 200, 'to_m': 500, 'kmh': 20}, {'from_m': 800, 'to_m': 900, 'kmh': 40}, {'from_m': 1000, 'to_m': 1300, 'kmh': 80}]}, {'limit': 20, 'next_m': None}), ('regression: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('boundary: two restrictions ahead listed far first', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}, {'from_m': 300, 'to_m': 400, 'kmh': 60}]}, {'limit': 100, 'next_m': 300}), ('sampled regression 12', {'front_m': 1300, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 500, 'to_m': 1100, 'kmh': 20}, {'from_m': 1500, 'to_m': 1600, 'kmh': 20}, {'from_m': 200, 'to_m': 300, 'kmh': 40}]}, {'limit': 20, 'next_m': None}), ('control 15', {'front_m': 100, 'length_m': 400, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 1500, 'to_m': 2100, 'kmh': 60}, {'from_m': 800, 'to_m': 900, 'kmh': 20}, {'from_m': 200, 'to_m': 300, 'kmh': 40}]}, {'limit': 120, 'next_m': 200}), ('control 18', {'front_m': 700, 'length_m': 400, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 120, 'next_m': 1000})], [('regression: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('sampled regression 30', {'front_m': 500, 'length_m': 400, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1500, 'to_m': 1800, 'kmh': 40}, {'from_m': 200, 'to_m': 500, 'kmh': 20}, {'from_m': 800, 'to_m': 900, 'kmh': 40}, {'from_m': 1000, 'to_m': 1300, 'kmh': 80}]}, {'limit': 20, 'next_m': None}), ('boundary: two restrictions ahead listed far first', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}, {'from_m': 300, 'to_m': 400, 'kmh': 60}]}, {'limit': 100, 'next_m': 300}), ('boundary: restriction exactly at sighting distance', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 600, 'to_m': 700, 'kmh': 40}]}, {'limit': 100, 'next_m': 600}), ('boundary: restriction just behind the rear', {'front_m': 1000, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 900, 'kmh': 20}]}, {'limit': 100, 'next_m': None}), ('control 23', {'front_m': 700, 'length_m': 100, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 200, 'to_m': 300, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 80}]}, {'limit': 120, 'next_m': 800}), ('control 26', {'front_m': 500, 'length_m': 100, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 800, 'to_m': 1100, 'kmh': 40}]}, {'limit': 120, 'next_m': 800}), ('sampled regression 29', {'front_m': 100, 'length_m': 200, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 0, 'to_m': 300, 'kmh': 20}, {'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 0, 'to_m': 100, 'kmh': 20}]}, {'limit': 20, 'next_m': None})], [('regression: restriction ahead slower than line speed only', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 450, 'to_m': 700, 'kmh': 30}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 30, 'next_m': None}), ('sampled regression 4', {'front_m': 700, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1100, 'kmh': 40}, {'from_m': 1000, 'to_m': 1600, 'kmh': 20}, {'from_m': 800, 'to_m': 900, 'kmh': 20}, {'from_m': 500, 'to_m': 600, 'kmh': 20}]}, {'limit': 20, 'next_m': None}), ('sampled regression 29', {'front_m': 100, 'length_m': 200, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 0, 'to_m': 300, 'kmh': 20}, {'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 0, 'to_m': 100, 'kmh': 20}]}, {'limit': 20, 'next_m': None}), ('boundary: restriction just behind the rear', {'front_m': 1000, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 900, 'kmh': 20}]}, {'limit': 100, 'next_m': None}), ('boundary: rear still inside the restriction', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('control 34', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1300, 'kmh': 80}, {'from_m': 0, 'to_m': 300, 'kmh': 20}, {'from_m': 1000, 'to_m': 1600, 'kmh': 80}, {'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 100, 'next_m': 1000}), ('control 37', {'front_m': 500, 'length_m': 400, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1600, 'kmh': 60}, {'from_m': 200, 'to_m': 800, 'kmh': 40}, {'from_m': 0, 'to_m': 100, 'kmh': 20}, {'from_m': 1500, 'to_m': 1800, 'kmh': 20}]}, {'limit': 40, 'next_m': None}), ('control 40', {'front_m': 1300, 'length_m': 200, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 1000, 'to_m': 1100, 'kmh': 60}, {'from_m': 1500, 'to_m': 2100, 'kmh': 20}]}, {'limit': 120, 'next_m': 1500})], [('regression: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('sampled regression 48', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 800, 'to_m': 1400, 'kmh': 80}, {'from_m': 1000, 'to_m': 1100, 'kmh': 40}, {'from_m': 0, 'to_m': 100, 'kmh': 20}]}, {'limit': 20, 'next_m': None}), ('sampled regression 56', {'front_m': 500, 'length_m': 200, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 200, 'to_m': 500, 'kmh': 60}, {'from_m': 800, 'to_m': 1400, 'kmh': 60}, {'from_m': 1000, 'to_m': 1600, 'kmh': 80}, {'from_m': 0, 'to_m': 100, 'kmh': 80}]}, {'limit': 60, 'next_m': None}), ('boundary: rear exactly at the restriction end', {'front_m': 800, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('regression: restriction ahead slower than line speed only', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 450, 'to_m': 700, 'kmh': 30}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 30, 'next_m': None}), ('control 45', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 0, 'to_m': 300, 'kmh': 60}, {'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 800, 'to_m': 1100, 'kmh': 40}, {'from_m': 200, 'to_m': 500, 'kmh': 60}]}, {'limit': 80, 'next_m': 800}), ('control 51', {'front_m': 900, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('control 54', {'front_m': 900, 'length_m': 100, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1600, 'kmh': 40}]}, {'limit': 100, 'next_m': 1000})]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
The driver is warned about a restriction that is faster than the one already in force.

A restriction [from_m, to_m) applies while any part of the train (rear = front - length) is inside it: from <= front and to > rear. The limit is the minimum of the line speed and applicable restrictions. next_m is the start of the nearest restriction ahead of the front (from > front) within sight_m of the front whose speed is below the current limit, else None.

split: open-access


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

N = 1
observations = []
def solve(x):
    front = x['front_m']
    rear = front - x['length_m']
    limit = x['line_kmh']
    for s in x['tsr']:
        if s['from_m'] <= front and s['to_m'] > rear:
            limit = min(limit, s['kmh'])
    ahead = [s for s in x['tsr'] if s['from_m'] > front and s['from_m'] - front <= x['sight_m'] and s['kmh'] < limit]
    nxt = min(ahead, key=lambda s: s['kmh'])['from_m'] if ahead else None
    return {'limit': limit, 'next_m': nxt}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: two restrictions ahead listed far first', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}, {'from_m': 300, 'to_m': 400, 'kmh': 60}]}, {'limit': 100, 'next_m': 300}), ('sampled regression 58', {'front_m': 700, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 800, 'to_m': 1100, 'kmh': 80}, {'from_m': 1000, 'to_m': 1600, 'kmh': 40}, {'from_m': 0, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': 800}), ('boundary: rear still inside the restriction', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('boundary: rear exactly at the restriction end', {'front_m': 800, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('boundary: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('control 1', {'front_m': 1100, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1500, 'to_m': 2100, 'kmh': 40}, {'from_m': 800, 'to_m': 1100, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('control 4', {'front_m': 700, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1100, 'kmh': 40}, {'from_m': 1000, 'to_m': 1600, 'kmh': 20}, {'from_m': 800, 'to_m': 900, 'kmh': 20}, {'from_m': 500, 'to_m': 600, 'kmh': 20}]}, {'limit': 20, 'next_m': None}), ('control 7', {'front_m': 1100, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 800, 'kmh': 40}, {'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 60, 'next_m': None})], [('regression: two restrictions ahead listed far first', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}, {'from_m': 300, 'to_m': 400, 'kmh': 60}]}, {'limit': 100, 'next_m': 300}), ('boundary: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('boundary: restriction ahead slower than line speed only', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 450, 'to_m': 700, 'kmh': 30}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 30, 'next_m': None}), ('boundary: restriction exactly at sighting distance', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 600, 'to_m': 700, 'kmh': 40}]}, {'limit': 100, 'next_m': 600}), ('boundary: restriction just behind the rear', {'front_m': 1000, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 900, 'kmh': 20}]}, {'limit': 100, 'next_m': None}), ('control 12', {'front_m': 1300, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 500, 'to_m': 1100, 'kmh': 20}, {'from_m': 1500, 'to_m': 1600, 'kmh': 20}, {'from_m': 200, 'to_m': 300, 'kmh': 40}]}, {'limit': 20, 'next_m': None}), ('control 15', {'front_m': 100, 'length_m': 400, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 1500, 'to_m': 2100, 'kmh': 60}, {'from_m': 800, 'to_m': 900, 'kmh': 20}, {'from_m': 200, 'to_m': 300, 'kmh': 40}]}, {'limit': 120, 'next_m': 200}), ('control 18', {'front_m': 700, 'length_m': 400, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 120, 'next_m': 1000})], [('regression: two restrictions ahead listed far first', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}, {'from_m': 300, 'to_m': 400, 'kmh': 60}]}, {'limit': 100, 'next_m': 300}), ('sampled regression 58', {'front_m': 700, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 800, 'to_m': 1100, 'kmh': 80}, {'from_m': 1000, 'to_m': 1600, 'kmh': 40}, {'from_m': 0, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': 800}), ('boundary: restriction exactly at sighting distance', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 600, 'to_m': 700, 'kmh': 40}]}, {'limit': 100, 'next_m': 600}), ('boundary: restriction just behind the rear', {'front_m': 1000, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 900, 'kmh': 20}]}, {'limit': 100, 'next_m': None}), ('boundary: rear still inside the restriction', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('control 23', {'front_m': 700, 'length_m': 100, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 200, 'to_m': 300, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 80}]}, {'limit': 120, 'next_m': 800}), ('control 26', {'front_m': 500, 'length_m': 100, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 800, 'to_m': 1100, 'kmh': 40}]}, {'limit': 120, 'next_m': 800}), ('control 29', {'front_m': 100, 'length_m': 200, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 0, 'to_m': 300, 'kmh': 20}, {'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 0, 'to_m': 100, 'kmh': 20}]}, {'limit': 20, 'next_m': None})], [('regression: two restrictions ahead listed far first', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}, {'from_m': 300, 'to_m': 400, 'kmh': 60}]}, {'limit': 100, 'next_m': 300}), ('boundary: restriction just behind the rear', {'front_m': 1000, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 900, 'kmh': 20}]}, {'limit': 100, 'next_m': None}), ('boundary: rear still inside the restriction', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('boundary: rear exactly at the restriction end', {'front_m': 800, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('boundary: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('control 34', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1300, 'kmh': 80}, {'from_m': 0, 'to_m': 300, 'kmh': 20}, {'from_m': 1000, 'to_m': 1600, 'kmh': 80}, {'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 100, 'next_m': 1000}), ('control 37', {'front_m': 500, 'length_m': 400, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1600, 'kmh': 60}, {'from_m': 200, 'to_m': 800, 'kmh': 40}, {'from_m': 0, 'to_m': 100, 'kmh': 20}, {'from_m': 1500, 'to_m': 1800, 'kmh': 20}]}, {'limit': 40, 'next_m': None}), ('control 40', {'front_m': 1300, 'length_m': 200, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 1000, 'to_m': 1100, 'kmh': 60}, {'from_m': 1500, 'to_m': 2100, 'kmh': 20}]}, {'limit': 120, 'next_m': 1500})], [('regression: two restrictions ahead listed far first', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}, {'from_m': 300, 'to_m': 400, 'kmh': 60}]}, {'limit': 100, 'next_m': 300}), ('sampled regression 58', {'front_m': 700, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 800, 'to_m': 1100, 'kmh': 80}, {'from_m': 1000, 'to_m': 1600, 'kmh': 40}, {'from_m': 0, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': 800}), ('boundary: rear exactly at the restriction end', {'front_m': 800, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('boundary: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('boundary: restriction ahead slower than line speed only', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 450, 'to_m': 700, 'kmh': 30}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 30, 'next_m': None}), ('control 45', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 0, 'to_m': 300, 'kmh': 60}, {'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 800, 'to_m': 1100, 'kmh': 40}, {'from_m': 200, 'to_m': 500, 'kmh': 60}]}, {'limit': 80, 'next_m': 800}), ('control 48', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 800, 'to_m': 1400, 'kmh': 80}, {'from_m': 1000, 'to_m': 1100, 'kmh': 40}, {'from_m': 0, 'to_m': 100, 'kmh': 20}]}, {'limit': 20, 'next_m': None}), ('control 51', {'front_m': 900, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None})]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

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

N = 1
observations = []
def solve(x):
    front = x['front_m']
    rear = front - x['length_m']
    limit = x['line_kmh']
    for s in x['tsr']:
        if s['from_m'] <= front and s['to_m'] > rear:
            limit = min(limit, s['kmh'])
    ahead = [s for s in x['tsr'] if s['from_m'] > front and s['from_m'] - front <= x['sight_m'] and s['kmh'] < limit]
    nxt = ahead[0]['from_m'] if ahead else None
    return {'limit': limit, 'next_m': nxt}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: two restrictions ahead listed far first', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}, {'from_m': 300, 'to_m': 400, 'kmh': 60}]}, {'limit': 100, 'next_m': 300}), ('sampled regression 58', {'front_m': 700, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 800, 'to_m': 1100, 'kmh': 80}, {'from_m': 1000, 'to_m': 1600, 'kmh': 40}, {'from_m': 0, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': 800}), ('boundary: rear still inside the restriction', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('boundary: rear exactly at the restriction end', {'front_m': 800, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('boundary: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('control 1', {'front_m': 1100, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1500, 'to_m': 2100, 'kmh': 40}, {'from_m': 800, 'to_m': 1100, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('control 4', {'front_m': 700, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1100, 'kmh': 40}, {'from_m': 1000, 'to_m': 1600, 'kmh': 20}, {'from_m': 800, 'to_m': 900, 'kmh': 20}, {'from_m': 500, 'to_m': 600, 'kmh': 20}]}, {'limit': 20, 'next_m': None}), ('control 7', {'front_m': 1100, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 800, 'kmh': 40}, {'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 60, 'next_m': None})], [('regression: two restrictions ahead listed far first', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}, {'from_m': 300, 'to_m': 400, 'kmh': 60}]}, {'limit': 100, 'next_m': 300}), ('boundary: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('boundary: restriction ahead slower than line speed only', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 450, 'to_m': 700, 'kmh': 30}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 30, 'next_m': None}), ('boundary: restriction exactly at sighting distance', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 600, 'to_m': 700, 'kmh': 40}]}, {'limit': 100, 'next_m': 600}), ('boundary: restriction just behind the rear', {'front_m': 1000, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 900, 'kmh': 20}]}, {'limit': 100, 'next_m': None}), ('control 12', {'front_m': 1300, 'length_m': 400, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 500, 'to_m': 1100, 'kmh': 20}, {'from_m': 1500, 'to_m': 1600, 'kmh': 20}, {'from_m': 200, 'to_m': 300, 'kmh': 40}]}, {'limit': 20, 'next_m': None}), ('control 15', {'front_m': 100, 'length_m': 400, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 1500, 'to_m': 2100, 'kmh': 60}, {'from_m': 800, 'to_m': 900, 'kmh': 20}, {'from_m': 200, 'to_m': 300, 'kmh': 40}]}, {'limit': 120, 'next_m': 200}), ('control 18', {'front_m': 700, 'length_m': 400, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 120, 'next_m': 1000})], [('regression: two restrictions ahead listed far first', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}, {'from_m': 300, 'to_m': 400, 'kmh': 60}]}, {'limit': 100, 'next_m': 300}), ('sampled regression 58', {'front_m': 700, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 800, 'to_m': 1100, 'kmh': 80}, {'from_m': 1000, 'to_m': 1600, 'kmh': 40}, {'from_m': 0, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': 800}), ('boundary: restriction exactly at sighting distance', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 600, 'to_m': 700, 'kmh': 40}]}, {'limit': 100, 'next_m': 600}), ('boundary: restriction just behind the rear', {'front_m': 1000, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 900, 'kmh': 20}]}, {'limit': 100, 'next_m': None}), ('boundary: rear still inside the restriction', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('control 23', {'front_m': 700, 'length_m': 100, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 200, 'to_m': 300, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 80}]}, {'limit': 120, 'next_m': 800}), ('control 26', {'front_m': 500, 'length_m': 100, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 800, 'to_m': 1100, 'kmh': 40}]}, {'limit': 120, 'next_m': 800}), ('control 29', {'front_m': 100, 'length_m': 200, 'line_kmh': 120, 'sight_m': 300, 'tsr': [{'from_m': 0, 'to_m': 300, 'kmh': 20}, {'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 0, 'to_m': 100, 'kmh': 20}]}, {'limit': 20, 'next_m': None})], [('regression: two restrictions ahead listed far first', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}, {'from_m': 300, 'to_m': 400, 'kmh': 60}]}, {'limit': 100, 'next_m': 300}), ('boundary: restriction just behind the rear', {'front_m': 1000, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 900, 'kmh': 20}]}, {'limit': 100, 'next_m': None}), ('boundary: rear still inside the restriction', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 40, 'next_m': None}), ('boundary: rear exactly at the restriction end', {'front_m': 800, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('boundary: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('control 34', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1300, 'kmh': 80}, {'from_m': 0, 'to_m': 300, 'kmh': 20}, {'from_m': 1000, 'to_m': 1600, 'kmh': 80}, {'from_m': 1000, 'to_m': 1300, 'kmh': 60}]}, {'limit': 100, 'next_m': 1000}), ('control 37', {'front_m': 500, 'length_m': 400, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 1000, 'to_m': 1600, 'kmh': 60}, {'from_m': 200, 'to_m': 800, 'kmh': 40}, {'from_m': 0, 'to_m': 100, 'kmh': 20}, {'from_m': 1500, 'to_m': 1800, 'kmh': 20}]}, {'limit': 40, 'next_m': None}), ('control 40', {'front_m': 1300, 'length_m': 200, 'line_kmh': 120, 'sight_m': 500, 'tsr': [{'from_m': 1000, 'to_m': 1100, 'kmh': 60}, {'from_m': 1500, 'to_m': 2100, 'kmh': 20}]}, {'limit': 120, 'next_m': 1500})], [('regression: two restrictions ahead listed far first', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}, {'from_m': 300, 'to_m': 400, 'kmh': 60}]}, {'limit': 100, 'next_m': 300}), ('sampled regression 58', {'front_m': 700, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 800, 'to_m': 1100, 'kmh': 80}, {'from_m': 1000, 'to_m': 1600, 'kmh': 40}, {'from_m': 0, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': 800}), ('boundary: rear exactly at the restriction end', {'front_m': 800, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None}), ('boundary: restriction ahead faster than current limit', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 400, 'to_m': 600, 'kmh': 40}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 40, 'next_m': None}), ('boundary: restriction ahead slower than line speed only', {'front_m': 500, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 450, 'to_m': 700, 'kmh': 30}, {'from_m': 800, 'to_m': 900, 'kmh': 60}]}, {'limit': 30, 'next_m': None}), ('control 45', {'front_m': 700, 'length_m': 200, 'line_kmh': 100, 'sight_m': 300, 'tsr': [{'from_m': 0, 'to_m': 300, 'kmh': 60}, {'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 800, 'to_m': 1100, 'kmh': 40}, {'from_m': 200, 'to_m': 500, 'kmh': 60}]}, {'limit': 80, 'next_m': 800}), ('control 48', {'front_m': 100, 'length_m': 100, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 200, 'to_m': 800, 'kmh': 80}, {'from_m': 800, 'to_m': 1400, 'kmh': 80}, {'from_m': 1000, 'to_m': 1100, 'kmh': 40}, {'from_m': 0, 'to_m': 100, 'kmh': 20}]}, {'limit': 20, 'next_m': None}), ('control 51', {'front_m': 900, 'length_m': 200, 'line_kmh': 100, 'sight_m': 500, 'tsr': [{'from_m': 500, 'to_m': 600, 'kmh': 40}]}, {'limit': 100, 'next_m': None})]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)

prompt:
The announced restriction is not the nearest one ahead.

A restriction [from_m, to_m) applies while any part of the train (rear = front - length) is inside it: from <= front and to > rear. The limit is the minimum of the line speed and applicable restrictions. next_m is the start of the nearest restriction ahead of the front (from > front) within sight_m of the front whose speed is below the current limit, else None.

split: open-access