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

N = 1
observations = []
def solve(x):
    t0 = x['strike_in_s']
    arrive = t0 + (x['distance_m'] * 36) // (x['speed_kmh'] * 10)
    red = t0 + 3
    entry_down = red + 4 + x['lower_s']
    exit_down = entry_down + 4
    proved = exit_down if x['four_quadrant'] else entry_down
    obstacle = x['obstacle_clear_s']
    clear_sig = max(proved, obstacle) if obstacle is not None else None
    warning = arrive - red
    ok = warning >= x['min_warning_s'] and clear_sig is not None and clear_sig <= arrive
    return {'arrive': arrive, 'proved': proved, 'signal_clear': clear_sig, 'warning_ok': ok}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: warning measured from red', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 120, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 25, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 30, 'proved': 15, 'signal_clear': 25, 'warning_ok': False}), ('boundary: clear exactly at the sighting point', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 90, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 30, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 40, 'proved': 15, 'signal_clear': 30, 'warning_ok': True}), ('control 49', {'strike_in_s': 0, 'distance_m': 2000, 'speed_kmh': 160, 'lower_s': 10, 'four_quadrant': True, 'obstacle_clear_s': 30, 'min_warning_s': 20, 'sighting_s': 15}, {'arrive': 45, 'proved': 21, 'signal_clear': 30, 'warning_ok': True}), ('boundary: fast train on a short approach', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 160, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 25, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 22, 'proved': 15, 'signal_clear': 25, 'warning_ok': False}), ('boundary: arrival rounding', {'strike_in_s': 0, 'distance_m': 1250, 'speed_kmh': 90, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 25, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 50, 'proved': 15, 'signal_clear': 25, 'warning_ok': True}), ('control 1', {'strike_in_s': 5, 'distance_m': 800, 'speed_kmh': 60, 'lower_s': 10, 'four_quadrant': True, 'obstacle_clear_s': 40, 'min_warning_s': 20, 'sighting_s': 10}, {'arrive': 53, 'proved': 26, 'signal_clear': 40, 'warning_ok': True}), ('control 4', {'strike_in_s': 0, 'distance_m': 2400, 'speed_kmh': 120, 'lower_s': 10, 'four_quadrant': True, 'obstacle_clear_s': 60, 'min_warning_s': 35, 'sighting_s': 5}, {'arrive': 72, 'proved': 21, 'signal_clear': 60, 'warning_ok': True}), ('control 7', {'strike_in_s': 30, 'distance_m': 2000, 'speed_kmh': 160, 'lower_s': 6, 'four_quadrant': False, 'obstacle_clear_s': 40, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 75, 'proved': 43, 'signal_clear': 43, 'warning_ok': True})], [('regression: warning measured from red', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 120, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 25, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 30, 'proved': 15, 'signal_clear': 25, 'warning_ok': False}), ('boundary: clear exactly at the sighting point', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 90, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 30, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 40, 'proved': 15, 'signal_clear': 30, 'warning_ok': True}), ('sampled regression 14', {'strike_in_s': 12, 'distance_m': 1500, 'speed_kmh': 160, 'lower_s': 10, 'four_quadrant': True, 'obstacle_clear_s': 20, 'min_warning_s': 20, 'sighting_s': 15}, {'arrive': 45, 'proved': 33, 'signal_clear': 33, 'warning_ok': False}), ('boundary: four-quadrant proving', {'strike_in_s': 0, 'distance_m': 2000, 'speed_kmh': 90, 'lower_s': 8, 'four_quadrant': True, 'obstacle_clear_s': 25, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 80, 'proved': 19, 'signal_clear': 25, 'warning_ok': True}), ('boundary: obstacle detector silent', {'strike_in_s': 0, 'distance_m': 2000, 'speed_kmh': 90, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': None, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 80, 'proved': 15, 'signal_clear': None, 'warning_ok': False}), ('control 12', {'strike_in_s': 12, 'distance_m': 800, 'speed_kmh': 60, 'lower_s': 8, 'four_quadrant': True, 'obstacle_clear_s': 25, 'min_warning_s': 20, 'sighting_s': 5}, {'arrive': 60, 'proved': 31, 'signal_clear': 31, 'warning_ok': True}), ('control 15', {'strike_in_s': 5, 'distance_m': 2000, 'speed_kmh': 120, 'lower_s': 8, 'four_quadrant': True, 'obstacle_clear_s': 30, 'min_warning_s': 27, 'sighting_s': 15}, {'arrive': 65, 'proved': 24, 'signal_clear': 30, 'warning_ok': True}), ('control 18', {'strike_in_s': 30, 'distance_m': 1000, 'speed_kmh': 160, 'lower_s': 6, 'four_quadrant': False, 'obstacle_clear_s': 25, 'min_warning_s': 20, 'sighting_s': 15}, {'arrive': 52, 'proved': 43, 'signal_clear': 43, 'warning_ok': False})], [('regression: warning measured from red', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 120, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 25, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 30, 'proved': 15, 'signal_clear': 25, 'warning_ok': False}), ('boundary: clear exactly at the sighting point', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 90, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 30, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 40, 'proved': 15, 'signal_clear': 30, 'warning_ok': True}), ('sampled regression 26', {'strike_in_s': 0, 'distance_m': 1500, 'speed_kmh': 160, 'lower_s': 10, 'four_quadrant': False, 'obstacle_clear_s': 25, 'min_warning_s': 20, 'sighting_s': 10}, {'arrive': 33, 'proved': 17, 'signal_clear': 25, 'warning_ok': False}), ('control 49', {'strike_in_s': 0, 'distance_m': 2000, 'speed_kmh': 160, 'lower_s': 10, 'four_quadrant': True, 'obstacle_clear_s': 30, 'min_warning_s': 20, 'sighting_s': 15}, {'arrive': 45, 'proved': 21, 'signal_clear': 30, 'warning_ok': True}), ('boundary: obstacle confirmed at strike-in', {'strike_in_s': 0, 'distance_m': 2000, 'speed_kmh': 90, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 0, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 80, 'proved': 15, 'signal_clear': 15, 'warning_ok': True}), ('control 23', {'strike_in_s': 0, 'distance_m': 800, 'speed_kmh': 60, 'lower_s': 10, 'four_quadrant': False, 'obstacle_clear_s': None, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 48, 'proved': 17, 'signal_clear': None, 'warning_ok': False}), ('control 29', {'strike_in_s': 5, 'distance_m': 1250, 'speed_kmh': 120, 'lower_s': 8, 'four_quadrant': True, 'obstacle_clear_s': 60, 'min_warning_s': 35, 'sighting_s': 10}, {'arrive': 42, 'proved': 24, 'signal_clear': 60, 'warning_ok': False}), ('control 32', {'strike_in_s': 5, 'distance_m': 800, 'speed_kmh': 160, 'lower_s': 10, 'four_quadrant': True, 'obstacle_clear_s': 25, 'min_warning_s': 35, 'sighting_s': 5}, {'arrive': 23, 'proved': 26, 'signal_clear': 26, 'warning_ok': False})], [('regression: warning measured from red', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 120, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 25, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 30, 'proved': 15, 'signal_clear': 25, 'warning_ok': False}), ('boundary: clear exactly at the sighting point', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 90, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 30, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 40, 'proved': 15, 'signal_clear': 30, 'warning_ok': True}), ('boundary: late obstacle confirmation', {'strike_in_s': 5, 'distance_m': 2400, 'speed_kmh': 120, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 60, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 77, 'proved': 20, 'signal_clear': 60, 'warning_ok': True}), ('boundary: fast train on a short approach', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 160, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 25, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 22, 'proved': 15, 'signal_clear': 25, 'warning_ok': False}), ('boundary: arrival rounding', {'strike_in_s': 0, 'distance_m': 1250, 'speed_kmh': 90, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 25, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 50, 'proved': 15, 'signal_clear': 25, 'warning_ok': True}), ('control 34', {'strike_in_s': 0, 'distance_m': 2000, 'speed_kmh': 160, 'lower_s': 10, 'four_quadrant': False, 'obstacle_clear_s': 20, 'min_warning_s': 20, 'sighting_s': 5}, {'arrive': 45, 'proved': 17, 'signal_clear': 20, 'warning_ok': True}), ('control 37', {'strike_in_s': 30, 'distance_m': 800, 'speed_kmh': 160, 'lower_s': 8, 'four_quadrant': True, 'obstacle_clear_s': 40, 'min_warning_s': 35, 'sighting_s': 15}, {'arrive': 48, 'proved': 49, 'signal_clear': 49, 'warning_ok': False}), ('control 40', {'strike_in_s': 12, 'distance_m': 800, 'speed_kmh': 160, 'lower_s': 6, 'four_quadrant': True, 'obstacle_clear_s': 40, 'min_warning_s': 35, 'sighting_s': 15}, {'arrive': 30, 'proved': 29, 'signal_clear': 40, 'warning_ok': False})], [('regression: warning measured from red', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 120, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 25, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 30, 'proved': 15, 'signal_clear': 25, 'warning_ok': False}), ('boundary: clear exactly at the sighting point', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 90, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 30, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 40, 'proved': 15, 'signal_clear': 30, 'warning_ok': True}), ('sampled regression 14', {'strike_in_s': 12, 'distance_m': 1500, 'speed_kmh': 160, 'lower_s': 10, 'four_quadrant': True, 'obstacle_clear_s': 20, 'min_warning_s': 20, 'sighting_s': 15}, {'arrive': 45, 'proved': 33, 'signal_clear': 33, 'warning_ok': False}), ('control 49', {'strike_in_s': 0, 'distance_m': 2000, 'speed_kmh': 160, 'lower_s': 10, 'four_quadrant': True, 'obstacle_clear_s': 30, 'min_warning_s': 20, 'sighting_s': 15}, {'arrive': 45, 'proved': 21, 'signal_clear': 30, 'warning_ok': True}), ('boundary: fast train on a short approach', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 160, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 25, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 22, 'proved': 15, 'signal_clear': 25, 'warning_ok': False}), ('control 45', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 90, 'lower_s': 10, 'four_quadrant': False, 'obstacle_clear_s': 0, 'min_warning_s': 35, 'sighting_s': 10}, {'arrive': 40, 'proved': 17, 'signal_clear': 17, 'warning_ok': True}), ('control 48', {'strike_in_s': 30, 'distance_m': 800, 'speed_kmh': 160, 'lower_s': 10, 'four_quadrant': False, 'obstacle_clear_s': 30, 'min_warning_s': 20, 'sighting_s': 15}, {'arrive': 48, 'proved': 47, 'signal_clear': 47, 'warning_ok': False}), ('control 51', {'strike_in_s': 0, 'distance_m': 1250, 'speed_kmh': 90, 'lower_s': 10, 'four_quadrant': True, 'obstacle_clear_s': 20, 'min_warning_s': 20, 'sighting_s': 5}, {'arrive': 50, 'proved': 21, 'signal_clear': 21, 'warning_ok': True})]]
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):
    t0 = x['strike_in_s']
    arrive = t0 + (x['distance_m'] * 36) // (x['speed_kmh'] * 10)
    red = t0 + 3
    entry_down = red + 4 + x['lower_s']
    exit_down = entry_down + 4
    proved = exit_down if x['four_quadrant'] else entry_down
    obstacle = x['obstacle_clear_s']
    clear_sig = max(proved, obstacle) if obstacle is not None else None
    warning = arrive - red
    ok = warning >= x['min_warning_s'] and clear_sig is not None and clear_sig < arrive - x['sighting_s']
    return {'arrive': arrive, 'proved': proved, 'signal_clear': clear_sig, 'warning_ok': ok}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: warning measured from red', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 120, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 25, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 30, 'proved': 15, 'signal_clear': 25, 'warning_ok': False}), ('boundary: clear exactly at the sighting point', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 90, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 30, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 40, 'proved': 15, 'signal_clear': 30, 'warning_ok': True}), ('control 49', {'strike_in_s': 0, 'distance_m': 2000, 'speed_kmh': 160, 'lower_s': 10, 'four_quadrant': True, 'obstacle_clear_s': 30, 'min_warning_s': 20, 'sighting_s': 15}, {'arrive': 45, 'proved': 21, 'signal_clear': 30, 'warning_ok': True}), ('boundary: fast train on a short approach', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 160, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 25, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 22, 'proved': 15, 'signal_clear': 25, 'warning_ok': False}), ('boundary: arrival rounding', {'strike_in_s': 0, 'distance_m': 1250, 'speed_kmh': 90, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 25, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 50, 'proved': 15, 'signal_clear': 25, 'warning_ok': True}), ('control 1', {'strike_in_s': 5, 'distance_m': 800, 'speed_kmh': 60, 'lower_s': 10, 'four_quadrant': True, 'obstacle_clear_s': 40, 'min_warning_s': 20, 'sighting_s': 10}, {'arrive': 53, 'proved': 26, 'signal_clear': 40, 'warning_ok': True}), ('control 4', {'strike_in_s': 0, 'distance_m': 2400, 'speed_kmh': 120, 'lower_s': 10, 'four_quadrant': True, 'obstacle_clear_s': 60, 'min_warning_s': 35, 'sighting_s': 5}, {'arrive': 72, 'proved': 21, 'signal_clear': 60, 'warning_ok': True}), ('control 7', {'strike_in_s': 30, 'distance_m': 2000, 'speed_kmh': 160, 'lower_s': 6, 'four_quadrant': False, 'obstacle_clear_s': 40, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 75, 'proved': 43, 'signal_clear': 43, 'warning_ok': True})], [('regression: warning measured from red', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 120, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 25, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 30, 'proved': 15, 'signal_clear': 25, 'warning_ok': False}), ('boundary: clear exactly at the sighting point', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 90, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 30, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 40, 'proved': 15, 'signal_clear': 30, 'warning_ok': True}), ('sampled regression 14', {'strike_in_s': 12, 'distance_m': 1500, 'speed_kmh': 160, 'lower_s': 10, 'four_quadrant': True, 'obstacle_clear_s': 20, 'min_warning_s': 20, 'sighting_s': 15}, {'arrive': 45, 'proved': 33, 'signal_clear': 33, 'warning_ok': False}), ('boundary: four-quadrant proving', {'strike_in_s': 0, 'distance_m': 2000, 'speed_kmh': 90, 'lower_s': 8, 'four_quadrant': True, 'obstacle_clear_s': 25, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 80, 'proved': 19, 'signal_clear': 25, 'warning_ok': True}), ('boundary: obstacle detector silent', {'strike_in_s': 0, 'distance_m': 2000, 'speed_kmh': 90, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': None, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 80, 'proved': 15, 'signal_clear': None, 'warning_ok': False}), ('control 12', {'strike_in_s': 12, 'distance_m': 800, 'speed_kmh': 60, 'lower_s': 8, 'four_quadrant': True, 'obstacle_clear_s': 25, 'min_warning_s': 20, 'sighting_s': 5}, {'arrive': 60, 'proved': 31, 'signal_clear': 31, 'warning_ok': True}), ('control 15', {'strike_in_s': 5, 'distance_m': 2000, 'speed_kmh': 120, 'lower_s': 8, 'four_quadrant': True, 'obstacle_clear_s': 30, 'min_warning_s': 27, 'sighting_s': 15}, {'arrive': 65, 'proved': 24, 'signal_clear': 30, 'warning_ok': True}), ('control 18', {'strike_in_s': 30, 'distance_m': 1000, 'speed_kmh': 160, 'lower_s': 6, 'four_quadrant': False, 'obstacle_clear_s': 25, 'min_warning_s': 20, 'sighting_s': 15}, {'arrive': 52, 'proved': 43, 'signal_clear': 43, 'warning_ok': False})], [('regression: warning measured from red', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 120, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 25, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 30, 'proved': 15, 'signal_clear': 25, 'warning_ok': False}), ('boundary: clear exactly at the sighting point', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 90, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 30, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 40, 'proved': 15, 'signal_clear': 30, 'warning_ok': True}), ('sampled regression 26', {'strike_in_s': 0, 'distance_m': 1500, 'speed_kmh': 160, 'lower_s': 10, 'four_quadrant': False, 'obstacle_clear_s': 25, 'min_warning_s': 20, 'sighting_s': 10}, {'arrive': 33, 'proved': 17, 'signal_clear': 25, 'warning_ok': False}), ('control 49', {'strike_in_s': 0, 'distance_m': 2000, 'speed_kmh': 160, 'lower_s': 10, 'four_quadrant': True, 'obstacle_clear_s': 30, 'min_warning_s': 20, 'sighting_s': 15}, {'arrive': 45, 'proved': 21, 'signal_clear': 30, 'warning_ok': True}), ('boundary: obstacle confirmed at strike-in', {'strike_in_s': 0, 'distance_m': 2000, 'speed_kmh': 90, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 0, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 80, 'proved': 15, 'signal_clear': 15, 'warning_ok': True}), ('control 23', {'strike_in_s': 0, 'distance_m': 800, 'speed_kmh': 60, 'lower_s': 10, 'four_quadrant': False, 'obstacle_clear_s': None, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 48, 'proved': 17, 'signal_clear': None, 'warning_ok': False}), ('control 29', {'strike_in_s': 5, 'distance_m': 1250, 'speed_kmh': 120, 'lower_s': 8, 'four_quadrant': True, 'obstacle_clear_s': 60, 'min_warning_s': 35, 'sighting_s': 10}, {'arrive': 42, 'proved': 24, 'signal_clear': 60, 'warning_ok': False}), ('control 32', {'strike_in_s': 5, 'distance_m': 800, 'speed_kmh': 160, 'lower_s': 10, 'four_quadrant': True, 'obstacle_clear_s': 25, 'min_warning_s': 35, 'sighting_s': 5}, {'arrive': 23, 'proved': 26, 'signal_clear': 26, 'warning_ok': False})], [('regression: warning measured from red', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 120, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 25, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 30, 'proved': 15, 'signal_clear': 25, 'warning_ok': False}), ('boundary: clear exactly at the sighting point', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 90, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 30, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 40, 'proved': 15, 'signal_clear': 30, 'warning_ok': True}), ('boundary: late obstacle confirmation', {'strike_in_s': 5, 'distance_m': 2400, 'speed_kmh': 120, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 60, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 77, 'proved': 20, 'signal_clear': 60, 'warning_ok': True}), ('boundary: fast train on a short approach', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 160, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 25, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 22, 'proved': 15, 'signal_clear': 25, 'warning_ok': False}), ('boundary: arrival rounding', {'strike_in_s': 0, 'distance_m': 1250, 'speed_kmh': 90, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 25, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 50, 'proved': 15, 'signal_clear': 25, 'warning_ok': True}), ('control 34', {'strike_in_s': 0, 'distance_m': 2000, 'speed_kmh': 160, 'lower_s': 10, 'four_quadrant': False, 'obstacle_clear_s': 20, 'min_warning_s': 20, 'sighting_s': 5}, {'arrive': 45, 'proved': 17, 'signal_clear': 20, 'warning_ok': True}), ('control 37', {'strike_in_s': 30, 'distance_m': 800, 'speed_kmh': 160, 'lower_s': 8, 'four_quadrant': True, 'obstacle_clear_s': 40, 'min_warning_s': 35, 'sighting_s': 15}, {'arrive': 48, 'proved': 49, 'signal_clear': 49, 'warning_ok': False}), ('control 40', {'strike_in_s': 12, 'distance_m': 800, 'speed_kmh': 160, 'lower_s': 6, 'four_quadrant': True, 'obstacle_clear_s': 40, 'min_warning_s': 35, 'sighting_s': 15}, {'arrive': 30, 'proved': 29, 'signal_clear': 40, 'warning_ok': False})], [('regression: warning measured from red', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 120, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 25, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 30, 'proved': 15, 'signal_clear': 25, 'warning_ok': False}), ('boundary: clear exactly at the sighting point', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 90, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 30, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 40, 'proved': 15, 'signal_clear': 30, 'warning_ok': True}), ('sampled regression 14', {'strike_in_s': 12, 'distance_m': 1500, 'speed_kmh': 160, 'lower_s': 10, 'four_quadrant': True, 'obstacle_clear_s': 20, 'min_warning_s': 20, 'sighting_s': 15}, {'arrive': 45, 'proved': 33, 'signal_clear': 33, 'warning_ok': False}), ('control 49', {'strike_in_s': 0, 'distance_m': 2000, 'speed_kmh': 160, 'lower_s': 10, 'four_quadrant': True, 'obstacle_clear_s': 30, 'min_warning_s': 20, 'sighting_s': 15}, {'arrive': 45, 'proved': 21, 'signal_clear': 30, 'warning_ok': True}), ('boundary: fast train on a short approach', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 160, 'lower_s': 8, 'four_quadrant': False, 'obstacle_clear_s': 25, 'min_warning_s': 27, 'sighting_s': 10}, {'arrive': 22, 'proved': 15, 'signal_clear': 25, 'warning_ok': False}), ('control 45', {'strike_in_s': 0, 'distance_m': 1000, 'speed_kmh': 90, 'lower_s': 10, 'four_quadrant': False, 'obstacle_clear_s': 0, 'min_warning_s': 35, 'sighting_s': 10}, {'arrive': 40, 'proved': 17, 'signal_clear': 17, 'warning_ok': True}), ('control 48', {'strike_in_s': 30, 'distance_m': 800, 'speed_kmh': 160, 'lower_s': 10, 'four_quadrant': False, 'obstacle_clear_s': 30, 'min_warning_s': 20, 'sighting_s': 15}, {'arrive': 48, 'proved': 47, 'signal_clear': 47, 'warning_ok': False}), ('control 51', {'strike_in_s': 0, 'distance_m': 1250, 'speed_kmh': 90, 'lower_s': 10, 'four_quadrant': True, 'obstacle_clear_s': 20, 'min_warning_s': 20, 'sighting_s': 5}, {'arrive': 50, 'proved': 21, 'signal_clear': 21, 'warning_ok': True})]]
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 crossing is judged safe although the driver cannot see the signal clear in time.

Strike-in at t0 starts amber; red follows 3 s later; entrance barriers are down 4 s after red plus lower_s; exit barriers 4 s after that. Half-barrier crossings are proven at entrance-down, four-quadrant crossings at exit-down. Train arrival is t0 + floor(distance*3.6/speed). The protecting signal clears at max(proven, obstacle clear) and never without an obstacle confirmation (None). warning_ok needs arrival-red >= min_warning_s and a clear time no later than arrival - sighting_s.

split: open-access


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

N = 1
observations = []
def solve(x):
    T = x['timer_s']
    start = None
    overran = False
    released = False
    out = []
    for t, ev in x['events']:
        if start is not None and not released and not overran and t - start > T:
            released = True
        if ev == 'berth_occ':
            if start is None:
                start = t
        elif ev == 'berth_clr':
            if not released:
                start = None
        elif ev == 'overlap_occ':
            if not released:
                overran = True
        elif ev == 'query':
            out.append('released' if released else 'locked')
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: expiry exactly on time', {'timer_s': 60, 'events': [[10, 'berth_occ'], [70, 'query']]}, ['released']), ('regression: ninety second timer at one minute', {'timer_s': 90, 'events': [[0, 'berth_occ'], [60, 'query'], [89, 'query'], [90, 'query']]}, ['locked', 'locked', 'released']), ('regression: berth clears after release', {'timer_s': 60, 'events': [[0, 'berth_occ'], [60, 'query'], [65, 'berth_clr'], [70, 'query']]}, ['released', 'released']), ('control 24', {'timer_s': 90, 'events': [[30, 'query'], [60, 'berth_occ'], [120, 'overlap_occ'], [210, 'query'], [240, 'berth_clr'], [245, 'berth_occ'], [245, 'query'], [245, 'berth_clr'], [305, 'berth_occ'], [335, 'overlap_occ'], [395, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('regression: track circuit bob restarts nothing', {'timer_s': 60, 'events': [[0, 'berth_occ'], [40, 'berth_occ'], [60, 'query']]}, ['released']), ('control 1', {'timer_s': 45, 'events': [[5, 'overlap_occ'], [35, 'query'], [65, 'berth_clr'], [125, 'query'], [170, 'query'], [170, 'berth_clr'], [230, 'berth_occ'], [350, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 4', {'timer_s': 90, 'events': [[60, 'berth_clr'], [150, 'berth_occ'], [155, 'berth_occ'], [155, 'query']]}, ['locked']), ('control 7', {'timer_s': 45, 'events': [[5, 'query'], [65, 'overlap_occ'], [110, 'overlap_occ'], [170, 'query']]}, ['locked', 'locked'])], [('regression: track circuit bob restarts nothing', {'timer_s': 60, 'events': [[0, 'berth_occ'], [40, 'berth_occ'], [60, 'query']]}, ['released']), ('regression: ninety second timer at one minute', {'timer_s': 90, 'events': [[0, 'berth_occ'], [60, 'query'], [89, 'query'], [90, 'query']]}, ['locked', 'locked', 'released']), ('sampled regression 33', {'timer_s': 60, 'events': [[60, 'berth_occ'], [60, 'query'], [120, 'query'], [150, 'berth_occ'], [240, 'berth_clr'], [360, 'query']]}, ['locked', 'released', 'released']), ('control 62', {'timer_s': 90, 'events': [[0, 'berth_occ'], [30, 'berth_occ'], [75, 'query'], [120, 'query'], [150, 'overlap_occ'], [240, 'query'], [245, 'query'], [365, 'query']]}, ['locked', 'released', 'released', 'released', 'released']), ('regression: train stops at time zero', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_occ'], [60, 'query']]}, ['released']), ('control 12', {'timer_s': 120, 'events': [[60, 'berth_occ'], [65, 'query'], [70, 'query'], [70, 'query'], [75, 'berth_occ'], [80, 'berth_occ'], [125, 'berth_clr'], [125, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 15', {'timer_s': 120, 'events': [[60, 'berth_clr'], [105, 'berth_clr'], [110, 'berth_clr'], [115, 'berth_clr'], [175, 'query'], [175, 'berth_clr'], [235, 'query'], [265, 'overlap_occ'], [270, 'berth_clr'], [390, 'query']]}, ['locked', 'locked', 'locked']), ('sampled regression 18', {'timer_s': 90, 'events': [[0, 'query'], [0, 'query'], [30, 'berth_occ'], [120, 'overlap_occ'], [210, 'berth_clr'], [215, 'query'], [245, 'berth_occ'], [365, 'query']]}, ['locked', 'locked', 'released', 'released'])], [('regression: train stops at time zero', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_occ'], [60, 'query']]}, ['released']), ('regression: ninety second timer at one minute', {'timer_s': 90, 'events': [[0, 'berth_occ'], [60, 'query'], [89, 'query'], [90, 'query']]}, ['locked', 'locked', 'released']), ('control 24', {'timer_s': 90, 'events': [[30, 'query'], [60, 'berth_occ'], [120, 'overlap_occ'], [210, 'query'], [240, 'berth_clr'], [245, 'berth_occ'], [245, 'query'], [245, 'berth_clr'], [305, 'berth_occ'], [335, 'overlap_occ'], [395, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('regression: berth clears after release', {'timer_s': 60, 'events': [[0, 'berth_occ'], [60, 'query'], [65, 'berth_clr'], [70, 'query']]}, ['released', 'released']), ('boundary: overrun into the overlap', {'timer_s': 60, 'events': [[0, 'berth_occ'], [20, 'overlap_occ'], [120, 'query']]}, ['locked']), ('control 23', {'timer_s': 45, 'events': [[0, 'query'], [5, 'berth_occ'], [95, 'berth_occ'], [185, 'berth_occ'], [245, 'query']]}, ['locked', 'released']), ('control 26', {'timer_s': 60, 'events': [[30, 'query'], [60, 'query'], [150, 'overlap_occ'], [150, 'query']]}, ['locked', 'locked', 'locked']), ('control 29', {'timer_s': 90, 'events': [[90, 'overlap_occ'], [95, 'query'], [95, 'berth_occ'], [185, 'query'], [230, 'query'], [260, 'query'], [350, 'berth_occ'], [410, 'query']]}, ['locked', 'locked', 'locked', 'locked', 'locked'])], [('regression: berth clears after release', {'timer_s': 60, 'events': [[0, 'berth_occ'], [60, 'query'], [65, 'berth_clr'], [70, 'query']]}, ['released', 'released']), ('regression: ninety second timer at one minute', {'timer_s': 90, 'events': [[0, 'berth_occ'], [60, 'query'], [89, 'query'], [90, 'query']]}, ['locked', 'locked', 'released']), ('sampled regression 32', {'timer_s': 90, 'events': [[60, 'berth_occ'], [105, 'berth_clr'], [105, 'berth_occ'], [105, 'query'], [135, 'query'], [195, 'berth_clr'], [255, 'query']]}, ['locked', 'locked', 'released']), ('control 62', {'timer_s': 90, 'events': [[0, 'berth_occ'], [30, 'berth_occ'], [75, 'query'], [120, 'query'], [150, 'overlap_occ'], [240, 'query'], [245, 'query'], [365, 'query']]}, ['locked', 'released', 'released', 'released', 'released']), ('regression: expiry after a minute boundary', {'timer_s': 120, 'events': [[30, 'berth_occ'], [140, 'query'], [150, 'query']]}, ['locked', 'released']), ('control 34', {'timer_s': 60, 'events': [[5, 'query'], [35, 'query'], [80, 'berth_occ'], [170, 'berth_occ'], [260, 'berth_occ'], [320, 'berth_occ'], [350, 'overlap_occ'], [395, 'overlap_occ'], [440, 'query'], [500, 'query'], [560, 'query']]}, ['locked', 'locked', 'released', 'released', 'released']), ('control 37', {'timer_s': 120, 'events': [[30, 'query'], [60, 'overlap_occ'], [120, 'berth_occ'], [180, 'overlap_occ'], [185, 'overlap_occ'], [185, 'overlap_occ'], [245, 'query'], [275, 'query'], [280, 'overlap_occ'], [280, 'berth_occ'], [280, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 40', {'timer_s': 90, 'events': [[60, 'overlap_occ'], [90, 'query'], [135, 'berth_occ'], [195, 'overlap_occ'], [225, 'berth_occ'], [230, 'berth_clr'], [230, 'query']]}, ['locked', 'locked'])], [('regression: ninety second timer at one minute', {'timer_s': 90, 'events': [[0, 'berth_occ'], [60, 'query'], [89, 'query'], [90, 'query']]}, ['locked', 'locked', 'released']), ('regression: track circuit bob restarts nothing', {'timer_s': 60, 'events': [[0, 'berth_occ'], [40, 'berth_occ'], [60, 'query']]}, ['released']), ('control 24', {'timer_s': 90, 'events': [[30, 'query'], [60, 'berth_occ'], [120, 'overlap_occ'], [210, 'query'], [240, 'berth_clr'], [245, 'berth_occ'], [245, 'query'], [245, 'berth_clr'], [305, 'berth_occ'], [335, 'overlap_occ'], [395, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('regression: expiry exactly on time', {'timer_s': 60, 'events': [[10, 'berth_occ'], [70, 'query']]}, ['released']), ('regression: train stops at time zero', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_occ'], [60, 'query']]}, ['released']), ('control 45', {'timer_s': 60, 'events': [[60, 'query'], [120, 'query'], [150, 'overlap_occ'], [155, 'berth_occ'], [245, 'overlap_occ'], [290, 'berth_occ'], [380, 'berth_clr'], [470, 'overlap_occ'], [470, 'query'], [475, 'berth_occ'], [595, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 48', {'timer_s': 45, 'events': [[60, 'overlap_occ'], [150, 'berth_occ'], [180, 'overlap_occ'], [180, 'berth_occ'], [270, 'berth_clr'], [275, 'berth_clr'], [275, 'overlap_occ'], [275, 'query']]}, ['locked']), ('control 51', {'timer_s': 90, 'events': [[90, 'berth_occ'], [150, 'berth_clr'], [195, 'query'], [255, 'berth_occ'], [315, 'query'], [320, 'query'], [320, 'overlap_occ'], [440, 'query']]}, ['locked', 'locked', 'locked', 'locked'])]]
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):
    T = x['timer_s']
    start = None
    overran = False
    released = False
    out = []
    for t, ev in x['events']:
        if start is not None and not released and not overran and (t - start) // 60 >= T // 60:
            released = True
        if ev == 'berth_occ':
            if start is None:
                start = t
        elif ev == 'berth_clr':
            if not released:
                start = None
        elif ev == 'overlap_occ':
            if not released:
                overran = True
        elif ev == 'query':
            out.append('released' if released else 'locked')
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: expiry exactly on time', {'timer_s': 60, 'events': [[10, 'berth_occ'], [70, 'query']]}, ['released']), ('regression: ninety second timer at one minute', {'timer_s': 90, 'events': [[0, 'berth_occ'], [60, 'query'], [89, 'query'], [90, 'query']]}, ['locked', 'locked', 'released']), ('regression: berth clears after release', {'timer_s': 60, 'events': [[0, 'berth_occ'], [60, 'query'], [65, 'berth_clr'], [70, 'query']]}, ['released', 'released']), ('control 24', {'timer_s': 90, 'events': [[30, 'query'], [60, 'berth_occ'], [120, 'overlap_occ'], [210, 'query'], [240, 'berth_clr'], [245, 'berth_occ'], [245, 'query'], [245, 'berth_clr'], [305, 'berth_occ'], [335, 'overlap_occ'], [395, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('regression: track circuit bob restarts nothing', {'timer_s': 60, 'events': [[0, 'berth_occ'], [40, 'berth_occ'], [60, 'query']]}, ['released']), ('control 1', {'timer_s': 45, 'events': [[5, 'overlap_occ'], [35, 'query'], [65, 'berth_clr'], [125, 'query'], [170, 'query'], [170, 'berth_clr'], [230, 'berth_occ'], [350, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 4', {'timer_s': 90, 'events': [[60, 'berth_clr'], [150, 'berth_occ'], [155, 'berth_occ'], [155, 'query']]}, ['locked']), ('control 7', {'timer_s': 45, 'events': [[5, 'query'], [65, 'overlap_occ'], [110, 'overlap_occ'], [170, 'query']]}, ['locked', 'locked'])], [('regression: track circuit bob restarts nothing', {'timer_s': 60, 'events': [[0, 'berth_occ'], [40, 'berth_occ'], [60, 'query']]}, ['released']), ('regression: ninety second timer at one minute', {'timer_s': 90, 'events': [[0, 'berth_occ'], [60, 'query'], [89, 'query'], [90, 'query']]}, ['locked', 'locked', 'released']), ('sampled regression 33', {'timer_s': 60, 'events': [[60, 'berth_occ'], [60, 'query'], [120, 'query'], [150, 'berth_occ'], [240, 'berth_clr'], [360, 'query']]}, ['locked', 'released', 'released']), ('control 62', {'timer_s': 90, 'events': [[0, 'berth_occ'], [30, 'berth_occ'], [75, 'query'], [120, 'query'], [150, 'overlap_occ'], [240, 'query'], [245, 'query'], [365, 'query']]}, ['locked', 'released', 'released', 'released', 'released']), ('regression: train stops at time zero', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_occ'], [60, 'query']]}, ['released']), ('control 12', {'timer_s': 120, 'events': [[60, 'berth_occ'], [65, 'query'], [70, 'query'], [70, 'query'], [75, 'berth_occ'], [80, 'berth_occ'], [125, 'berth_clr'], [125, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 15', {'timer_s': 120, 'events': [[60, 'berth_clr'], [105, 'berth_clr'], [110, 'berth_clr'], [115, 'berth_clr'], [175, 'query'], [175, 'berth_clr'], [235, 'query'], [265, 'overlap_occ'], [270, 'berth_clr'], [390, 'query']]}, ['locked', 'locked', 'locked']), ('sampled regression 18', {'timer_s': 90, 'events': [[0, 'query'], [0, 'query'], [30, 'berth_occ'], [120, 'overlap_occ'], [210, 'berth_clr'], [215, 'query'], [245, 'berth_occ'], [365, 'query']]}, ['locked', 'locked', 'released', 'released'])], [('regression: train stops at time zero', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_occ'], [60, 'query']]}, ['released']), ('regression: ninety second timer at one minute', {'timer_s': 90, 'events': [[0, 'berth_occ'], [60, 'query'], [89, 'query'], [90, 'query']]}, ['locked', 'locked', 'released']), ('control 24', {'timer_s': 90, 'events': [[30, 'query'], [60, 'berth_occ'], [120, 'overlap_occ'], [210, 'query'], [240, 'berth_clr'], [245, 'berth_occ'], [245, 'query'], [245, 'berth_clr'], [305, 'berth_occ'], [335, 'overlap_occ'], [395, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('regression: berth clears after release', {'timer_s': 60, 'events': [[0, 'berth_occ'], [60, 'query'], [65, 'berth_clr'], [70, 'query']]}, ['released', 'released']), ('boundary: overrun into the overlap', {'timer_s': 60, 'events': [[0, 'berth_occ'], [20, 'overlap_occ'], [120, 'query']]}, ['locked']), ('control 23', {'timer_s': 45, 'events': [[0, 'query'], [5, 'berth_occ'], [95, 'berth_occ'], [185, 'berth_occ'], [245, 'query']]}, ['locked', 'released']), ('control 26', {'timer_s': 60, 'events': [[30, 'query'], [60, 'query'], [150, 'overlap_occ'], [150, 'query']]}, ['locked', 'locked', 'locked']), ('control 29', {'timer_s': 90, 'events': [[90, 'overlap_occ'], [95, 'query'], [95, 'berth_occ'], [185, 'query'], [230, 'query'], [260, 'query'], [350, 'berth_occ'], [410, 'query']]}, ['locked', 'locked', 'locked', 'locked', 'locked'])], [('regression: berth clears after release', {'timer_s': 60, 'events': [[0, 'berth_occ'], [60, 'query'], [65, 'berth_clr'], [70, 'query']]}, ['released', 'released']), ('regression: ninety second timer at one minute', {'timer_s': 90, 'events': [[0, 'berth_occ'], [60, 'query'], [89, 'query'], [90, 'query']]}, ['locked', 'locked', 'released']), ('sampled regression 32', {'timer_s': 90, 'events': [[60, 'berth_occ'], [105, 'berth_clr'], [105, 'berth_occ'], [105, 'query'], [135, 'query'], [195, 'berth_clr'], [255, 'query']]}, ['locked', 'locked', 'released']), ('control 62', {'timer_s': 90, 'events': [[0, 'berth_occ'], [30, 'berth_occ'], [75, 'query'], [120, 'query'], [150, 'overlap_occ'], [240, 'query'], [245, 'query'], [365, 'query']]}, ['locked', 'released', 'released', 'released', 'released']), ('regression: expiry after a minute boundary', {'timer_s': 120, 'events': [[30, 'berth_occ'], [140, 'query'], [150, 'query']]}, ['locked', 'released']), ('control 34', {'timer_s': 60, 'events': [[5, 'query'], [35, 'query'], [80, 'berth_occ'], [170, 'berth_occ'], [260, 'berth_occ'], [320, 'berth_occ'], [350, 'overlap_occ'], [395, 'overlap_occ'], [440, 'query'], [500, 'query'], [560, 'query']]}, ['locked', 'locked', 'released', 'released', 'released']), ('control 37', {'timer_s': 120, 'events': [[30, 'query'], [60, 'overlap_occ'], [120, 'berth_occ'], [180, 'overlap_occ'], [185, 'overlap_occ'], [185, 'overlap_occ'], [245, 'query'], [275, 'query'], [280, 'overlap_occ'], [280, 'berth_occ'], [280, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 40', {'timer_s': 90, 'events': [[60, 'overlap_occ'], [90, 'query'], [135, 'berth_occ'], [195, 'overlap_occ'], [225, 'berth_occ'], [230, 'berth_clr'], [230, 'query']]}, ['locked', 'locked'])], [('regression: ninety second timer at one minute', {'timer_s': 90, 'events': [[0, 'berth_occ'], [60, 'query'], [89, 'query'], [90, 'query']]}, ['locked', 'locked', 'released']), ('regression: track circuit bob restarts nothing', {'timer_s': 60, 'events': [[0, 'berth_occ'], [40, 'berth_occ'], [60, 'query']]}, ['released']), ('control 24', {'timer_s': 90, 'events': [[30, 'query'], [60, 'berth_occ'], [120, 'overlap_occ'], [210, 'query'], [240, 'berth_clr'], [245, 'berth_occ'], [245, 'query'], [245, 'berth_clr'], [305, 'berth_occ'], [335, 'overlap_occ'], [395, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('regression: expiry exactly on time', {'timer_s': 60, 'events': [[10, 'berth_occ'], [70, 'query']]}, ['released']), ('regression: train stops at time zero', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_occ'], [60, 'query']]}, ['released']), ('control 45', {'timer_s': 60, 'events': [[60, 'query'], [120, 'query'], [150, 'overlap_occ'], [155, 'berth_occ'], [245, 'overlap_occ'], [290, 'berth_occ'], [380, 'berth_clr'], [470, 'overlap_occ'], [470, 'query'], [475, 'berth_occ'], [595, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 48', {'timer_s': 45, 'events': [[60, 'overlap_occ'], [150, 'berth_occ'], [180, 'overlap_occ'], [180, 'berth_occ'], [270, 'berth_clr'], [275, 'berth_clr'], [275, 'overlap_occ'], [275, 'query']]}, ['locked']), ('control 51', {'timer_s': 90, 'events': [[90, 'berth_occ'], [150, 'berth_clr'], [195, 'query'], [255, 'berth_occ'], [315, 'query'], [320, 'query'], [320, 'overlap_occ'], [440, 'query']]}, ['locked', 'locked', 'locked', 'locked'])]]
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 overlap stays locked at the exact moment the timer expires.

The overlap beyond a signal is locked. The release timer starts at the first berth occupation; the overlap is released when an event time reaches start + timer_s while the train has not overrun into the overlap. A berth clear before release cancels the timer (a later occupation restarts it); after release it has no effect. Entering the overlap before release marks an overrun and blocks release. query appends locked or released.

split: open-access


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

N = 1
observations = []
def solve(x):
    T = x['timer_s']
    start = None
    overran = False
    released = False
    out = []
    for t, ev in x['events']:
        if start is not None and not released and not overran and t - start >= T:
            released = True
        if ev == 'berth_occ':
            start = t
        elif ev == 'berth_clr':
            if not released:
                start = None
        elif ev == 'overlap_occ':
            if not released:
                overran = True
        elif ev == 'query':
            out.append('released' if released else 'locked')
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: track circuit bob restarts nothing', {'timer_s': 60, 'events': [[0, 'berth_occ'], [40, 'berth_occ'], [60, 'query']]}, ['released']), ('sampled regression 80', {'timer_s': 120, 'events': [[5, 'berth_occ'], [35, 'query'], [65, 'berth_occ'], [155, 'berth_occ'], [155, 'berth_occ'], [215, 'query']]}, ['locked', 'released']), ('regression: train stops at time zero', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_occ'], [60, 'query']]}, ['released']), ('boundary: expiry exactly on time', {'timer_s': 60, 'events': [[10, 'berth_occ'], [70, 'query']]}, ['released']), ('boundary: train leaves before expiry', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_clr'], [90, 'query']]}, ['locked']), ('control 1', {'timer_s': 45, 'events': [[5, 'overlap_occ'], [35, 'query'], [65, 'berth_clr'], [125, 'query'], [170, 'query'], [170, 'berth_clr'], [230, 'berth_occ'], [350, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 4', {'timer_s': 90, 'events': [[60, 'berth_clr'], [150, 'berth_occ'], [155, 'berth_occ'], [155, 'query']]}, ['locked']), ('control 7', {'timer_s': 45, 'events': [[5, 'query'], [65, 'overlap_occ'], [110, 'overlap_occ'], [170, 'query']]}, ['locked', 'locked'])], [('regression: train stops at time zero', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_occ'], [60, 'query']]}, ['released']), ('sampled regression 46', {'timer_s': 120, 'events': [[90, 'berth_clr'], [120, 'berth_clr'], [120, 'berth_occ'], [150, 'query'], [180, 'berth_occ'], [270, 'berth_occ'], [315, 'overlap_occ'], [375, 'query']]}, ['locked', 'released']), ('regression: track circuit bob restarts nothing', {'timer_s': 60, 'events': [[0, 'berth_occ'], [40, 'berth_occ'], [60, 'query']]}, ['released']), ('boundary: train leaves before expiry', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_clr'], [90, 'query']]}, ['locked']), ('boundary: berth clears after release', {'timer_s': 60, 'events': [[0, 'berth_occ'], [60, 'query'], [65, 'berth_clr'], [70, 'query']]}, ['released', 'released']), ('control 12', {'timer_s': 120, 'events': [[60, 'berth_occ'], [65, 'query'], [70, 'query'], [70, 'query'], [75, 'berth_occ'], [80, 'berth_occ'], [125, 'berth_clr'], [125, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 15', {'timer_s': 120, 'events': [[60, 'berth_clr'], [105, 'berth_clr'], [110, 'berth_clr'], [115, 'berth_clr'], [175, 'query'], [175, 'berth_clr'], [235, 'query'], [265, 'overlap_occ'], [270, 'berth_clr'], [390, 'query']]}, ['locked', 'locked', 'locked']), ('control 18', {'timer_s': 90, 'events': [[0, 'query'], [0, 'query'], [30, 'berth_occ'], [120, 'overlap_occ'], [210, 'berth_clr'], [215, 'query'], [245, 'berth_occ'], [365, 'query']]}, ['locked', 'locked', 'released', 'released'])], [('regression: track circuit bob restarts nothing', {'timer_s': 60, 'events': [[0, 'berth_occ'], [40, 'berth_occ'], [60, 'query']]}, ['released']), ('regression: train stops at time zero', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_occ'], [60, 'query']]}, ['released']), ('boundary: berth clears after release', {'timer_s': 60, 'events': [[0, 'berth_occ'], [60, 'query'], [65, 'berth_clr'], [70, 'query']]}, ['released', 'released']), ('boundary: overrun into the overlap', {'timer_s': 60, 'events': [[0, 'berth_occ'], [20, 'overlap_occ'], [120, 'query']]}, ['locked']), ('boundary: ninety second timer at one minute', {'timer_s': 90, 'events': [[0, 'berth_occ'], [60, 'query'], [89, 'query'], [90, 'query']]}, ['locked', 'locked', 'released']), ('control 23', {'timer_s': 45, 'events': [[0, 'query'], [5, 'berth_occ'], [95, 'berth_occ'], [185, 'berth_occ'], [245, 'query']]}, ['locked', 'released']), ('control 26', {'timer_s': 60, 'events': [[30, 'query'], [60, 'query'], [150, 'overlap_occ'], [150, 'query']]}, ['locked', 'locked', 'locked']), ('control 29', {'timer_s': 90, 'events': [[90, 'overlap_occ'], [95, 'query'], [95, 'berth_occ'], [185, 'query'], [230, 'query'], [260, 'query'], [350, 'berth_occ'], [410, 'query']]}, ['locked', 'locked', 'locked', 'locked', 'locked'])], [('regression: train stops at time zero', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_occ'], [60, 'query']]}, ['released']), ('regression: track circuit bob restarts nothing', {'timer_s': 60, 'events': [[0, 'berth_occ'], [40, 'berth_occ'], [60, 'query']]}, ['released']), ('boundary: ninety second timer at one minute', {'timer_s': 90, 'events': [[0, 'berth_occ'], [60, 'query'], [89, 'query'], [90, 'query']]}, ['locked', 'locked', 'released']), ('boundary: expiry after a minute boundary', {'timer_s': 120, 'events': [[30, 'berth_occ'], [140, 'query'], [150, 'query']]}, ['locked', 'released']), ('boundary: expiry exactly on time', {'timer_s': 60, 'events': [[10, 'berth_occ'], [70, 'query']]}, ['released']), ('control 34', {'timer_s': 60, 'events': [[5, 'query'], [35, 'query'], [80, 'berth_occ'], [170, 'berth_occ'], [260, 'berth_occ'], [320, 'berth_occ'], [350, 'overlap_occ'], [395, 'overlap_occ'], [440, 'query'], [500, 'query'], [560, 'query']]}, ['locked', 'locked', 'released', 'released', 'released']), ('control 37', {'timer_s': 120, 'events': [[30, 'query'], [60, 'overlap_occ'], [120, 'berth_occ'], [180, 'overlap_occ'], [185, 'overlap_occ'], [185, 'overlap_occ'], [245, 'query'], [275, 'query'], [280, 'overlap_occ'], [280, 'berth_occ'], [280, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 40', {'timer_s': 90, 'events': [[60, 'overlap_occ'], [90, 'query'], [135, 'berth_occ'], [195, 'overlap_occ'], [225, 'berth_occ'], [230, 'berth_clr'], [230, 'query']]}, ['locked', 'locked'])], [('regression: track circuit bob restarts nothing', {'timer_s': 60, 'events': [[0, 'berth_occ'], [40, 'berth_occ'], [60, 'query']]}, ['released']), ('sampled regression 80', {'timer_s': 120, 'events': [[5, 'berth_occ'], [35, 'query'], [65, 'berth_occ'], [155, 'berth_occ'], [155, 'berth_occ'], [215, 'query']]}, ['locked', 'released']), ('regression: train stops at time zero', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_occ'], [60, 'query']]}, ['released']), ('boundary: expiry exactly on time', {'timer_s': 60, 'events': [[10, 'berth_occ'], [70, 'query']]}, ['released']), ('boundary: train leaves before expiry', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_clr'], [90, 'query']]}, ['locked']), ('control 45', {'timer_s': 60, 'events': [[60, 'query'], [120, 'query'], [150, 'overlap_occ'], [155, 'berth_occ'], [245, 'overlap_occ'], [290, 'berth_occ'], [380, 'berth_clr'], [470, 'overlap_occ'], [470, 'query'], [475, 'berth_occ'], [595, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 48', {'timer_s': 45, 'events': [[60, 'overlap_occ'], [150, 'berth_occ'], [180, 'overlap_occ'], [180, 'berth_occ'], [270, 'berth_clr'], [275, 'berth_clr'], [275, 'overlap_occ'], [275, 'query']]}, ['locked']), ('control 51', {'timer_s': 90, 'events': [[90, 'berth_occ'], [150, 'berth_clr'], [195, 'query'], [255, 'berth_occ'], [315, 'query'], [320, 'query'], [320, 'overlap_occ'], [440, 'query']]}, ['locked', 'locked', 'locked', 'locked'])]]
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):
    T = x['timer_s']
    start = None
    overran = False
    released = False
    out = []
    for t, ev in x['events']:
        if start is not None and not released and not overran and t - start >= T:
            released = True
        if ev == 'berth_occ':
            start = start or t
        elif ev == 'berth_clr':
            if not released:
                start = None
        elif ev == 'overlap_occ':
            if not released:
                overran = True
        elif ev == 'query':
            out.append('released' if released else 'locked')
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: track circuit bob restarts nothing', {'timer_s': 60, 'events': [[0, 'berth_occ'], [40, 'berth_occ'], [60, 'query']]}, ['released']), ('sampled regression 80', {'timer_s': 120, 'events': [[5, 'berth_occ'], [35, 'query'], [65, 'berth_occ'], [155, 'berth_occ'], [155, 'berth_occ'], [215, 'query']]}, ['locked', 'released']), ('regression: train stops at time zero', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_occ'], [60, 'query']]}, ['released']), ('boundary: expiry exactly on time', {'timer_s': 60, 'events': [[10, 'berth_occ'], [70, 'query']]}, ['released']), ('boundary: train leaves before expiry', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_clr'], [90, 'query']]}, ['locked']), ('control 1', {'timer_s': 45, 'events': [[5, 'overlap_occ'], [35, 'query'], [65, 'berth_clr'], [125, 'query'], [170, 'query'], [170, 'berth_clr'], [230, 'berth_occ'], [350, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 4', {'timer_s': 90, 'events': [[60, 'berth_clr'], [150, 'berth_occ'], [155, 'berth_occ'], [155, 'query']]}, ['locked']), ('control 7', {'timer_s': 45, 'events': [[5, 'query'], [65, 'overlap_occ'], [110, 'overlap_occ'], [170, 'query']]}, ['locked', 'locked'])], [('regression: train stops at time zero', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_occ'], [60, 'query']]}, ['released']), ('sampled regression 46', {'timer_s': 120, 'events': [[90, 'berth_clr'], [120, 'berth_clr'], [120, 'berth_occ'], [150, 'query'], [180, 'berth_occ'], [270, 'berth_occ'], [315, 'overlap_occ'], [375, 'query']]}, ['locked', 'released']), ('regression: track circuit bob restarts nothing', {'timer_s': 60, 'events': [[0, 'berth_occ'], [40, 'berth_occ'], [60, 'query']]}, ['released']), ('boundary: train leaves before expiry', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_clr'], [90, 'query']]}, ['locked']), ('boundary: berth clears after release', {'timer_s': 60, 'events': [[0, 'berth_occ'], [60, 'query'], [65, 'berth_clr'], [70, 'query']]}, ['released', 'released']), ('control 12', {'timer_s': 120, 'events': [[60, 'berth_occ'], [65, 'query'], [70, 'query'], [70, 'query'], [75, 'berth_occ'], [80, 'berth_occ'], [125, 'berth_clr'], [125, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 15', {'timer_s': 120, 'events': [[60, 'berth_clr'], [105, 'berth_clr'], [110, 'berth_clr'], [115, 'berth_clr'], [175, 'query'], [175, 'berth_clr'], [235, 'query'], [265, 'overlap_occ'], [270, 'berth_clr'], [390, 'query']]}, ['locked', 'locked', 'locked']), ('control 18', {'timer_s': 90, 'events': [[0, 'query'], [0, 'query'], [30, 'berth_occ'], [120, 'overlap_occ'], [210, 'berth_clr'], [215, 'query'], [245, 'berth_occ'], [365, 'query']]}, ['locked', 'locked', 'released', 'released'])], [('regression: track circuit bob restarts nothing', {'timer_s': 60, 'events': [[0, 'berth_occ'], [40, 'berth_occ'], [60, 'query']]}, ['released']), ('regression: train stops at time zero', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_occ'], [60, 'query']]}, ['released']), ('boundary: berth clears after release', {'timer_s': 60, 'events': [[0, 'berth_occ'], [60, 'query'], [65, 'berth_clr'], [70, 'query']]}, ['released', 'released']), ('boundary: overrun into the overlap', {'timer_s': 60, 'events': [[0, 'berth_occ'], [20, 'overlap_occ'], [120, 'query']]}, ['locked']), ('boundary: ninety second timer at one minute', {'timer_s': 90, 'events': [[0, 'berth_occ'], [60, 'query'], [89, 'query'], [90, 'query']]}, ['locked', 'locked', 'released']), ('control 23', {'timer_s': 45, 'events': [[0, 'query'], [5, 'berth_occ'], [95, 'berth_occ'], [185, 'berth_occ'], [245, 'query']]}, ['locked', 'released']), ('control 26', {'timer_s': 60, 'events': [[30, 'query'], [60, 'query'], [150, 'overlap_occ'], [150, 'query']]}, ['locked', 'locked', 'locked']), ('control 29', {'timer_s': 90, 'events': [[90, 'overlap_occ'], [95, 'query'], [95, 'berth_occ'], [185, 'query'], [230, 'query'], [260, 'query'], [350, 'berth_occ'], [410, 'query']]}, ['locked', 'locked', 'locked', 'locked', 'locked'])], [('regression: train stops at time zero', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_occ'], [60, 'query']]}, ['released']), ('regression: track circuit bob restarts nothing', {'timer_s': 60, 'events': [[0, 'berth_occ'], [40, 'berth_occ'], [60, 'query']]}, ['released']), ('boundary: ninety second timer at one minute', {'timer_s': 90, 'events': [[0, 'berth_occ'], [60, 'query'], [89, 'query'], [90, 'query']]}, ['locked', 'locked', 'released']), ('boundary: expiry after a minute boundary', {'timer_s': 120, 'events': [[30, 'berth_occ'], [140, 'query'], [150, 'query']]}, ['locked', 'released']), ('boundary: expiry exactly on time', {'timer_s': 60, 'events': [[10, 'berth_occ'], [70, 'query']]}, ['released']), ('control 34', {'timer_s': 60, 'events': [[5, 'query'], [35, 'query'], [80, 'berth_occ'], [170, 'berth_occ'], [260, 'berth_occ'], [320, 'berth_occ'], [350, 'overlap_occ'], [395, 'overlap_occ'], [440, 'query'], [500, 'query'], [560, 'query']]}, ['locked', 'locked', 'released', 'released', 'released']), ('control 37', {'timer_s': 120, 'events': [[30, 'query'], [60, 'overlap_occ'], [120, 'berth_occ'], [180, 'overlap_occ'], [185, 'overlap_occ'], [185, 'overlap_occ'], [245, 'query'], [275, 'query'], [280, 'overlap_occ'], [280, 'berth_occ'], [280, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 40', {'timer_s': 90, 'events': [[60, 'overlap_occ'], [90, 'query'], [135, 'berth_occ'], [195, 'overlap_occ'], [225, 'berth_occ'], [230, 'berth_clr'], [230, 'query']]}, ['locked', 'locked'])], [('regression: track circuit bob restarts nothing', {'timer_s': 60, 'events': [[0, 'berth_occ'], [40, 'berth_occ'], [60, 'query']]}, ['released']), ('sampled regression 80', {'timer_s': 120, 'events': [[5, 'berth_occ'], [35, 'query'], [65, 'berth_occ'], [155, 'berth_occ'], [155, 'berth_occ'], [215, 'query']]}, ['locked', 'released']), ('regression: train stops at time zero', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_occ'], [60, 'query']]}, ['released']), ('boundary: expiry exactly on time', {'timer_s': 60, 'events': [[10, 'berth_occ'], [70, 'query']]}, ['released']), ('boundary: train leaves before expiry', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_clr'], [90, 'query']]}, ['locked']), ('control 45', {'timer_s': 60, 'events': [[60, 'query'], [120, 'query'], [150, 'overlap_occ'], [155, 'berth_occ'], [245, 'overlap_occ'], [290, 'berth_occ'], [380, 'berth_clr'], [470, 'overlap_occ'], [470, 'query'], [475, 'berth_occ'], [595, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 48', {'timer_s': 45, 'events': [[60, 'overlap_occ'], [150, 'berth_occ'], [180, 'overlap_occ'], [180, 'berth_occ'], [270, 'berth_clr'], [275, 'berth_clr'], [275, 'overlap_occ'], [275, 'query']]}, ['locked']), ('control 51', {'timer_s': 90, 'events': [[90, 'berth_occ'], [150, 'berth_clr'], [195, 'query'], [255, 'berth_occ'], [315, 'query'], [320, 'query'], [320, 'overlap_occ'], [440, 'query']]}, ['locked', 'locked', 'locked', 'locked'])]]
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 bobbing berth track circuit keeps pushing the overlap release back.

The overlap beyond a signal is locked. The release timer starts at the first berth occupation; the overlap is released when an event time reaches start + timer_s while the train has not overrun into the overlap. A berth clear before release cancels the timer (a later occupation restarts it); after release it has no effect. Entering the overlap before release marks an overrun and blocks release. query appends locked or released.

split: open-access


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

N = 1
observations = []
def solve(x):
    T = x['timer_s']
    start = None
    overran = False
    released = False
    out = []
    for t, ev in x['events']:
        if start is not None and not released and not overran and t - start >= T:
            released = True
        if ev == 'berth_occ':
            if start is None:
                start = t
        elif ev == 'berth_clr':
            pass
        elif ev == 'overlap_occ':
            if not released:
                overran = True
        elif ev == 'query':
            out.append('released' if released else 'locked')
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: train leaves before expiry', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_clr'], [90, 'query']]}, ['locked']), ('boundary: berth clears after release', {'timer_s': 60, 'events': [[0, 'berth_occ'], [60, 'query'], [65, 'berth_clr'], [70, 'query']]}, ['released', 'released']), ('sampled regression 51', {'timer_s': 90, 'events': [[90, 'berth_occ'], [150, 'berth_clr'], [195, 'query'], [255, 'berth_occ'], [315, 'query'], [320, 'query'], [320, 'overlap_occ'], [440, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 18', {'timer_s': 90, 'events': [[0, 'query'], [0, 'query'], [30, 'berth_occ'], [120, 'overlap_occ'], [210, 'berth_clr'], [215, 'query'], [245, 'berth_occ'], [365, 'query']]}, ['locked', 'locked', 'released', 'released']), ('boundary: expiry exactly on time', {'timer_s': 60, 'events': [[10, 'berth_occ'], [70, 'query']]}, ['released']), ('control 1', {'timer_s': 45, 'events': [[5, 'overlap_occ'], [35, 'query'], [65, 'berth_clr'], [125, 'query'], [170, 'query'], [170, 'berth_clr'], [230, 'berth_occ'], [350, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 4', {'timer_s': 90, 'events': [[60, 'berth_clr'], [150, 'berth_occ'], [155, 'berth_occ'], [155, 'query']]}, ['locked']), ('control 7', {'timer_s': 45, 'events': [[5, 'query'], [65, 'overlap_occ'], [110, 'overlap_occ'], [170, 'query']]}, ['locked', 'locked'])], [('regression: train leaves before expiry', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_clr'], [90, 'query']]}, ['locked']), ('boundary: berth clears after release', {'timer_s': 60, 'events': [[0, 'berth_occ'], [60, 'query'], [65, 'berth_clr'], [70, 'query']]}, ['released', 'released']), ('control 59', {'timer_s': 45, 'events': [[30, 'query'], [120, 'query'], [120, 'berth_occ'], [210, 'query'], [215, 'berth_clr'], [215, 'berth_clr'], [215, 'berth_clr'], [275, 'query']]}, ['locked', 'locked', 'released', 'released']), ('boundary: train stops at time zero', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_occ'], [60, 'query']]}, ['released']), ('boundary: overrun into the overlap', {'timer_s': 60, 'events': [[0, 'berth_occ'], [20, 'overlap_occ'], [120, 'query']]}, ['locked']), ('control 12', {'timer_s': 120, 'events': [[60, 'berth_occ'], [65, 'query'], [70, 'query'], [70, 'query'], [75, 'berth_occ'], [80, 'berth_occ'], [125, 'berth_clr'], [125, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 15', {'timer_s': 120, 'events': [[60, 'berth_clr'], [105, 'berth_clr'], [110, 'berth_clr'], [115, 'berth_clr'], [175, 'query'], [175, 'berth_clr'], [235, 'query'], [265, 'overlap_occ'], [270, 'berth_clr'], [390, 'query']]}, ['locked', 'locked', 'locked']), ('control 18', {'timer_s': 90, 'events': [[0, 'query'], [0, 'query'], [30, 'berth_occ'], [120, 'overlap_occ'], [210, 'berth_clr'], [215, 'query'], [245, 'berth_occ'], [365, 'query']]}, ['locked', 'locked', 'released', 'released'])], [('regression: train leaves before expiry', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_clr'], [90, 'query']]}, ['locked']), ('boundary: berth clears after release', {'timer_s': 60, 'events': [[0, 'berth_occ'], [60, 'query'], [65, 'berth_clr'], [70, 'query']]}, ['released', 'released']), ('sampled regression 9', {'timer_s': 60, 'events': [[5, 'berth_occ'], [5, 'query'], [35, 'berth_clr'], [155, 'query']]}, ['locked', 'locked']), ('control 78', {'timer_s': 90, 'events': [[0, 'query'], [90, 'berth_occ'], [120, 'berth_occ'], [120, 'query'], [210, 'berth_clr'], [210, 'query']]}, ['locked', 'locked', 'released']), ('boundary: overrun into the overlap', {'timer_s': 60, 'events': [[0, 'berth_occ'], [20, 'overlap_occ'], [120, 'query']]}, ['locked']), ('control 23', {'timer_s': 45, 'events': [[0, 'query'], [5, 'berth_occ'], [95, 'berth_occ'], [185, 'berth_occ'], [245, 'query']]}, ['locked', 'released']), ('control 26', {'timer_s': 60, 'events': [[30, 'query'], [60, 'query'], [150, 'overlap_occ'], [150, 'query']]}, ['locked', 'locked', 'locked']), ('control 29', {'timer_s': 90, 'events': [[90, 'overlap_occ'], [95, 'query'], [95, 'berth_occ'], [185, 'query'], [230, 'query'], [260, 'query'], [350, 'berth_occ'], [410, 'query']]}, ['locked', 'locked', 'locked', 'locked', 'locked'])], [('regression: train leaves before expiry', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_clr'], [90, 'query']]}, ['locked']), ('boundary: berth clears after release', {'timer_s': 60, 'events': [[0, 'berth_occ'], [60, 'query'], [65, 'berth_clr'], [70, 'query']]}, ['released', 'released']), ('sampled regression 75', {'timer_s': 90, 'events': [[0, 'berth_occ'], [0, 'query'], [60, 'berth_clr'], [120, 'query'], [180, 'overlap_occ'], [225, 'berth_occ'], [270, 'query'], [275, 'berth_occ'], [320, 'overlap_occ'], [380, 'berth_occ'], [380, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 33', {'timer_s': 60, 'events': [[60, 'berth_occ'], [60, 'query'], [120, 'query'], [150, 'berth_occ'], [240, 'berth_clr'], [360, 'query']]}, ['locked', 'released', 'released']), ('boundary: ninety second timer at one minute', {'timer_s': 90, 'events': [[0, 'berth_occ'], [60, 'query'], [89, 'query'], [90, 'query']]}, ['locked', 'locked', 'released']), ('control 34', {'timer_s': 60, 'events': [[5, 'query'], [35, 'query'], [80, 'berth_occ'], [170, 'berth_occ'], [260, 'berth_occ'], [320, 'berth_occ'], [350, 'overlap_occ'], [395, 'overlap_occ'], [440, 'query'], [500, 'query'], [560, 'query']]}, ['locked', 'locked', 'released', 'released', 'released']), ('control 37', {'timer_s': 120, 'events': [[30, 'query'], [60, 'overlap_occ'], [120, 'berth_occ'], [180, 'overlap_occ'], [185, 'overlap_occ'], [185, 'overlap_occ'], [245, 'query'], [275, 'query'], [280, 'overlap_occ'], [280, 'berth_occ'], [280, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 40', {'timer_s': 90, 'events': [[60, 'overlap_occ'], [90, 'query'], [135, 'berth_occ'], [195, 'overlap_occ'], [225, 'berth_occ'], [230, 'berth_clr'], [230, 'query']]}, ['locked', 'locked'])], [('regression: train leaves before expiry', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_clr'], [90, 'query']]}, ['locked']), ('boundary: berth clears after release', {'timer_s': 60, 'events': [[0, 'berth_occ'], [60, 'query'], [65, 'berth_clr'], [70, 'query']]}, ['released', 'released']), ('sampled regression 8', {'timer_s': 120, 'events': [[30, 'berth_occ'], [120, 'berth_clr'], [165, 'berth_clr'], [170, 'berth_occ'], [215, 'berth_clr'], [215, 'overlap_occ'], [305, 'query'], [305, 'berth_occ'], [395, 'berth_occ'], [440, 'berth_occ'], [560, 'query']]}, ['locked', 'locked']), ('control 66', {'timer_s': 90, 'events': [[5, 'query'], [65, 'berth_occ'], [155, 'overlap_occ'], [160, 'overlap_occ'], [160, 'berth_occ'], [165, 'berth_occ'], [210, 'berth_occ'], [210, 'berth_clr'], [215, 'overlap_occ'], [275, 'overlap_occ'], [275, 'query']]}, ['locked', 'released']), ('boundary: expiry exactly on time', {'timer_s': 60, 'events': [[10, 'berth_occ'], [70, 'query']]}, ['released']), ('control 45', {'timer_s': 60, 'events': [[60, 'query'], [120, 'query'], [150, 'overlap_occ'], [155, 'berth_occ'], [245, 'overlap_occ'], [290, 'berth_occ'], [380, 'berth_clr'], [470, 'overlap_occ'], [470, 'query'], [475, 'berth_occ'], [595, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 48', {'timer_s': 45, 'events': [[60, 'overlap_occ'], [150, 'berth_occ'], [180, 'overlap_occ'], [180, 'berth_occ'], [270, 'berth_clr'], [275, 'berth_clr'], [275, 'overlap_occ'], [275, 'query']]}, ['locked']), ('sampled regression 51', {'timer_s': 90, 'events': [[90, 'berth_occ'], [150, 'berth_clr'], [195, 'query'], [255, 'berth_occ'], [315, 'query'], [320, 'query'], [320, 'overlap_occ'], [440, 'query']]}, ['locked', 'locked', 'locked', 'locked'])]]
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):
    T = x['timer_s']
    start = None
    overran = False
    released = False
    out = []
    for t, ev in x['events']:
        if start is not None and not released and not overran and t - start >= T:
            released = True
        if ev == 'berth_occ':
            if start is None:
                start = t
        elif ev == 'berth_clr':
            start = None
            released = False
        elif ev == 'overlap_occ':
            if not released:
                overran = True
        elif ev == 'query':
            out.append('released' if released else 'locked')
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: train leaves before expiry', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_clr'], [90, 'query']]}, ['locked']), ('boundary: berth clears after release', {'timer_s': 60, 'events': [[0, 'berth_occ'], [60, 'query'], [65, 'berth_clr'], [70, 'query']]}, ['released', 'released']), ('sampled regression 51', {'timer_s': 90, 'events': [[90, 'berth_occ'], [150, 'berth_clr'], [195, 'query'], [255, 'berth_occ'], [315, 'query'], [320, 'query'], [320, 'overlap_occ'], [440, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 18', {'timer_s': 90, 'events': [[0, 'query'], [0, 'query'], [30, 'berth_occ'], [120, 'overlap_occ'], [210, 'berth_clr'], [215, 'query'], [245, 'berth_occ'], [365, 'query']]}, ['locked', 'locked', 'released', 'released']), ('boundary: expiry exactly on time', {'timer_s': 60, 'events': [[10, 'berth_occ'], [70, 'query']]}, ['released']), ('control 1', {'timer_s': 45, 'events': [[5, 'overlap_occ'], [35, 'query'], [65, 'berth_clr'], [125, 'query'], [170, 'query'], [170, 'berth_clr'], [230, 'berth_occ'], [350, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 4', {'timer_s': 90, 'events': [[60, 'berth_clr'], [150, 'berth_occ'], [155, 'berth_occ'], [155, 'query']]}, ['locked']), ('control 7', {'timer_s': 45, 'events': [[5, 'query'], [65, 'overlap_occ'], [110, 'overlap_occ'], [170, 'query']]}, ['locked', 'locked'])], [('regression: train leaves before expiry', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_clr'], [90, 'query']]}, ['locked']), ('boundary: berth clears after release', {'timer_s': 60, 'events': [[0, 'berth_occ'], [60, 'query'], [65, 'berth_clr'], [70, 'query']]}, ['released', 'released']), ('control 59', {'timer_s': 45, 'events': [[30, 'query'], [120, 'query'], [120, 'berth_occ'], [210, 'query'], [215, 'berth_clr'], [215, 'berth_clr'], [215, 'berth_clr'], [275, 'query']]}, ['locked', 'locked', 'released', 'released']), ('boundary: train stops at time zero', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_occ'], [60, 'query']]}, ['released']), ('boundary: overrun into the overlap', {'timer_s': 60, 'events': [[0, 'berth_occ'], [20, 'overlap_occ'], [120, 'query']]}, ['locked']), ('control 12', {'timer_s': 120, 'events': [[60, 'berth_occ'], [65, 'query'], [70, 'query'], [70, 'query'], [75, 'berth_occ'], [80, 'berth_occ'], [125, 'berth_clr'], [125, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 15', {'timer_s': 120, 'events': [[60, 'berth_clr'], [105, 'berth_clr'], [110, 'berth_clr'], [115, 'berth_clr'], [175, 'query'], [175, 'berth_clr'], [235, 'query'], [265, 'overlap_occ'], [270, 'berth_clr'], [390, 'query']]}, ['locked', 'locked', 'locked']), ('control 18', {'timer_s': 90, 'events': [[0, 'query'], [0, 'query'], [30, 'berth_occ'], [120, 'overlap_occ'], [210, 'berth_clr'], [215, 'query'], [245, 'berth_occ'], [365, 'query']]}, ['locked', 'locked', 'released', 'released'])], [('regression: train leaves before expiry', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_clr'], [90, 'query']]}, ['locked']), ('boundary: berth clears after release', {'timer_s': 60, 'events': [[0, 'berth_occ'], [60, 'query'], [65, 'berth_clr'], [70, 'query']]}, ['released', 'released']), ('sampled regression 9', {'timer_s': 60, 'events': [[5, 'berth_occ'], [5, 'query'], [35, 'berth_clr'], [155, 'query']]}, ['locked', 'locked']), ('control 78', {'timer_s': 90, 'events': [[0, 'query'], [90, 'berth_occ'], [120, 'berth_occ'], [120, 'query'], [210, 'berth_clr'], [210, 'query']]}, ['locked', 'locked', 'released']), ('boundary: overrun into the overlap', {'timer_s': 60, 'events': [[0, 'berth_occ'], [20, 'overlap_occ'], [120, 'query']]}, ['locked']), ('control 23', {'timer_s': 45, 'events': [[0, 'query'], [5, 'berth_occ'], [95, 'berth_occ'], [185, 'berth_occ'], [245, 'query']]}, ['locked', 'released']), ('control 26', {'timer_s': 60, 'events': [[30, 'query'], [60, 'query'], [150, 'overlap_occ'], [150, 'query']]}, ['locked', 'locked', 'locked']), ('control 29', {'timer_s': 90, 'events': [[90, 'overlap_occ'], [95, 'query'], [95, 'berth_occ'], [185, 'query'], [230, 'query'], [260, 'query'], [350, 'berth_occ'], [410, 'query']]}, ['locked', 'locked', 'locked', 'locked', 'locked'])], [('regression: train leaves before expiry', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_clr'], [90, 'query']]}, ['locked']), ('boundary: berth clears after release', {'timer_s': 60, 'events': [[0, 'berth_occ'], [60, 'query'], [65, 'berth_clr'], [70, 'query']]}, ['released', 'released']), ('sampled regression 75', {'timer_s': 90, 'events': [[0, 'berth_occ'], [0, 'query'], [60, 'berth_clr'], [120, 'query'], [180, 'overlap_occ'], [225, 'berth_occ'], [270, 'query'], [275, 'berth_occ'], [320, 'overlap_occ'], [380, 'berth_occ'], [380, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 33', {'timer_s': 60, 'events': [[60, 'berth_occ'], [60, 'query'], [120, 'query'], [150, 'berth_occ'], [240, 'berth_clr'], [360, 'query']]}, ['locked', 'released', 'released']), ('boundary: ninety second timer at one minute', {'timer_s': 90, 'events': [[0, 'berth_occ'], [60, 'query'], [89, 'query'], [90, 'query']]}, ['locked', 'locked', 'released']), ('control 34', {'timer_s': 60, 'events': [[5, 'query'], [35, 'query'], [80, 'berth_occ'], [170, 'berth_occ'], [260, 'berth_occ'], [320, 'berth_occ'], [350, 'overlap_occ'], [395, 'overlap_occ'], [440, 'query'], [500, 'query'], [560, 'query']]}, ['locked', 'locked', 'released', 'released', 'released']), ('control 37', {'timer_s': 120, 'events': [[30, 'query'], [60, 'overlap_occ'], [120, 'berth_occ'], [180, 'overlap_occ'], [185, 'overlap_occ'], [185, 'overlap_occ'], [245, 'query'], [275, 'query'], [280, 'overlap_occ'], [280, 'berth_occ'], [280, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 40', {'timer_s': 90, 'events': [[60, 'overlap_occ'], [90, 'query'], [135, 'berth_occ'], [195, 'overlap_occ'], [225, 'berth_occ'], [230, 'berth_clr'], [230, 'query']]}, ['locked', 'locked'])], [('regression: train leaves before expiry', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_clr'], [90, 'query']]}, ['locked']), ('boundary: berth clears after release', {'timer_s': 60, 'events': [[0, 'berth_occ'], [60, 'query'], [65, 'berth_clr'], [70, 'query']]}, ['released', 'released']), ('sampled regression 8', {'timer_s': 120, 'events': [[30, 'berth_occ'], [120, 'berth_clr'], [165, 'berth_clr'], [170, 'berth_occ'], [215, 'berth_clr'], [215, 'overlap_occ'], [305, 'query'], [305, 'berth_occ'], [395, 'berth_occ'], [440, 'berth_occ'], [560, 'query']]}, ['locked', 'locked']), ('control 66', {'timer_s': 90, 'events': [[5, 'query'], [65, 'berth_occ'], [155, 'overlap_occ'], [160, 'overlap_occ'], [160, 'berth_occ'], [165, 'berth_occ'], [210, 'berth_occ'], [210, 'berth_clr'], [215, 'overlap_occ'], [275, 'overlap_occ'], [275, 'query']]}, ['locked', 'released']), ('boundary: expiry exactly on time', {'timer_s': 60, 'events': [[10, 'berth_occ'], [70, 'query']]}, ['released']), ('control 45', {'timer_s': 60, 'events': [[60, 'query'], [120, 'query'], [150, 'overlap_occ'], [155, 'berth_occ'], [245, 'overlap_occ'], [290, 'berth_occ'], [380, 'berth_clr'], [470, 'overlap_occ'], [470, 'query'], [475, 'berth_occ'], [595, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 48', {'timer_s': 45, 'events': [[60, 'overlap_occ'], [150, 'berth_occ'], [180, 'overlap_occ'], [180, 'berth_occ'], [270, 'berth_clr'], [275, 'berth_clr'], [275, 'overlap_occ'], [275, 'query']]}, ['locked']), ('sampled regression 51', {'timer_s': 90, 'events': [[90, 'berth_occ'], [150, 'berth_clr'], [195, 'query'], [255, 'berth_occ'], [315, 'query'], [320, 'query'], [320, 'overlap_occ'], [440, 'query']]}, ['locked', 'locked', 'locked', 'locked'])]]
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 overlap is released after the train has already left the berth.

The overlap beyond a signal is locked. The release timer starts at the first berth occupation; the overlap is released when an event time reaches start + timer_s while the train has not overrun into the overlap. A berth clear before release cancels the timer (a later occupation restarts it); after release it has no effect. Entering the overlap before release marks an overrun and blocks release. query appends locked or released.

split: open-access


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

N = 1
observations = []
def solve(x):
    T = x['timer_s']
    start = None
    overran = False
    released = False
    out = []
    for t, ev in x['events']:
        if start is not None and not released and not overran and t - start >= T:
            released = True
        if ev == 'berth_occ':
            if start is None:
                start = t
        elif ev == 'berth_clr':
            if not released:
                start = None
        elif ev == 'overlap_occ':
            pass
        elif ev == 'query':
            out.append('released' if released else 'locked')
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: overrun into the overlap', {'timer_s': 60, 'events': [[0, 'berth_occ'], [20, 'overlap_occ'], [120, 'query']]}, ['locked']), ('sampled regression 6', {'timer_s': 120, 'events': [[90, 'query'], [95, 'berth_clr'], [100, 'overlap_occ'], [130, 'berth_occ'], [130, 'overlap_occ'], [220, 'query'], [280, 'berth_clr'], [285, 'query'], [345, 'berth_clr'], [405, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('sampled regression 11', {'timer_s': 120, 'events': [[5, 'berth_occ'], [65, 'overlap_occ'], [125, 'query'], [185, 'query']]}, ['locked', 'locked']), ('boundary: expiry exactly on time', {'timer_s': 60, 'events': [[10, 'berth_occ'], [70, 'query']]}, ['released']), ('boundary: track circuit bob restarts nothing', {'timer_s': 60, 'events': [[0, 'berth_occ'], [40, 'berth_occ'], [60, 'query']]}, ['released']), ('sampled regression 1', {'timer_s': 45, 'events': [[5, 'overlap_occ'], [35, 'query'], [65, 'berth_clr'], [125, 'query'], [170, 'query'], [170, 'berth_clr'], [230, 'berth_occ'], [350, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 4', {'timer_s': 90, 'events': [[60, 'berth_clr'], [150, 'berth_occ'], [155, 'berth_occ'], [155, 'query']]}, ['locked']), ('control 7', {'timer_s': 45, 'events': [[5, 'query'], [65, 'overlap_occ'], [110, 'overlap_occ'], [170, 'query']]}, ['locked', 'locked'])], [('regression: overrun into the overlap', {'timer_s': 60, 'events': [[0, 'berth_occ'], [20, 'overlap_occ'], [120, 'query']]}, ['locked']), ('sampled regression 20', {'timer_s': 90, 'events': [[5, 'overlap_occ'], [95, 'overlap_occ'], [100, 'overlap_occ'], [160, 'query'], [220, 'berth_occ'], [340, 'query']]}, ['locked', 'locked']), ('sampled regression 42', {'timer_s': 120, 'events': [[90, 'berth_occ'], [180, 'overlap_occ'], [240, 'berth_clr'], [330, 'query'], [390, 'query']]}, ['locked', 'locked']), ('boundary: train stops at time zero', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_occ'], [60, 'query']]}, ['released']), ('boundary: train leaves before expiry', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_clr'], [90, 'query']]}, ['locked']), ('control 12', {'timer_s': 120, 'events': [[60, 'berth_occ'], [65, 'query'], [70, 'query'], [70, 'query'], [75, 'berth_occ'], [80, 'berth_occ'], [125, 'berth_clr'], [125, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 15', {'timer_s': 120, 'events': [[60, 'berth_clr'], [105, 'berth_clr'], [110, 'berth_clr'], [115, 'berth_clr'], [175, 'query'], [175, 'berth_clr'], [235, 'query'], [265, 'overlap_occ'], [270, 'berth_clr'], [390, 'query']]}, ['locked', 'locked', 'locked']), ('control 18', {'timer_s': 90, 'events': [[0, 'query'], [0, 'query'], [30, 'berth_occ'], [120, 'overlap_occ'], [210, 'berth_clr'], [215, 'query'], [245, 'berth_occ'], [365, 'query']]}, ['locked', 'locked', 'released', 'released'])], [('regression: overrun into the overlap', {'timer_s': 60, 'events': [[0, 'berth_occ'], [20, 'overlap_occ'], [120, 'query']]}, ['locked']), ('sampled regression 37', {'timer_s': 120, 'events': [[30, 'query'], [60, 'overlap_occ'], [120, 'berth_occ'], [180, 'overlap_occ'], [185, 'overlap_occ'], [185, 'overlap_occ'], [245, 'query'], [275, 'query'], [280, 'overlap_occ'], [280, 'berth_occ'], [280, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('sampled regression 77', {'timer_s': 120, 'events': [[60, 'query'], [120, 'berth_occ'], [165, 'overlap_occ'], [170, 'query'], [175, 'berth_occ'], [205, 'query'], [205, 'berth_occ'], [250, 'query'], [250, 'query']]}, ['locked', 'locked', 'locked', 'locked', 'locked']), ('boundary: berth clears after release', {'timer_s': 60, 'events': [[0, 'berth_occ'], [60, 'query'], [65, 'berth_clr'], [70, 'query']]}, ['released', 'released']), ('boundary: ninety second timer at one minute', {'timer_s': 90, 'events': [[0, 'berth_occ'], [60, 'query'], [89, 'query'], [90, 'query']]}, ['locked', 'locked', 'released']), ('control 23', {'timer_s': 45, 'events': [[0, 'query'], [5, 'berth_occ'], [95, 'berth_occ'], [185, 'berth_occ'], [245, 'query']]}, ['locked', 'released']), ('control 26', {'timer_s': 60, 'events': [[30, 'query'], [60, 'query'], [150, 'overlap_occ'], [150, 'query']]}, ['locked', 'locked', 'locked']), ('sampled regression 29', {'timer_s': 90, 'events': [[90, 'overlap_occ'], [95, 'query'], [95, 'berth_occ'], [185, 'query'], [230, 'query'], [260, 'query'], [350, 'berth_occ'], [410, 'query']]}, ['locked', 'locked', 'locked', 'locked', 'locked'])], [('regression: overrun into the overlap', {'timer_s': 60, 'events': [[0, 'berth_occ'], [20, 'overlap_occ'], [120, 'query']]}, ['locked']), ('sampled regression 47', {'timer_s': 45, 'events': [[45, 'berth_occ'], [45, 'overlap_occ'], [50, 'query'], [95, 'query'], [95, 'query']]}, ['locked', 'locked', 'locked']), ('sampled regression 36', {'timer_s': 120, 'events': [[60, 'berth_clr'], [65, 'berth_occ'], [125, 'berth_occ'], [130, 'berth_occ'], [160, 'berth_occ'], [165, 'overlap_occ'], [210, 'overlap_occ'], [270, 'berth_occ'], [315, 'berth_occ'], [320, 'overlap_occ'], [320, 'query']]}, ['locked']), ('boundary: ninety second timer at one minute', {'timer_s': 90, 'events': [[0, 'berth_occ'], [60, 'query'], [89, 'query'], [90, 'query']]}, ['locked', 'locked', 'released']), ('boundary: expiry after a minute boundary', {'timer_s': 120, 'events': [[30, 'berth_occ'], [140, 'query'], [150, 'query']]}, ['locked', 'released']), ('control 34', {'timer_s': 60, 'events': [[5, 'query'], [35, 'query'], [80, 'berth_occ'], [170, 'berth_occ'], [260, 'berth_occ'], [320, 'berth_occ'], [350, 'overlap_occ'], [395, 'overlap_occ'], [440, 'query'], [500, 'query'], [560, 'query']]}, ['locked', 'locked', 'released', 'released', 'released']), ('sampled regression 37', {'timer_s': 120, 'events': [[30, 'query'], [60, 'overlap_occ'], [120, 'berth_occ'], [180, 'overlap_occ'], [185, 'overlap_occ'], [185, 'overlap_occ'], [245, 'query'], [275, 'query'], [280, 'overlap_occ'], [280, 'berth_occ'], [280, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('sampled regression 40', {'timer_s': 90, 'events': [[60, 'overlap_occ'], [90, 'query'], [135, 'berth_occ'], [195, 'overlap_occ'], [225, 'berth_occ'], [230, 'berth_clr'], [230, 'query']]}, ['locked', 'locked'])], [('regression: overrun into the overlap', {'timer_s': 60, 'events': [[0, 'berth_occ'], [20, 'overlap_occ'], [120, 'query']]}, ['locked']), ('sampled regression 73', {'timer_s': 60, 'events': [[5, 'overlap_occ'], [50, 'berth_occ'], [140, 'berth_clr'], [200, 'berth_occ'], [260, 'query'], [290, 'overlap_occ'], [290, 'overlap_occ'], [290, 'query']]}, ['locked', 'locked']), ('sampled regression 51', {'timer_s': 90, 'events': [[90, 'berth_occ'], [150, 'berth_clr'], [195, 'query'], [255, 'berth_occ'], [315, 'query'], [320, 'query'], [320, 'overlap_occ'], [440, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('boundary: expiry exactly on time', {'timer_s': 60, 'events': [[10, 'berth_occ'], [70, 'query']]}, ['released']), ('boundary: track circuit bob restarts nothing', {'timer_s': 60, 'events': [[0, 'berth_occ'], [40, 'berth_occ'], [60, 'query']]}, ['released']), ('sampled regression 45', {'timer_s': 60, 'events': [[60, 'query'], [120, 'query'], [150, 'overlap_occ'], [155, 'berth_occ'], [245, 'overlap_occ'], [290, 'berth_occ'], [380, 'berth_clr'], [470, 'overlap_occ'], [470, 'query'], [475, 'berth_occ'], [595, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('sampled regression 48', {'timer_s': 45, 'events': [[60, 'overlap_occ'], [150, 'berth_occ'], [180, 'overlap_occ'], [180, 'berth_occ'], [270, 'berth_clr'], [275, 'berth_clr'], [275, 'overlap_occ'], [275, 'query']]}, ['locked']), ('control 54', {'timer_s': 60, 'events': [[5, 'berth_occ'], [95, 'overlap_occ'], [140, 'query'], [145, 'query'], [205, 'query'], [205, 'overlap_occ'], [265, 'query']]}, ['released', 'released', 'released', 'released'])]]
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):
    T = x['timer_s']
    start = None
    overran = False
    released = False
    out = []
    for t, ev in x['events']:
        if start is not None and not released and not overran and t - start >= T:
            released = True
        if ev == 'berth_occ':
            if start is None:
                start = t
        elif ev == 'berth_clr':
            if not released:
                start = None
        elif ev == 'overlap_occ':
            if start is None:
                overran = True
        elif ev == 'query':
            out.append('released' if released else 'locked')
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: overrun into the overlap', {'timer_s': 60, 'events': [[0, 'berth_occ'], [20, 'overlap_occ'], [120, 'query']]}, ['locked']), ('sampled regression 6', {'timer_s': 120, 'events': [[90, 'query'], [95, 'berth_clr'], [100, 'overlap_occ'], [130, 'berth_occ'], [130, 'overlap_occ'], [220, 'query'], [280, 'berth_clr'], [285, 'query'], [345, 'berth_clr'], [405, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('sampled regression 11', {'timer_s': 120, 'events': [[5, 'berth_occ'], [65, 'overlap_occ'], [125, 'query'], [185, 'query']]}, ['locked', 'locked']), ('boundary: expiry exactly on time', {'timer_s': 60, 'events': [[10, 'berth_occ'], [70, 'query']]}, ['released']), ('boundary: track circuit bob restarts nothing', {'timer_s': 60, 'events': [[0, 'berth_occ'], [40, 'berth_occ'], [60, 'query']]}, ['released']), ('sampled regression 1', {'timer_s': 45, 'events': [[5, 'overlap_occ'], [35, 'query'], [65, 'berth_clr'], [125, 'query'], [170, 'query'], [170, 'berth_clr'], [230, 'berth_occ'], [350, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 4', {'timer_s': 90, 'events': [[60, 'berth_clr'], [150, 'berth_occ'], [155, 'berth_occ'], [155, 'query']]}, ['locked']), ('control 7', {'timer_s': 45, 'events': [[5, 'query'], [65, 'overlap_occ'], [110, 'overlap_occ'], [170, 'query']]}, ['locked', 'locked'])], [('regression: overrun into the overlap', {'timer_s': 60, 'events': [[0, 'berth_occ'], [20, 'overlap_occ'], [120, 'query']]}, ['locked']), ('sampled regression 20', {'timer_s': 90, 'events': [[5, 'overlap_occ'], [95, 'overlap_occ'], [100, 'overlap_occ'], [160, 'query'], [220, 'berth_occ'], [340, 'query']]}, ['locked', 'locked']), ('sampled regression 42', {'timer_s': 120, 'events': [[90, 'berth_occ'], [180, 'overlap_occ'], [240, 'berth_clr'], [330, 'query'], [390, 'query']]}, ['locked', 'locked']), ('boundary: train stops at time zero', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_occ'], [60, 'query']]}, ['released']), ('boundary: train leaves before expiry', {'timer_s': 60, 'events': [[0, 'berth_occ'], [30, 'berth_clr'], [90, 'query']]}, ['locked']), ('control 12', {'timer_s': 120, 'events': [[60, 'berth_occ'], [65, 'query'], [70, 'query'], [70, 'query'], [75, 'berth_occ'], [80, 'berth_occ'], [125, 'berth_clr'], [125, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('control 15', {'timer_s': 120, 'events': [[60, 'berth_clr'], [105, 'berth_clr'], [110, 'berth_clr'], [115, 'berth_clr'], [175, 'query'], [175, 'berth_clr'], [235, 'query'], [265, 'overlap_occ'], [270, 'berth_clr'], [390, 'query']]}, ['locked', 'locked', 'locked']), ('control 18', {'timer_s': 90, 'events': [[0, 'query'], [0, 'query'], [30, 'berth_occ'], [120, 'overlap_occ'], [210, 'berth_clr'], [215, 'query'], [245, 'berth_occ'], [365, 'query']]}, ['locked', 'locked', 'released', 'released'])], [('regression: overrun into the overlap', {'timer_s': 60, 'events': [[0, 'berth_occ'], [20, 'overlap_occ'], [120, 'query']]}, ['locked']), ('sampled regression 37', {'timer_s': 120, 'events': [[30, 'query'], [60, 'overlap_occ'], [120, 'berth_occ'], [180, 'overlap_occ'], [185, 'overlap_occ'], [185, 'overlap_occ'], [245, 'query'], [275, 'query'], [280, 'overlap_occ'], [280, 'berth_occ'], [280, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('sampled regression 77', {'timer_s': 120, 'events': [[60, 'query'], [120, 'berth_occ'], [165, 'overlap_occ'], [170, 'query'], [175, 'berth_occ'], [205, 'query'], [205, 'berth_occ'], [250, 'query'], [250, 'query']]}, ['locked', 'locked', 'locked', 'locked', 'locked']), ('boundary: berth clears after release', {'timer_s': 60, 'events': [[0, 'berth_occ'], [60, 'query'], [65, 'berth_clr'], [70, 'query']]}, ['released', 'released']), ('boundary: ninety second timer at one minute', {'timer_s': 90, 'events': [[0, 'berth_occ'], [60, 'query'], [89, 'query'], [90, 'query']]}, ['locked', 'locked', 'released']), ('control 23', {'timer_s': 45, 'events': [[0, 'query'], [5, 'berth_occ'], [95, 'berth_occ'], [185, 'berth_occ'], [245, 'query']]}, ['locked', 'released']), ('control 26', {'timer_s': 60, 'events': [[30, 'query'], [60, 'query'], [150, 'overlap_occ'], [150, 'query']]}, ['locked', 'locked', 'locked']), ('sampled regression 29', {'timer_s': 90, 'events': [[90, 'overlap_occ'], [95, 'query'], [95, 'berth_occ'], [185, 'query'], [230, 'query'], [260, 'query'], [350, 'berth_occ'], [410, 'query']]}, ['locked', 'locked', 'locked', 'locked', 'locked'])], [('regression: overrun into the overlap', {'timer_s': 60, 'events': [[0, 'berth_occ'], [20, 'overlap_occ'], [120, 'query']]}, ['locked']), ('sampled regression 47', {'timer_s': 45, 'events': [[45, 'berth_occ'], [45, 'overlap_occ'], [50, 'query'], [95, 'query'], [95, 'query']]}, ['locked', 'locked', 'locked']), ('sampled regression 36', {'timer_s': 120, 'events': [[60, 'berth_clr'], [65, 'berth_occ'], [125, 'berth_occ'], [130, 'berth_occ'], [160, 'berth_occ'], [165, 'overlap_occ'], [210, 'overlap_occ'], [270, 'berth_occ'], [315, 'berth_occ'], [320, 'overlap_occ'], [320, 'query']]}, ['locked']), ('boundary: ninety second timer at one minute', {'timer_s': 90, 'events': [[0, 'berth_occ'], [60, 'query'], [89, 'query'], [90, 'query']]}, ['locked', 'locked', 'released']), ('boundary: expiry after a minute boundary', {'timer_s': 120, 'events': [[30, 'berth_occ'], [140, 'query'], [150, 'query']]}, ['locked', 'released']), ('control 34', {'timer_s': 60, 'events': [[5, 'query'], [35, 'query'], [80, 'berth_occ'], [170, 'berth_occ'], [260, 'berth_occ'], [320, 'berth_occ'], [350, 'overlap_occ'], [395, 'overlap_occ'], [440, 'query'], [500, 'query'], [560, 'query']]}, ['locked', 'locked', 'released', 'released', 'released']), ('sampled regression 37', {'timer_s': 120, 'events': [[30, 'query'], [60, 'overlap_occ'], [120, 'berth_occ'], [180, 'overlap_occ'], [185, 'overlap_occ'], [185, 'overlap_occ'], [245, 'query'], [275, 'query'], [280, 'overlap_occ'], [280, 'berth_occ'], [280, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('sampled regression 40', {'timer_s': 90, 'events': [[60, 'overlap_occ'], [90, 'query'], [135, 'berth_occ'], [195, 'overlap_occ'], [225, 'berth_occ'], [230, 'berth_clr'], [230, 'query']]}, ['locked', 'locked'])], [('regression: overrun into the overlap', {'timer_s': 60, 'events': [[0, 'berth_occ'], [20, 'overlap_occ'], [120, 'query']]}, ['locked']), ('sampled regression 73', {'timer_s': 60, 'events': [[5, 'overlap_occ'], [50, 'berth_occ'], [140, 'berth_clr'], [200, 'berth_occ'], [260, 'query'], [290, 'overlap_occ'], [290, 'overlap_occ'], [290, 'query']]}, ['locked', 'locked']), ('sampled regression 51', {'timer_s': 90, 'events': [[90, 'berth_occ'], [150, 'berth_clr'], [195, 'query'], [255, 'berth_occ'], [315, 'query'], [320, 'query'], [320, 'overlap_occ'], [440, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('boundary: expiry exactly on time', {'timer_s': 60, 'events': [[10, 'berth_occ'], [70, 'query']]}, ['released']), ('boundary: track circuit bob restarts nothing', {'timer_s': 60, 'events': [[0, 'berth_occ'], [40, 'berth_occ'], [60, 'query']]}, ['released']), ('sampled regression 45', {'timer_s': 60, 'events': [[60, 'query'], [120, 'query'], [150, 'overlap_occ'], [155, 'berth_occ'], [245, 'overlap_occ'], [290, 'berth_occ'], [380, 'berth_clr'], [470, 'overlap_occ'], [470, 'query'], [475, 'berth_occ'], [595, 'query']]}, ['locked', 'locked', 'locked', 'locked']), ('sampled regression 48', {'timer_s': 45, 'events': [[60, 'overlap_occ'], [150, 'berth_occ'], [180, 'overlap_occ'], [180, 'berth_occ'], [270, 'berth_clr'], [275, 'berth_clr'], [275, 'overlap_occ'], [275, 'query']]}, ['locked']), ('control 54', {'timer_s': 60, 'events': [[5, 'berth_occ'], [95, 'overlap_occ'], [140, 'query'], [145, 'query'], [205, 'query'], [205, 'overlap_occ'], [265, 'query']]}, ['released', 'released', 'released', 'released'])]]
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 overlap is released while the train stands in it.

The overlap beyond a signal is locked. The release timer starts at the first berth occupation; the overlap is released when an event time reaches start + timer_s while the train has not overrun into the overlap. A berth clear before release cancels the timer (a later occupation restarts it); after release it has no effect. Entering the overlap before release marks an overrun and blocks release. query appends locked or released.

split: open-access