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

N = 1
observations = []
def solve(preset, scans):
    acc = 0
    prev = False
    out = []
    for rung_in, dt in scans:
        rung_in = bool(rung_in)
        if rung_in and prev:
            acc = min(preset, acc + dt)
        elif not rung_in:
            acc = 0
        dn = rung_in and acc > preset
        tt = rung_in and not dn
        prev = rung_in
        out.append([dn, tt, acc])
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['regression: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['regression: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['regression: scenario 1',
   [30, [[True, 40], [False, 75], [True, 60], [False, 25], [False, 10], [True, 60], [True, 25], [True, 40]]],
   [[False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 25],
    [True, False, 30]]],
  ['regression: scenario 2',
   [30, [[False, 25], [True, 50], [True, 0], [True, 0], [True, 25], [True, 75], [True, 75]]],
   [[False, False, 0],
    [False, True, 0],
    [False, True, 0],
    [False, True, 0],
    [False, True, 25],
    [True, False, 30],
    [True, False, 30]]],
  ['control: scenario 3',
   [120, [[True, 25], [True, 20], [False, 75], [True, 75], [True, 0], [False, 10], [True, 25]]],
   [[False, True, 0],
    [False, True, 20],
    [False, False, 0],
    [False, True, 0],
    [False, True, 0],
    [False, False, 0],
    [False, True, 0]]],
  ['regression: scenario 4',
   [0,
    [[True, 10],
     [False, 25],
     [True, 25],
     [True, 20],
     [True, 40],
     [True, 20],
     [True, 75],
     [True, 0],
     [True, 10]]],
   [[True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0]]]],
 [['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['regression: scenario 12',
   [0,
    [[False, 50],
     [True, 60],
     [True, 60],
     [True, 60],
     [True, 20],
     [True, 0],
     [True, 0],
     [True, 10],
     [True, 60],
     [True, 60]]],
   [[False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0]]],
  ['regression: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['regression: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['regression: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['regression: scenario 1',
   [0,
    [[True, 40],
     [True, 10],
     [True, 10],
     [False, 10],
     [True, 20],
     [True, 25],
     [True, 20],
     [False, 25],
     [True, 20]]],
   [[True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0]]],
  ['control: scenario 2',
   [150,
    [[True, 60],
     [True, 10],
     [False, 20],
     [False, 40],
     [True, 50],
     [True, 25],
     [False, 25],
     [False, 75],
     [True, 25],
     [False, 0],
     [True, 60],
     [False, 10]]],
   [[False, True, 0],
    [False, True, 10],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 25],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0]]],
  ['regression: scenario 3',
   [50,
    [[False, 50],
     [True, 75],
     [True, 75],
     [True, 20],
     [True, 75],
     [True, 0],
     [False, 60],
     [True, 25],
     [False, 10]]],
   [[False, False, 0],
    [False, True, 0],
    [True, False, 50],
    [True, False, 50],
    [True, False, 50],
    [True, False, 50],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0]]]],
 [['regression: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['regression: scenario 34',
   [0, [[True, 10], [True, 20], [True, 60], [True, 25], [True, 50], [False, 50], [False, 25], [True, 40]]],
   [[True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [False, False, 0],
    [True, False, 0]]],
  ['regression: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['regression: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['regression: scenario 1',
   [50,
    [[True, 75],
     [True, 40],
     [True, 60],
     [True, 0],
     [True, 25],
     [False, 50],
     [False, 75],
     [True, 60],
     [True, 20],
     [True, 60],
     [False, 60],
     [True, 75]]],
   [[False, True, 0],
    [False, True, 40],
    [True, False, 50],
    [True, False, 50],
    [True, False, 50],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 20],
    [True, False, 50],
    [False, False, 0],
    [False, True, 0]]],
  ['control: scenario 2',
   [120, [[False, 0], [False, 75], [True, 75], [True, 0], [True, 0], [False, 75], [True, 60], [True, 40]]],
   [[False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 0],
    [False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40]]],
  ['control: scenario 3',
   [50,
    [[True, 40],
     [False, 0],
     [True, 60],
     [True, 0],
     [True, 40],
     [True, 0],
     [True, 0],
     [False, 0],
     [False, 50],
     [False, 60],
     [False, 10],
     [True, 60]]],
   [[False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 0],
    [False, True, 40],
    [False, True, 40],
    [False, True, 40],
    [False, False, 0],
    [False, False, 0],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0]]]],
 [['regression: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['regression: scenario 9',
   [0,
    [[True, 20],
     [True, 40],
     [True, 50],
     [True, 20],
     [True, 25],
     [True, 10],
     [False, 60],
     [True, 75],
     [True, 40],
     [True, 10],
     [True, 60],
     [False, 10],
     [True, 10],
     [True, 40]]],
   [[True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0]]],
  ['regression: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['regression: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['regression: scenario 1',
   [0,
    [[True, 10],
     [True, 0],
     [False, 50],
     [True, 40],
     [False, 20],
     [False, 25],
     [True, 50],
     [True, 60],
     [True, 40]]],
   [[True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [False, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0]]],
  ['control: scenario 2',
   [100, [[False, 50], [True, 50], [True, 20], [False, 50], [True, 40], [True, 10], [False, 10]]],
   [[False, False, 0],
    [False, True, 0],
    [False, True, 20],
    [False, False, 0],
    [False, True, 0],
    [False, True, 10],
    [False, False, 0]]],
  ['regression: scenario 3',
   [120,
    [[True, 60],
     [True, 10],
     [False, 10],
     [True, 50],
     [True, 20],
     [True, 25],
     [True, 25],
     [False, 75],
     [True, 40],
     [True, 50],
     [True, 75],
     [True, 0]]],
   [[False, True, 0],
    [False, True, 10],
    [False, False, 0],
    [False, True, 0],
    [False, True, 20],
    [False, True, 45],
    [False, True, 70],
    [False, False, 0],
    [False, True, 0],
    [False, True, 50],
    [True, False, 120],
    [True, False, 120]]]],
 [['regression: scenario 1',
   [120,
    [[True, 0],
     [True, 50],
     [True, 50],
     [True, 75],
     [True, 75],
     [False, 40],
     [True, 25],
     [False, 0],
     [False, 10],
     [True, 25],
     [False, 0]]],
   [[False, True, 0],
    [False, True, 50],
    [False, True, 100],
    [True, False, 120],
    [True, False, 120],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0]]],
  ['regression: scenario 40',
   [0,
    [[True, 10],
     [True, 25],
     [True, 50],
     [False, 60],
     [False, 20],
     [True, 50],
     [True, 0],
     [True, 60],
     [False, 60]]],
   [[True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0]]],
  ['regression: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['regression: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['regression: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['control: scenario 2',
   [150, [[True, 50], [False, 40], [True, 20], [True, 20], [True, 10], [True, 40], [False, 50]]],
   [[False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 20],
    [False, True, 30],
    [False, True, 70],
    [False, False, 0]]],
  ['control: scenario 3',
   [200,
    [[False, 20],
     [False, 50],
     [True, 75],
     [False, 60],
     [False, 50],
     [True, 0],
     [True, 25],
     [True, 20],
     [True, 40],
     [True, 25],
     [True, 25],
     [True, 60]]],
   [[False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 25],
    [False, True, 45],
    [False, True, 85],
    [False, True, 110],
    [False, True, 135],
    [False, True, 195]]]]]
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(preset, scans):
    acc = 0
    prev = False
    out = []
    for rung_in, dt in scans:
        rung_in = bool(rung_in)
        if rung_in and prev:
            acc = min(preset, acc + dt)
        elif not rung_in:
            acc = 0
        dn = rung_in and acc >= preset and preset > 0
        tt = rung_in and not dn
        prev = rung_in
        out.append([dn, tt, acc])
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['regression: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['regression: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['regression: scenario 1',
   [30, [[True, 40], [False, 75], [True, 60], [False, 25], [False, 10], [True, 60], [True, 25], [True, 40]]],
   [[False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 25],
    [True, False, 30]]],
  ['regression: scenario 2',
   [30, [[False, 25], [True, 50], [True, 0], [True, 0], [True, 25], [True, 75], [True, 75]]],
   [[False, False, 0],
    [False, True, 0],
    [False, True, 0],
    [False, True, 0],
    [False, True, 25],
    [True, False, 30],
    [True, False, 30]]],
  ['control: scenario 3',
   [120, [[True, 25], [True, 20], [False, 75], [True, 75], [True, 0], [False, 10], [True, 25]]],
   [[False, True, 0],
    [False, True, 20],
    [False, False, 0],
    [False, True, 0],
    [False, True, 0],
    [False, False, 0],
    [False, True, 0]]],
  ['regression: scenario 4',
   [0,
    [[True, 10],
     [False, 25],
     [True, 25],
     [True, 20],
     [True, 40],
     [True, 20],
     [True, 75],
     [True, 0],
     [True, 10]]],
   [[True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0]]]],
 [['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['regression: scenario 12',
   [0,
    [[False, 50],
     [True, 60],
     [True, 60],
     [True, 60],
     [True, 20],
     [True, 0],
     [True, 0],
     [True, 10],
     [True, 60],
     [True, 60]]],
   [[False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0]]],
  ['regression: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['regression: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['regression: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['regression: scenario 1',
   [0,
    [[True, 40],
     [True, 10],
     [True, 10],
     [False, 10],
     [True, 20],
     [True, 25],
     [True, 20],
     [False, 25],
     [True, 20]]],
   [[True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0]]],
  ['control: scenario 2',
   [150,
    [[True, 60],
     [True, 10],
     [False, 20],
     [False, 40],
     [True, 50],
     [True, 25],
     [False, 25],
     [False, 75],
     [True, 25],
     [False, 0],
     [True, 60],
     [False, 10]]],
   [[False, True, 0],
    [False, True, 10],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 25],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0]]],
  ['regression: scenario 3',
   [50,
    [[False, 50],
     [True, 75],
     [True, 75],
     [True, 20],
     [True, 75],
     [True, 0],
     [False, 60],
     [True, 25],
     [False, 10]]],
   [[False, False, 0],
    [False, True, 0],
    [True, False, 50],
    [True, False, 50],
    [True, False, 50],
    [True, False, 50],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0]]]],
 [['regression: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['regression: scenario 34',
   [0, [[True, 10], [True, 20], [True, 60], [True, 25], [True, 50], [False, 50], [False, 25], [True, 40]]],
   [[True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [False, False, 0],
    [True, False, 0]]],
  ['regression: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['regression: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['regression: scenario 1',
   [50,
    [[True, 75],
     [True, 40],
     [True, 60],
     [True, 0],
     [True, 25],
     [False, 50],
     [False, 75],
     [True, 60],
     [True, 20],
     [True, 60],
     [False, 60],
     [True, 75]]],
   [[False, True, 0],
    [False, True, 40],
    [True, False, 50],
    [True, False, 50],
    [True, False, 50],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 20],
    [True, False, 50],
    [False, False, 0],
    [False, True, 0]]],
  ['control: scenario 2',
   [120, [[False, 0], [False, 75], [True, 75], [True, 0], [True, 0], [False, 75], [True, 60], [True, 40]]],
   [[False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 0],
    [False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40]]],
  ['control: scenario 3',
   [50,
    [[True, 40],
     [False, 0],
     [True, 60],
     [True, 0],
     [True, 40],
     [True, 0],
     [True, 0],
     [False, 0],
     [False, 50],
     [False, 60],
     [False, 10],
     [True, 60]]],
   [[False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 0],
    [False, True, 40],
    [False, True, 40],
    [False, True, 40],
    [False, False, 0],
    [False, False, 0],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0]]]],
 [['regression: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['regression: scenario 9',
   [0,
    [[True, 20],
     [True, 40],
     [True, 50],
     [True, 20],
     [True, 25],
     [True, 10],
     [False, 60],
     [True, 75],
     [True, 40],
     [True, 10],
     [True, 60],
     [False, 10],
     [True, 10],
     [True, 40]]],
   [[True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0]]],
  ['regression: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['regression: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['regression: scenario 1',
   [0,
    [[True, 10],
     [True, 0],
     [False, 50],
     [True, 40],
     [False, 20],
     [False, 25],
     [True, 50],
     [True, 60],
     [True, 40]]],
   [[True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [False, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0]]],
  ['control: scenario 2',
   [100, [[False, 50], [True, 50], [True, 20], [False, 50], [True, 40], [True, 10], [False, 10]]],
   [[False, False, 0],
    [False, True, 0],
    [False, True, 20],
    [False, False, 0],
    [False, True, 0],
    [False, True, 10],
    [False, False, 0]]],
  ['regression: scenario 3',
   [120,
    [[True, 60],
     [True, 10],
     [False, 10],
     [True, 50],
     [True, 20],
     [True, 25],
     [True, 25],
     [False, 75],
     [True, 40],
     [True, 50],
     [True, 75],
     [True, 0]]],
   [[False, True, 0],
    [False, True, 10],
    [False, False, 0],
    [False, True, 0],
    [False, True, 20],
    [False, True, 45],
    [False, True, 70],
    [False, False, 0],
    [False, True, 0],
    [False, True, 50],
    [True, False, 120],
    [True, False, 120]]]],
 [['regression: scenario 1',
   [120,
    [[True, 0],
     [True, 50],
     [True, 50],
     [True, 75],
     [True, 75],
     [False, 40],
     [True, 25],
     [False, 0],
     [False, 10],
     [True, 25],
     [False, 0]]],
   [[False, True, 0],
    [False, True, 50],
    [False, True, 100],
    [True, False, 120],
    [True, False, 120],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0]]],
  ['regression: scenario 40',
   [0,
    [[True, 10],
     [True, 25],
     [True, 50],
     [False, 60],
     [False, 20],
     [True, 50],
     [True, 0],
     [True, 60],
     [False, 60]]],
   [[True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0]]],
  ['regression: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['regression: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['regression: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['control: scenario 2',
   [150, [[True, 50], [False, 40], [True, 20], [True, 20], [True, 10], [True, 40], [False, 50]]],
   [[False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 20],
    [False, True, 30],
    [False, True, 70],
    [False, False, 0]]],
  ['control: scenario 3',
   [200,
    [[False, 20],
     [False, 50],
     [True, 75],
     [False, 60],
     [False, 50],
     [True, 0],
     [True, 25],
     [True, 20],
     [True, 40],
     [True, 25],
     [True, 25],
     [True, 60]]],
   [[False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 25],
    [False, True, 45],
    [False, True, 85],
    [False, True, 110],
    [False, True, 135],
    [False, True, 195]]]]]
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 running timer never reports done even though ACC equals PRE.

On-delay timer (TON) evaluated once per scan. scans is a list of [rung_in, elapsed_ms since the previous scan]. The accumulator starts on the false-to-true scan without crediting that scan's elapsed time, then adds each later true scan's elapsed time, clamped at preset. A false rung resets the accumulator. DN is rung_in and acc >= preset; TT is rung_in and not DN. Return [DN, TT, ACC] per scan.

split: open-access


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

N = 1
observations = []
def solve(preset, scans):
    acc = 0
    prev = False
    out = []
    for rung_in, dt in scans:
        rung_in = bool(rung_in)
        if rung_in and prev:
            acc = min(preset, acc + dt)
        elif not rung_in:
            acc = 0
        dn = rung_in and acc >= preset
        tt = rung_in
        prev = rung_in
        out.append([dn, tt, acc])
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['regression: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['regression: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['regression: scenario 1',
   [30, [[True, 40], [False, 75], [True, 60], [False, 25], [False, 10], [True, 60], [True, 25], [True, 40]]],
   [[False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 25],
    [True, False, 30]]],
  ['regression: scenario 2',
   [30, [[False, 25], [True, 50], [True, 0], [True, 0], [True, 25], [True, 75], [True, 75]]],
   [[False, False, 0],
    [False, True, 0],
    [False, True, 0],
    [False, True, 0],
    [False, True, 25],
    [True, False, 30],
    [True, False, 30]]],
  ['regression: scenario 3',
   [120, [[True, 25], [True, 20], [False, 75], [True, 75], [True, 0], [False, 10], [True, 25]]],
   [[False, True, 0],
    [False, True, 20],
    [False, False, 0],
    [False, True, 0],
    [False, True, 0],
    [False, False, 0],
    [False, True, 0]]],
  ['regression: scenario 4',
   [0,
    [[True, 10],
     [False, 25],
     [True, 25],
     [True, 20],
     [True, 40],
     [True, 20],
     [True, 75],
     [True, 0],
     [True, 10]]],
   [[True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0]]]],
 [['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['regression: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['regression: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['regression: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['regression: scenario 1',
   [0,
    [[True, 40],
     [True, 10],
     [True, 10],
     [False, 10],
     [True, 20],
     [True, 25],
     [True, 20],
     [False, 25],
     [True, 20]]],
   [[True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0]]],
  ['regression: scenario 2',
   [150,
    [[True, 60],
     [True, 10],
     [False, 20],
     [False, 40],
     [True, 50],
     [True, 25],
     [False, 25],
     [False, 75],
     [True, 25],
     [False, 0],
     [True, 60],
     [False, 10]]],
   [[False, True, 0],
    [False, True, 10],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 25],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0]]],
  ['regression: scenario 3',
   [50,
    [[False, 50],
     [True, 75],
     [True, 75],
     [True, 20],
     [True, 75],
     [True, 0],
     [False, 60],
     [True, 25],
     [False, 10]]],
   [[False, False, 0],
    [False, True, 0],
    [True, False, 50],
    [True, False, 50],
    [True, False, 50],
    [True, False, 50],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0]]],
  ['regression: scenario 4',
   [120,
    [[True, 75],
     [False, 60],
     [True, 20],
     [True, 25],
     [False, 40],
     [False, 40],
     [True, 50],
     [True, 60],
     [True, 75],
     [True, 40],
     [True, 0]]],
   [[False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 25],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 60],
    [True, False, 120],
    [True, False, 120],
    [True, False, 120]]]],
 [['regression: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['regression: scenario 1',
   [50,
    [[True, 75],
     [True, 40],
     [True, 60],
     [True, 0],
     [True, 25],
     [False, 50],
     [False, 75],
     [True, 60],
     [True, 20],
     [True, 60],
     [False, 60],
     [True, 75]]],
   [[False, True, 0],
    [False, True, 40],
    [True, False, 50],
    [True, False, 50],
    [True, False, 50],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 20],
    [True, False, 50],
    [False, False, 0],
    [False, True, 0]]],
  ['regression: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['regression: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['regression: scenario 2',
   [120, [[False, 0], [False, 75], [True, 75], [True, 0], [True, 0], [False, 75], [True, 60], [True, 40]]],
   [[False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 0],
    [False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40]]],
  ['regression: scenario 3',
   [50,
    [[True, 40],
     [False, 0],
     [True, 60],
     [True, 0],
     [True, 40],
     [True, 0],
     [True, 0],
     [False, 0],
     [False, 50],
     [False, 60],
     [False, 10],
     [True, 60]]],
   [[False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 0],
    [False, True, 40],
    [False, True, 40],
    [False, True, 40],
    [False, False, 0],
    [False, False, 0],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0]]],
  ['regression: scenario 4',
   [100, [[False, 60], [False, 20], [True, 75], [False, 25], [True, 60], [False, 25], [True, 40]]],
   [[False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, True, 0]]]],
 [['regression: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['regression: scenario 2',
   [100, [[False, 50], [True, 50], [True, 20], [False, 50], [True, 40], [True, 10], [False, 10]]],
   [[False, False, 0],
    [False, True, 0],
    [False, True, 20],
    [False, False, 0],
    [False, True, 0],
    [False, True, 10],
    [False, False, 0]]],
  ['regression: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['regression: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['regression: scenario 1',
   [0,
    [[True, 10],
     [True, 0],
     [False, 50],
     [True, 40],
     [False, 20],
     [False, 25],
     [True, 50],
     [True, 60],
     [True, 40]]],
   [[True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [False, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0]]],
  ['regression: scenario 3',
   [120,
    [[True, 60],
     [True, 10],
     [False, 10],
     [True, 50],
     [True, 20],
     [True, 25],
     [True, 25],
     [False, 75],
     [True, 40],
     [True, 50],
     [True, 75],
     [True, 0]]],
   [[False, True, 0],
    [False, True, 10],
    [False, False, 0],
    [False, True, 0],
    [False, True, 20],
    [False, True, 45],
    [False, True, 70],
    [False, False, 0],
    [False, True, 0],
    [False, True, 50],
    [True, False, 120],
    [True, False, 120]]],
  ['regression: scenario 4',
   [0, [[True, 25], [False, 75], [True, 20], [False, 25], [True, 20], [False, 25], [True, 40]]],
   [[True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0]]]],
 [['regression: scenario 1',
   [120,
    [[True, 0],
     [True, 50],
     [True, 50],
     [True, 75],
     [True, 75],
     [False, 40],
     [True, 25],
     [False, 0],
     [False, 10],
     [True, 25],
     [False, 0]]],
   [[False, True, 0],
    [False, True, 50],
    [False, True, 100],
    [True, False, 120],
    [True, False, 120],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0]]],
  ['regression: scenario 3',
   [200,
    [[False, 20],
     [False, 50],
     [True, 75],
     [False, 60],
     [False, 50],
     [True, 0],
     [True, 25],
     [True, 20],
     [True, 40],
     [True, 25],
     [True, 25],
     [True, 60]]],
   [[False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 25],
    [False, True, 45],
    [False, True, 85],
    [False, True, 110],
    [False, True, 135],
    [False, True, 195]]],
  ['regression: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['regression: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['regression: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['regression: scenario 2',
   [150, [[True, 50], [False, 40], [True, 20], [True, 20], [True, 10], [True, 40], [False, 50]]],
   [[False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 20],
    [False, True, 30],
    [False, True, 70],
    [False, False, 0]]],
  ['regression: scenario 4',
   [100,
    [[False, 60],
     [False, 0],
     [True, 50],
     [True, 20],
     [True, 60],
     [True, 20],
     [True, 50],
     [True, 0],
     [True, 20],
     [True, 0],
     [True, 20],
     [True, 25]]],
   [[False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 20],
    [False, True, 80],
    [True, False, 100],
    [True, False, 100],
    [True, False, 100],
    [True, False, 100],
    [True, False, 100],
    [True, False, 100],
    [True, False, 100]]]]]
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(preset, scans):
    acc = 0
    prev = False
    out = []
    for rung_in, dt in scans:
        rung_in = bool(rung_in)
        if rung_in and prev:
            acc = min(preset, acc + dt)
        elif not rung_in:
            acc = 0
        dn = rung_in and acc >= preset
        tt = not dn
        prev = rung_in
        out.append([dn, tt, acc])
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['regression: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['regression: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['regression: scenario 1',
   [30, [[True, 40], [False, 75], [True, 60], [False, 25], [False, 10], [True, 60], [True, 25], [True, 40]]],
   [[False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 25],
    [True, False, 30]]],
  ['regression: scenario 2',
   [30, [[False, 25], [True, 50], [True, 0], [True, 0], [True, 25], [True, 75], [True, 75]]],
   [[False, False, 0],
    [False, True, 0],
    [False, True, 0],
    [False, True, 0],
    [False, True, 25],
    [True, False, 30],
    [True, False, 30]]],
  ['regression: scenario 3',
   [120, [[True, 25], [True, 20], [False, 75], [True, 75], [True, 0], [False, 10], [True, 25]]],
   [[False, True, 0],
    [False, True, 20],
    [False, False, 0],
    [False, True, 0],
    [False, True, 0],
    [False, False, 0],
    [False, True, 0]]],
  ['regression: scenario 4',
   [0,
    [[True, 10],
     [False, 25],
     [True, 25],
     [True, 20],
     [True, 40],
     [True, 20],
     [True, 75],
     [True, 0],
     [True, 10]]],
   [[True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0]]]],
 [['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['regression: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['regression: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['regression: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['regression: scenario 1',
   [0,
    [[True, 40],
     [True, 10],
     [True, 10],
     [False, 10],
     [True, 20],
     [True, 25],
     [True, 20],
     [False, 25],
     [True, 20]]],
   [[True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0]]],
  ['regression: scenario 2',
   [150,
    [[True, 60],
     [True, 10],
     [False, 20],
     [False, 40],
     [True, 50],
     [True, 25],
     [False, 25],
     [False, 75],
     [True, 25],
     [False, 0],
     [True, 60],
     [False, 10]]],
   [[False, True, 0],
    [False, True, 10],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 25],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0]]],
  ['regression: scenario 3',
   [50,
    [[False, 50],
     [True, 75],
     [True, 75],
     [True, 20],
     [True, 75],
     [True, 0],
     [False, 60],
     [True, 25],
     [False, 10]]],
   [[False, False, 0],
    [False, True, 0],
    [True, False, 50],
    [True, False, 50],
    [True, False, 50],
    [True, False, 50],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0]]],
  ['regression: scenario 4',
   [120,
    [[True, 75],
     [False, 60],
     [True, 20],
     [True, 25],
     [False, 40],
     [False, 40],
     [True, 50],
     [True, 60],
     [True, 75],
     [True, 40],
     [True, 0]]],
   [[False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 25],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 60],
    [True, False, 120],
    [True, False, 120],
    [True, False, 120]]]],
 [['regression: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['regression: scenario 1',
   [50,
    [[True, 75],
     [True, 40],
     [True, 60],
     [True, 0],
     [True, 25],
     [False, 50],
     [False, 75],
     [True, 60],
     [True, 20],
     [True, 60],
     [False, 60],
     [True, 75]]],
   [[False, True, 0],
    [False, True, 40],
    [True, False, 50],
    [True, False, 50],
    [True, False, 50],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 20],
    [True, False, 50],
    [False, False, 0],
    [False, True, 0]]],
  ['regression: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['regression: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['regression: scenario 2',
   [120, [[False, 0], [False, 75], [True, 75], [True, 0], [True, 0], [False, 75], [True, 60], [True, 40]]],
   [[False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 0],
    [False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40]]],
  ['regression: scenario 3',
   [50,
    [[True, 40],
     [False, 0],
     [True, 60],
     [True, 0],
     [True, 40],
     [True, 0],
     [True, 0],
     [False, 0],
     [False, 50],
     [False, 60],
     [False, 10],
     [True, 60]]],
   [[False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 0],
    [False, True, 40],
    [False, True, 40],
    [False, True, 40],
    [False, False, 0],
    [False, False, 0],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0]]],
  ['regression: scenario 4',
   [100, [[False, 60], [False, 20], [True, 75], [False, 25], [True, 60], [False, 25], [True, 40]]],
   [[False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, True, 0]]]],
 [['regression: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['regression: scenario 2',
   [100, [[False, 50], [True, 50], [True, 20], [False, 50], [True, 40], [True, 10], [False, 10]]],
   [[False, False, 0],
    [False, True, 0],
    [False, True, 20],
    [False, False, 0],
    [False, True, 0],
    [False, True, 10],
    [False, False, 0]]],
  ['regression: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['regression: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['regression: scenario 1',
   [0,
    [[True, 10],
     [True, 0],
     [False, 50],
     [True, 40],
     [False, 20],
     [False, 25],
     [True, 50],
     [True, 60],
     [True, 40]]],
   [[True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [False, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0]]],
  ['regression: scenario 3',
   [120,
    [[True, 60],
     [True, 10],
     [False, 10],
     [True, 50],
     [True, 20],
     [True, 25],
     [True, 25],
     [False, 75],
     [True, 40],
     [True, 50],
     [True, 75],
     [True, 0]]],
   [[False, True, 0],
    [False, True, 10],
    [False, False, 0],
    [False, True, 0],
    [False, True, 20],
    [False, True, 45],
    [False, True, 70],
    [False, False, 0],
    [False, True, 0],
    [False, True, 50],
    [True, False, 120],
    [True, False, 120]]],
  ['regression: scenario 4',
   [0, [[True, 25], [False, 75], [True, 20], [False, 25], [True, 20], [False, 25], [True, 40]]],
   [[True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0]]]],
 [['regression: scenario 1',
   [120,
    [[True, 0],
     [True, 50],
     [True, 50],
     [True, 75],
     [True, 75],
     [False, 40],
     [True, 25],
     [False, 0],
     [False, 10],
     [True, 25],
     [False, 0]]],
   [[False, True, 0],
    [False, True, 50],
    [False, True, 100],
    [True, False, 120],
    [True, False, 120],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0]]],
  ['regression: scenario 3',
   [200,
    [[False, 20],
     [False, 50],
     [True, 75],
     [False, 60],
     [False, 50],
     [True, 0],
     [True, 25],
     [True, 20],
     [True, 40],
     [True, 25],
     [True, 25],
     [True, 60]]],
   [[False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 25],
    [False, True, 45],
    [False, True, 85],
    [False, True, 110],
    [False, True, 135],
    [False, True, 195]]],
  ['regression: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['regression: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['regression: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['regression: scenario 2',
   [150, [[True, 50], [False, 40], [True, 20], [True, 20], [True, 10], [True, 40], [False, 50]]],
   [[False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 20],
    [False, True, 30],
    [False, True, 70],
    [False, False, 0]]],
  ['regression: scenario 4',
   [100,
    [[False, 60],
     [False, 0],
     [True, 50],
     [True, 20],
     [True, 60],
     [True, 20],
     [True, 50],
     [True, 0],
     [True, 20],
     [True, 0],
     [True, 20],
     [True, 25]]],
   [[False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 20],
    [False, True, 80],
    [True, False, 100],
    [True, False, 100],
    [True, False, 100],
    [True, False, 100],
    [True, False, 100],
    [True, False, 100],
    [True, False, 100]]]]]
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:
TT and DN are both true on the same scan once the timer has finished.

On-delay timer (TON) evaluated once per scan. scans is a list of [rung_in, elapsed_ms since the previous scan]. The accumulator starts on the false-to-true scan without crediting that scan's elapsed time, then adds each later true scan's elapsed time, clamped at preset. A false rung resets the accumulator. DN is rung_in and acc >= preset; TT is rung_in and not DN. Return [DN, TT, ACC] per scan.

split: open-access


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

N = 1
observations = []
def solve(preset, scans):
    acc = 0
    prev = False
    out = []
    for rung_in, dt in scans:
        rung_in = bool(rung_in)
        if rung_in and prev:
            acc = min(preset, acc + dt)
        elif not rung_in:
            acc = 0
        dn = acc >= preset
        tt = rung_in and not dn
        prev = rung_in
        out.append([dn, tt, acc])
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['regression: scenario 4',
   [0,
    [[True, 10],
     [False, 25],
     [True, 25],
     [True, 20],
     [True, 40],
     [True, 20],
     [True, 75],
     [True, 0],
     [True, 10]]],
   [[True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0]]],
  ['control: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['control: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['control: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['control: scenario 1',
   [30, [[True, 40], [False, 75], [True, 60], [False, 25], [False, 10], [True, 60], [True, 25], [True, 40]]],
   [[False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 25],
    [True, False, 30]]],
  ['control: scenario 2',
   [30, [[False, 25], [True, 50], [True, 0], [True, 0], [True, 25], [True, 75], [True, 75]]],
   [[False, False, 0],
    [False, True, 0],
    [False, True, 0],
    [False, True, 0],
    [False, True, 25],
    [True, False, 30],
    [True, False, 30]]],
  ['control: scenario 3',
   [120, [[True, 25], [True, 20], [False, 75], [True, 75], [True, 0], [False, 10], [True, 25]]],
   [[False, True, 0],
    [False, True, 20],
    [False, False, 0],
    [False, True, 0],
    [False, True, 0],
    [False, False, 0],
    [False, True, 0]]]],
 [['regression: scenario 1',
   [0,
    [[True, 40],
     [True, 10],
     [True, 10],
     [False, 10],
     [True, 20],
     [True, 25],
     [True, 20],
     [False, 25],
     [True, 20]]],
   [[True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0]]],
  ['regression: scenario 32',
   [0,
    [[True, 20],
     [False, 75],
     [True, 50],
     [True, 50],
     [False, 0],
     [False, 0],
     [True, 20],
     [True, 10],
     [False, 40],
     [True, 25],
     [True, 75],
     [True, 10],
     [True, 0],
     [True, 60]]],
   [[True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0]]],
  ['control: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['control: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['control: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['control: scenario 2',
   [150,
    [[True, 60],
     [True, 10],
     [False, 20],
     [False, 40],
     [True, 50],
     [True, 25],
     [False, 25],
     [False, 75],
     [True, 25],
     [False, 0],
     [True, 60],
     [False, 10]]],
   [[False, True, 0],
    [False, True, 10],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 25],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0]]],
  ['control: scenario 3',
   [50,
    [[False, 50],
     [True, 75],
     [True, 75],
     [True, 20],
     [True, 75],
     [True, 0],
     [False, 60],
     [True, 25],
     [False, 10]]],
   [[False, False, 0],
    [False, True, 0],
    [True, False, 50],
    [True, False, 50],
    [True, False, 50],
    [True, False, 50],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0]]]],
 [['regression: scenario 34',
   [0, [[True, 10], [True, 20], [True, 60], [True, 25], [True, 50], [False, 50], [False, 25], [True, 40]]],
   [[True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [False, False, 0],
    [True, False, 0]]],
  ['regression: scenario 57',
   [0,
    [[True, 75],
     [False, 10],
     [True, 50],
     [True, 40],
     [True, 60],
     [True, 0],
     [False, 20],
     [False, 0],
     [True, 50]]],
   [[True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [False, False, 0],
    [True, False, 0]]],
  ['control: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['control: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['control: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['control: scenario 1',
   [50,
    [[True, 75],
     [True, 40],
     [True, 60],
     [True, 0],
     [True, 25],
     [False, 50],
     [False, 75],
     [True, 60],
     [True, 20],
     [True, 60],
     [False, 60],
     [True, 75]]],
   [[False, True, 0],
    [False, True, 40],
    [True, False, 50],
    [True, False, 50],
    [True, False, 50],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 20],
    [True, False, 50],
    [False, False, 0],
    [False, True, 0]]],
  ['control: scenario 2',
   [120, [[False, 0], [False, 75], [True, 75], [True, 0], [True, 0], [False, 75], [True, 60], [True, 40]]],
   [[False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 0],
    [False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40]]]],
 [['regression: scenario 9',
   [0,
    [[True, 20],
     [True, 40],
     [True, 50],
     [True, 20],
     [True, 25],
     [True, 10],
     [False, 60],
     [True, 75],
     [True, 40],
     [True, 10],
     [True, 60],
     [False, 10],
     [True, 10],
     [True, 40]]],
   [[True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0]]],
  ['regression: scenario 25',
   [0,
    [[True, 25],
     [False, 75],
     [False, 10],
     [True, 75],
     [True, 50],
     [True, 40],
     [True, 60],
     [True, 60],
     [True, 0],
     [True, 75],
     [True, 0]]],
   [[True, False, 0],
    [False, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0]]],
  ['control: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['control: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['control: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['regression: scenario 1',
   [0,
    [[True, 10],
     [True, 0],
     [False, 50],
     [True, 40],
     [False, 20],
     [False, 25],
     [True, 50],
     [True, 60],
     [True, 40]]],
   [[True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [False, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0]]],
  ['control: scenario 2',
   [100, [[False, 50], [True, 50], [True, 20], [False, 50], [True, 40], [True, 10], [False, 10]]],
   [[False, False, 0],
    [False, True, 0],
    [False, True, 20],
    [False, False, 0],
    [False, True, 0],
    [False, True, 10],
    [False, False, 0]]]],
 [['regression: scenario 40',
   [0,
    [[True, 10],
     [True, 25],
     [True, 50],
     [False, 60],
     [False, 20],
     [True, 50],
     [True, 0],
     [True, 60],
     [False, 60]]],
   [[True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0]]],
  ['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['control: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['control: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['control: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['control: scenario 1',
   [120,
    [[True, 0],
     [True, 50],
     [True, 50],
     [True, 75],
     [True, 75],
     [False, 40],
     [True, 25],
     [False, 0],
     [False, 10],
     [True, 25],
     [False, 0]]],
   [[False, True, 0],
    [False, True, 50],
    [False, True, 100],
    [True, False, 120],
    [True, False, 120],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0]]],
  ['control: scenario 2',
   [150, [[True, 50], [False, 40], [True, 20], [True, 20], [True, 10], [True, 40], [False, 50]]],
   [[False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 20],
    [False, True, 30],
    [False, True, 70],
    [False, False, 0]]],
  ['control: scenario 3',
   [200,
    [[False, 20],
     [False, 50],
     [True, 75],
     [False, 60],
     [False, 50],
     [True, 0],
     [True, 25],
     [True, 20],
     [True, 40],
     [True, 25],
     [True, 25],
     [True, 60]]],
   [[False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 25],
    [False, True, 45],
    [False, True, 85],
    [False, True, 110],
    [False, True, 135],
    [False, True, 195]]]]]
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(preset, scans):
    acc = 0
    prev = False
    out = []
    for rung_in, dt in scans:
        rung_in = bool(rung_in)
        if rung_in and prev:
            acc = min(preset, acc + dt)
        elif not rung_in:
            acc = 0
        dn = (rung_in or prev) and acc >= preset
        tt = rung_in and not dn
        prev = rung_in
        out.append([dn, tt, acc])
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['regression: scenario 4',
   [0,
    [[True, 10],
     [False, 25],
     [True, 25],
     [True, 20],
     [True, 40],
     [True, 20],
     [True, 75],
     [True, 0],
     [True, 10]]],
   [[True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0]]],
  ['control: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['control: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['control: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['control: scenario 1',
   [30, [[True, 40], [False, 75], [True, 60], [False, 25], [False, 10], [True, 60], [True, 25], [True, 40]]],
   [[False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 25],
    [True, False, 30]]],
  ['control: scenario 2',
   [30, [[False, 25], [True, 50], [True, 0], [True, 0], [True, 25], [True, 75], [True, 75]]],
   [[False, False, 0],
    [False, True, 0],
    [False, True, 0],
    [False, True, 0],
    [False, True, 25],
    [True, False, 30],
    [True, False, 30]]],
  ['control: scenario 3',
   [120, [[True, 25], [True, 20], [False, 75], [True, 75], [True, 0], [False, 10], [True, 25]]],
   [[False, True, 0],
    [False, True, 20],
    [False, False, 0],
    [False, True, 0],
    [False, True, 0],
    [False, False, 0],
    [False, True, 0]]]],
 [['regression: scenario 1',
   [0,
    [[True, 40],
     [True, 10],
     [True, 10],
     [False, 10],
     [True, 20],
     [True, 25],
     [True, 20],
     [False, 25],
     [True, 20]]],
   [[True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0]]],
  ['regression: scenario 32',
   [0,
    [[True, 20],
     [False, 75],
     [True, 50],
     [True, 50],
     [False, 0],
     [False, 0],
     [True, 20],
     [True, 10],
     [False, 40],
     [True, 25],
     [True, 75],
     [True, 10],
     [True, 0],
     [True, 60]]],
   [[True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0]]],
  ['control: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['control: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['control: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['control: scenario 2',
   [150,
    [[True, 60],
     [True, 10],
     [False, 20],
     [False, 40],
     [True, 50],
     [True, 25],
     [False, 25],
     [False, 75],
     [True, 25],
     [False, 0],
     [True, 60],
     [False, 10]]],
   [[False, True, 0],
    [False, True, 10],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 25],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0]]],
  ['control: scenario 3',
   [50,
    [[False, 50],
     [True, 75],
     [True, 75],
     [True, 20],
     [True, 75],
     [True, 0],
     [False, 60],
     [True, 25],
     [False, 10]]],
   [[False, False, 0],
    [False, True, 0],
    [True, False, 50],
    [True, False, 50],
    [True, False, 50],
    [True, False, 50],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0]]]],
 [['regression: scenario 34',
   [0, [[True, 10], [True, 20], [True, 60], [True, 25], [True, 50], [False, 50], [False, 25], [True, 40]]],
   [[True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [False, False, 0],
    [True, False, 0]]],
  ['regression: scenario 57',
   [0,
    [[True, 75],
     [False, 10],
     [True, 50],
     [True, 40],
     [True, 60],
     [True, 0],
     [False, 20],
     [False, 0],
     [True, 50]]],
   [[True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [False, False, 0],
    [True, False, 0]]],
  ['control: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['control: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['control: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['control: scenario 1',
   [50,
    [[True, 75],
     [True, 40],
     [True, 60],
     [True, 0],
     [True, 25],
     [False, 50],
     [False, 75],
     [True, 60],
     [True, 20],
     [True, 60],
     [False, 60],
     [True, 75]]],
   [[False, True, 0],
    [False, True, 40],
    [True, False, 50],
    [True, False, 50],
    [True, False, 50],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 20],
    [True, False, 50],
    [False, False, 0],
    [False, True, 0]]],
  ['control: scenario 2',
   [120, [[False, 0], [False, 75], [True, 75], [True, 0], [True, 0], [False, 75], [True, 60], [True, 40]]],
   [[False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 0],
    [False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40]]]],
 [['regression: scenario 9',
   [0,
    [[True, 20],
     [True, 40],
     [True, 50],
     [True, 20],
     [True, 25],
     [True, 10],
     [False, 60],
     [True, 75],
     [True, 40],
     [True, 10],
     [True, 60],
     [False, 10],
     [True, 10],
     [True, 40]]],
   [[True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0]]],
  ['regression: scenario 25',
   [0,
    [[True, 25],
     [False, 75],
     [False, 10],
     [True, 75],
     [True, 50],
     [True, 40],
     [True, 60],
     [True, 60],
     [True, 0],
     [True, 75],
     [True, 0]]],
   [[True, False, 0],
    [False, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0]]],
  ['control: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['control: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['control: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['regression: scenario 1',
   [0,
    [[True, 10],
     [True, 0],
     [False, 50],
     [True, 40],
     [False, 20],
     [False, 25],
     [True, 50],
     [True, 60],
     [True, 40]]],
   [[True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [True, False, 0],
    [False, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0]]],
  ['control: scenario 2',
   [100, [[False, 50], [True, 50], [True, 20], [False, 50], [True, 40], [True, 10], [False, 10]]],
   [[False, False, 0],
    [False, True, 0],
    [False, True, 20],
    [False, False, 0],
    [False, True, 0],
    [False, True, 10],
    [False, False, 0]]]],
 [['regression: scenario 40',
   [0,
    [[True, 10],
     [True, 25],
     [True, 50],
     [False, 60],
     [False, 20],
     [True, 50],
     [True, 0],
     [True, 60],
     [False, 60]]],
   [[True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0],
    [False, False, 0],
    [True, False, 0],
    [True, False, 0],
    [True, False, 0],
    [False, False, 0]]],
  ['regression: zero preset',
   [0, [[False, 10], [True, 10], [False, 5], [True, 40]]],
   [[False, False, 0], [True, False, 0], [False, False, 0], [True, False, 0]]],
  ['control: preset reached exactly',
   [100, [[True, 30], [True, 50], [True, 50], [True, 10]]],
   [[False, True, 0], [False, True, 50], [True, False, 100], [True, False, 100]]],
  ['control: interrupted timing restarts',
   [60, [[True, 40], [True, 40], [False, 40], [True, 40], [True, 40], [True, 40]]],
   [[False, True, 0],
    [False, True, 40],
    [False, False, 0],
    [False, True, 0],
    [False, True, 40],
    [True, False, 60]]],
  ['control: long hold after done',
   [50, [[True, 30], [True, 30], [True, 30], [True, 30], [False, 30]]],
   [[False, True, 0], [False, True, 30], [True, False, 50], [True, False, 50], [False, False, 0]]],
  ['control: scenario 1',
   [120,
    [[True, 0],
     [True, 50],
     [True, 50],
     [True, 75],
     [True, 75],
     [False, 40],
     [True, 25],
     [False, 0],
     [False, 10],
     [True, 25],
     [False, 0]]],
   [[False, True, 0],
    [False, True, 50],
    [False, True, 100],
    [True, False, 120],
    [True, False, 120],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0]]],
  ['control: scenario 2',
   [150, [[True, 50], [False, 40], [True, 20], [True, 20], [True, 10], [True, 40], [False, 50]]],
   [[False, True, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 20],
    [False, True, 30],
    [False, True, 70],
    [False, False, 0]]],
  ['control: scenario 3',
   [200,
    [[False, 20],
     [False, 50],
     [True, 75],
     [False, 60],
     [False, 50],
     [True, 0],
     [True, 25],
     [True, 20],
     [True, 40],
     [True, 25],
     [True, 25],
     [True, 60]]],
   [[False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, False, 0],
    [False, False, 0],
    [False, True, 0],
    [False, True, 25],
    [False, True, 45],
    [False, True, 85],
    [False, True, 110],
    [False, True, 135],
    [False, True, 195]]]]]
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 timer with a zero preset shows DN set on scans where its rung is false.

On-delay timer (TON) evaluated once per scan. scans is a list of [rung_in, elapsed_ms since the previous scan]. The accumulator starts on the false-to-true scan without crediting that scan's elapsed time, then adds each later true scan's elapsed time, clamped at preset. A false rung resets the accumulator. DN is rung_in and acc >= preset; TT is rung_in and not DN. Return [DN, TT, ACC] per scan.

split: open-access