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

N = 1
observations = []
def solve(x):
    count = 0
    nudge = False
    block_start = None
    out = []
    for t, ev in x['events']:
        if ev == 'obstruct':
            if block_start is None:
                block_start = t
            if nudge:
                out.append('ignored')
            else:
                count += 1
                if count >= 3 or t - block_start >= 20:
                    nudge = True
                    out.append('nudge')
                else:
                    out.append('reopen')
        elif ev == 'unblock':
            block_start = None
        elif ev == 'edge':
            out.append('reopen')
        elif ev == 'closed':
            nudge = False
            block_start = None
            out.append('done')
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: new cycle after closing', {'events': [[1, 'obstruct'], [2, 'obstruct'], [3, 'closed'], [4, 'obstruct'], [5, 'unblock']]}, ['reopen', 'reopen', 'done', 'reopen']), ('regression: closing clears nudging', {'events': [[0, 'obstruct'], [1, 'obstruct'], [2, 'obstruct'], [3, 'closed'], [4, 'obstruct']]}, ['reopen', 'reopen', 'nudge', 'done', 'reopen']), ('sampled regression 11', {'events': [[8, 'unblock'], [13, 'obstruct'], [18, 'closed'], [23, 'obstruct'], [35, 'obstruct']]}, ['reopen', 'done', 'reopen', 'reopen']), ('sampled regression 68', {'events': [[5, 'obstruct'], [13, 'obstruct'], [18, 'obstruct'], [30, 'obstruct'], [35, 'edge'], [36, 'obstruct'], [48, 'closed'], [53, 'obstruct'], [55, 'edge'], [60, 'unblock']]}, ['reopen', 'reopen', 'nudge', 'ignored', 'reopen', 'ignored', 'done', 'reopen', 'reopen']), ('boundary: third obstruction', {'events': [[1, 'obstruct'], [2, 'unblock'], [3, 'obstruct'], [4, 'unblock'], [5, 'obstruct']]}, ['reopen', 'reopen', 'nudge']), ('sampled regression 1', {'events': [[8, 'obstruct'], [13, 'closed'], [18, 'obstruct'], [26, 'edge'], [28, 'obstruct'], [29, 'obstruct'], [41, 'obstruct'], [42, 'obstruct'], [54, 'obstruct'], [66, 'closed']]}, ['reopen', 'done', 'reopen', 'reopen', 'reopen', 'nudge', 'ignored', 'ignored', 'ignored', 'done']), ('control 4', {'events': [[5, 'edge'], [10, 'unblock'], [11, 'obstruct'], [19, 'closed']]}, ['reopen', 'reopen', 'done']), ('control 7', {'events': [[2, 'unblock'], [10, 'edge'], [18, 'obstruct'], [23, 'unblock'], [28, 'edge'], [33, 'obstruct']]}, ['reopen', 'reopen', 'reopen', 'reopen'])], [('regression: closing clears nudging', {'events': [[0, 'obstruct'], [1, 'obstruct'], [2, 'obstruct'], [3, 'closed'], [4, 'obstruct']]}, ['reopen', 'reopen', 'nudge', 'done', 'reopen']), ('sampled regression 47', {'events': [[2, 'edge'], [10, 'obstruct'], [15, 'closed'], [20, 'unblock'], [28, 'obstruct'], [29, 'closed'], [41, 'edge'], [42, 'obstruct'], [43, 'closed'], [55, 'edge']]}, ['reopen', 'reopen', 'done', 'reopen', 'done', 'reopen', 'reopen', 'done', 'reopen']), ('boundary: edge contacts do not count', {'events': [[1, 'obstruct'], [2, 'edge'], [3, 'unblock'], [4, 'obstruct'], [5, 'edge']]}, ['reopen', 'reopen', 'reopen', 'reopen']), ('regression: new cycle after closing', {'events': [[1, 'obstruct'], [2, 'obstruct'], [3, 'closed'], [4, 'obstruct'], [5, 'unblock']]}, ['reopen', 'reopen', 'done', 'reopen']), ('boundary: curtain held for twenty seconds', {'events': [[0, 'obstruct'], [20, 'obstruct']]}, ['reopen', 'nudge']), ('sampled regression 12', {'events': [[5, 'obstruct'], [13, 'edge'], [15, 'unblock'], [16, 'obstruct'], [21, 'unblock'], [22, 'edge'], [30, 'closed'], [32, 'obstruct'], [44, 'edge']]}, ['reopen', 'reopen', 'reopen', 'reopen', 'done', 'reopen', 'reopen']), ('control 15', {'events': [[8, 'obstruct'], [9, 'obstruct'], [10, 'obstruct'], [11, 'unblock'], [16, 'obstruct'], [24, 'obstruct'], [29, 'edge']]}, ['reopen', 'reopen', 'nudge', 'ignored', 'ignored', 'reopen']), ('control 18', {'events': [[12, 'obstruct'], [20, 'obstruct'], [22, 'obstruct']]}, ['reopen', 'reopen', 'nudge'])], [('regression: new cycle after closing', {'events': [[1, 'obstruct'], [2, 'obstruct'], [3, 'closed'], [4, 'obstruct'], [5, 'unblock']]}, ['reopen', 'reopen', 'done', 'reopen']), ('regression: closing clears nudging', {'events': [[0, 'obstruct'], [1, 'obstruct'], [2, 'obstruct'], [3, 'closed'], [4, 'obstruct']]}, ['reopen', 'reopen', 'nudge', 'done', 'reopen']), ('sampled regression 69', {'events': [[2, 'unblock'], [14, 'edge'], [15, 'obstruct'], [16, 'obstruct'], [28, 'obstruct'], [36, 'obstruct'], [38, 'obstruct'], [50, 'closed'], [55, 'edge'], [56, 'obstruct']]}, ['reopen', 'reopen', 'reopen', 'nudge', 'ignored', 'ignored', 'done', 'reopen', 'reopen']), ('boundary: curtain held for twenty seconds', {'events': [[0, 'obstruct'], [20, 'obstruct']]}, ['reopen', 'nudge']), ('boundary: curtain broken then blocked again', {'events': [[0, 'obstruct'], [5, 'unblock'], [15, 'obstruct'], [26, 'obstruct']]}, ['reopen', 'reopen', 'nudge']), ('control 23', {'events': [[1, 'unblock'], [6, 'unblock'], [18, 'obstruct'], [30, 'closed']]}, ['reopen', 'done']), ('control 26', {'events': [[12, 'closed'], [13, 'closed'], [15, 'obstruct'], [17, 'obstruct'], [19, 'obstruct']]}, ['done', 'done', 'reopen', 'reopen', 'nudge']), ('control 29', {'events': [[8, 'edge'], [10, 'obstruct'], [12, 'obstruct'], [20, 'closed']]}, ['reopen', 'reopen', 'reopen', 'done'])], [('regression: closing clears nudging', {'events': [[0, 'obstruct'], [1, 'obstruct'], [2, 'obstruct'], [3, 'closed'], [4, 'obstruct']]}, ['reopen', 'reopen', 'nudge', 'done', 'reopen']), ('sampled regression 25', {'events': [[2, 'obstruct'], [10, 'obstruct'], [18, 'closed'], [20, 'obstruct']]}, ['reopen', 'reopen', 'done', 'reopen']), ('sampled regression 68', {'events': [[5, 'obstruct'], [13, 'obstruct'], [18, 'obstruct'], [30, 'obstruct'], [35, 'edge'], [36, 'obstruct'], [48, 'closed'], [53, 'obstruct'], [55, 'edge'], [60, 'unblock']]}, ['reopen', 'reopen', 'nudge', 'ignored', 'reopen', 'ignored', 'done', 'reopen', 'reopen']), ('boundary: third obstruction', {'events': [[1, 'obstruct'], [2, 'unblock'], [3, 'obstruct'], [4, 'unblock'], [5, 'obstruct']]}, ['reopen', 'reopen', 'nudge']), ('boundary: safety edge while nudging', {'events': [[1, 'obstruct'], [2, 'obstruct'], [3, 'obstruct'], [4, 'edge'], [5, 'obstruct']]}, ['reopen', 'reopen', 'nudge', 'reopen', 'ignored']), ('sampled regression 34', {'events': [[8, 'edge'], [16, 'obstruct'], [24, 'obstruct'], [36, 'closed'], [48, 'obstruct'], [60, 'obstruct'], [62, 'obstruct'], [64, 'unblock'], [72, 'obstruct'], [80, 'unblock']]}, ['reopen', 'reopen', 'reopen', 'done', 'reopen', 'reopen', 'nudge', 'ignored']), ('control 37', {'events': [[2, 'closed'], [4, 'closed'], [9, 'obstruct'], [21, 'edge']]}, ['done', 'done', 'reopen', 'reopen']), ('control 40', {'events': [[2, 'closed'], [7, 'obstruct'], [15, 'edge'], [16, 'obstruct'], [18, 'closed']]}, ['done', 'reopen', 'reopen', 'reopen', 'done'])], [('regression: new cycle after closing', {'events': [[1, 'obstruct'], [2, 'obstruct'], [3, 'closed'], [4, 'obstruct'], [5, 'unblock']]}, ['reopen', 'reopen', 'done', 'reopen']), ('regression: closing clears nudging', {'events': [[0, 'obstruct'], [1, 'obstruct'], [2, 'obstruct'], [3, 'closed'], [4, 'obstruct']]}, ['reopen', 'reopen', 'nudge', 'done', 'reopen']), ('sampled regression 68', {'events': [[5, 'obstruct'], [13, 'obstruct'], [18, 'obstruct'], [30, 'obstruct'], [35, 'edge'], [36, 'obstruct'], [48, 'closed'], [53, 'obstruct'], [55, 'edge'], [60, 'unblock']]}, ['reopen', 'reopen', 'nudge', 'ignored', 'reopen', 'ignored', 'done', 'reopen', 'reopen']), ('boundary: safety edge while nudging', {'events': [[1, 'obstruct'], [2, 'obstruct'], [3, 'obstruct'], [4, 'edge'], [5, 'obstruct']]}, ['reopen', 'reopen', 'nudge', 'reopen', 'ignored']), ('boundary: edge contacts do not count', {'events': [[1, 'obstruct'], [2, 'edge'], [3, 'unblock'], [4, 'obstruct'], [5, 'edge']]}, ['reopen', 'reopen', 'reopen', 'reopen']), ('control 45', {'events': [[5, 'edge'], [17, 'closed'], [22, 'obstruct'], [24, 'closed']]}, ['reopen', 'done', 'reopen', 'done']), ('control 48', {'events': [[2, 'obstruct'], [7, 'obstruct'], [15, 'obstruct'], [27, 'obstruct'], [35, 'unblock']]}, ['reopen', 'reopen', 'nudge', 'ignored']), ('control 51', {'events': [[8, 'closed'], [9, 'closed'], [14, 'obstruct'], [26, 'closed'], [38, 'obstruct']]}, ['done', 'done', 'reopen', 'done', 'reopen'])]]
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):
    count = 0
    nudge = False
    block_start = None
    out = []
    for t, ev in x['events']:
        if ev == 'obstruct':
            if block_start is None:
                block_start = t
            if nudge:
                out.append('ignored')
            else:
                count += 1
                if count >= 3 or t - block_start >= 20:
                    nudge = True
                    out.append('nudge')
                else:
                    out.append('reopen')
        elif ev == 'unblock':
            block_start = None
        elif ev == 'edge':
            out.append('reopen')
        elif ev == 'closed':
            count = 0
            block_start = None
            out.append('done')
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: new cycle after closing', {'events': [[1, 'obstruct'], [2, 'obstruct'], [3, 'closed'], [4, 'obstruct'], [5, 'unblock']]}, ['reopen', 'reopen', 'done', 'reopen']), ('regression: closing clears nudging', {'events': [[0, 'obstruct'], [1, 'obstruct'], [2, 'obstruct'], [3, 'closed'], [4, 'obstruct']]}, ['reopen', 'reopen', 'nudge', 'done', 'reopen']), ('sampled regression 11', {'events': [[8, 'unblock'], [13, 'obstruct'], [18, 'closed'], [23, 'obstruct'], [35, 'obstruct']]}, ['reopen', 'done', 'reopen', 'reopen']), ('sampled regression 68', {'events': [[5, 'obstruct'], [13, 'obstruct'], [18, 'obstruct'], [30, 'obstruct'], [35, 'edge'], [36, 'obstruct'], [48, 'closed'], [53, 'obstruct'], [55, 'edge'], [60, 'unblock']]}, ['reopen', 'reopen', 'nudge', 'ignored', 'reopen', 'ignored', 'done', 'reopen', 'reopen']), ('boundary: third obstruction', {'events': [[1, 'obstruct'], [2, 'unblock'], [3, 'obstruct'], [4, 'unblock'], [5, 'obstruct']]}, ['reopen', 'reopen', 'nudge']), ('sampled regression 1', {'events': [[8, 'obstruct'], [13, 'closed'], [18, 'obstruct'], [26, 'edge'], [28, 'obstruct'], [29, 'obstruct'], [41, 'obstruct'], [42, 'obstruct'], [54, 'obstruct'], [66, 'closed']]}, ['reopen', 'done', 'reopen', 'reopen', 'reopen', 'nudge', 'ignored', 'ignored', 'ignored', 'done']), ('control 4', {'events': [[5, 'edge'], [10, 'unblock'], [11, 'obstruct'], [19, 'closed']]}, ['reopen', 'reopen', 'done']), ('control 7', {'events': [[2, 'unblock'], [10, 'edge'], [18, 'obstruct'], [23, 'unblock'], [28, 'edge'], [33, 'obstruct']]}, ['reopen', 'reopen', 'reopen', 'reopen'])], [('regression: closing clears nudging', {'events': [[0, 'obstruct'], [1, 'obstruct'], [2, 'obstruct'], [3, 'closed'], [4, 'obstruct']]}, ['reopen', 'reopen', 'nudge', 'done', 'reopen']), ('sampled regression 47', {'events': [[2, 'edge'], [10, 'obstruct'], [15, 'closed'], [20, 'unblock'], [28, 'obstruct'], [29, 'closed'], [41, 'edge'], [42, 'obstruct'], [43, 'closed'], [55, 'edge']]}, ['reopen', 'reopen', 'done', 'reopen', 'done', 'reopen', 'reopen', 'done', 'reopen']), ('boundary: edge contacts do not count', {'events': [[1, 'obstruct'], [2, 'edge'], [3, 'unblock'], [4, 'obstruct'], [5, 'edge']]}, ['reopen', 'reopen', 'reopen', 'reopen']), ('regression: new cycle after closing', {'events': [[1, 'obstruct'], [2, 'obstruct'], [3, 'closed'], [4, 'obstruct'], [5, 'unblock']]}, ['reopen', 'reopen', 'done', 'reopen']), ('boundary: curtain held for twenty seconds', {'events': [[0, 'obstruct'], [20, 'obstruct']]}, ['reopen', 'nudge']), ('sampled regression 12', {'events': [[5, 'obstruct'], [13, 'edge'], [15, 'unblock'], [16, 'obstruct'], [21, 'unblock'], [22, 'edge'], [30, 'closed'], [32, 'obstruct'], [44, 'edge']]}, ['reopen', 'reopen', 'reopen', 'reopen', 'done', 'reopen', 'reopen']), ('control 15', {'events': [[8, 'obstruct'], [9, 'obstruct'], [10, 'obstruct'], [11, 'unblock'], [16, 'obstruct'], [24, 'obstruct'], [29, 'edge']]}, ['reopen', 'reopen', 'nudge', 'ignored', 'ignored', 'reopen']), ('control 18', {'events': [[12, 'obstruct'], [20, 'obstruct'], [22, 'obstruct']]}, ['reopen', 'reopen', 'nudge'])], [('regression: new cycle after closing', {'events': [[1, 'obstruct'], [2, 'obstruct'], [3, 'closed'], [4, 'obstruct'], [5, 'unblock']]}, ['reopen', 'reopen', 'done', 'reopen']), ('regression: closing clears nudging', {'events': [[0, 'obstruct'], [1, 'obstruct'], [2, 'obstruct'], [3, 'closed'], [4, 'obstruct']]}, ['reopen', 'reopen', 'nudge', 'done', 'reopen']), ('sampled regression 69', {'events': [[2, 'unblock'], [14, 'edge'], [15, 'obstruct'], [16, 'obstruct'], [28, 'obstruct'], [36, 'obstruct'], [38, 'obstruct'], [50, 'closed'], [55, 'edge'], [56, 'obstruct']]}, ['reopen', 'reopen', 'reopen', 'nudge', 'ignored', 'ignored', 'done', 'reopen', 'reopen']), ('boundary: curtain held for twenty seconds', {'events': [[0, 'obstruct'], [20, 'obstruct']]}, ['reopen', 'nudge']), ('boundary: curtain broken then blocked again', {'events': [[0, 'obstruct'], [5, 'unblock'], [15, 'obstruct'], [26, 'obstruct']]}, ['reopen', 'reopen', 'nudge']), ('control 23', {'events': [[1, 'unblock'], [6, 'unblock'], [18, 'obstruct'], [30, 'closed']]}, ['reopen', 'done']), ('control 26', {'events': [[12, 'closed'], [13, 'closed'], [15, 'obstruct'], [17, 'obstruct'], [19, 'obstruct']]}, ['done', 'done', 'reopen', 'reopen', 'nudge']), ('control 29', {'events': [[8, 'edge'], [10, 'obstruct'], [12, 'obstruct'], [20, 'closed']]}, ['reopen', 'reopen', 'reopen', 'done'])], [('regression: closing clears nudging', {'events': [[0, 'obstruct'], [1, 'obstruct'], [2, 'obstruct'], [3, 'closed'], [4, 'obstruct']]}, ['reopen', 'reopen', 'nudge', 'done', 'reopen']), ('sampled regression 25', {'events': [[2, 'obstruct'], [10, 'obstruct'], [18, 'closed'], [20, 'obstruct']]}, ['reopen', 'reopen', 'done', 'reopen']), ('sampled regression 68', {'events': [[5, 'obstruct'], [13, 'obstruct'], [18, 'obstruct'], [30, 'obstruct'], [35, 'edge'], [36, 'obstruct'], [48, 'closed'], [53, 'obstruct'], [55, 'edge'], [60, 'unblock']]}, ['reopen', 'reopen', 'nudge', 'ignored', 'reopen', 'ignored', 'done', 'reopen', 'reopen']), ('boundary: third obstruction', {'events': [[1, 'obstruct'], [2, 'unblock'], [3, 'obstruct'], [4, 'unblock'], [5, 'obstruct']]}, ['reopen', 'reopen', 'nudge']), ('boundary: safety edge while nudging', {'events': [[1, 'obstruct'], [2, 'obstruct'], [3, 'obstruct'], [4, 'edge'], [5, 'obstruct']]}, ['reopen', 'reopen', 'nudge', 'reopen', 'ignored']), ('sampled regression 34', {'events': [[8, 'edge'], [16, 'obstruct'], [24, 'obstruct'], [36, 'closed'], [48, 'obstruct'], [60, 'obstruct'], [62, 'obstruct'], [64, 'unblock'], [72, 'obstruct'], [80, 'unblock']]}, ['reopen', 'reopen', 'reopen', 'done', 'reopen', 'reopen', 'nudge', 'ignored']), ('control 37', {'events': [[2, 'closed'], [4, 'closed'], [9, 'obstruct'], [21, 'edge']]}, ['done', 'done', 'reopen', 'reopen']), ('control 40', {'events': [[2, 'closed'], [7, 'obstruct'], [15, 'edge'], [16, 'obstruct'], [18, 'closed']]}, ['done', 'reopen', 'reopen', 'reopen', 'done'])], [('regression: new cycle after closing', {'events': [[1, 'obstruct'], [2, 'obstruct'], [3, 'closed'], [4, 'obstruct'], [5, 'unblock']]}, ['reopen', 'reopen', 'done', 'reopen']), ('regression: closing clears nudging', {'events': [[0, 'obstruct'], [1, 'obstruct'], [2, 'obstruct'], [3, 'closed'], [4, 'obstruct']]}, ['reopen', 'reopen', 'nudge', 'done', 'reopen']), ('sampled regression 68', {'events': [[5, 'obstruct'], [13, 'obstruct'], [18, 'obstruct'], [30, 'obstruct'], [35, 'edge'], [36, 'obstruct'], [48, 'closed'], [53, 'obstruct'], [55, 'edge'], [60, 'unblock']]}, ['reopen', 'reopen', 'nudge', 'ignored', 'reopen', 'ignored', 'done', 'reopen', 'reopen']), ('boundary: safety edge while nudging', {'events': [[1, 'obstruct'], [2, 'obstruct'], [3, 'obstruct'], [4, 'edge'], [5, 'obstruct']]}, ['reopen', 'reopen', 'nudge', 'reopen', 'ignored']), ('boundary: edge contacts do not count', {'events': [[1, 'obstruct'], [2, 'edge'], [3, 'unblock'], [4, 'obstruct'], [5, 'edge']]}, ['reopen', 'reopen', 'reopen', 'reopen']), ('control 45', {'events': [[5, 'edge'], [17, 'closed'], [22, 'obstruct'], [24, 'closed']]}, ['reopen', 'done', 'reopen', 'done']), ('control 48', {'events': [[2, 'obstruct'], [7, 'obstruct'], [15, 'obstruct'], [27, 'obstruct'], [35, 'unblock']]}, ['reopen', 'reopen', 'nudge', 'ignored']), ('control 51', {'events': [[8, 'closed'], [9, 'closed'], [14, 'obstruct'], [26, 'closed'], [38, 'obstruct']]}, ['done', 'done', 'reopen', 'done', 'reopen'])]]
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:
Obstructions from the previous door cycle carry over into the next.

During a door cycle each light-curtain obstruction reopens the doors and counts; the third obstruction, or an obstruction while the curtain has been blocked continuously for 20 s or more since the first unbroken obstruction, starts nudging (slow close, curtain ignored). While nudging, curtain obstructions are ignored. The mechanical safety edge always reopens and does not affect counting. unblock ends a continuous blockage. closed ends the cycle and resets everything.

split: open-access


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

N = 1
observations = []
def solve(x):
    count = 0
    nudge = False
    block_start = None
    out = []
    for t, ev in x['events']:
        if ev == 'obstruct':
            block_start = t
            if nudge:
                out.append('ignored')
            else:
                count += 1
                if count >= 3 or t - block_start >= 20:
                    nudge = True
                    out.append('nudge')
                else:
                    out.append('reopen')
        elif ev == 'unblock':
            block_start = None
        elif ev == 'edge':
            out.append('reopen')
        elif ev == 'closed':
            count = 0
            nudge = False
            block_start = None
            out.append('done')
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: curtain held for twenty seconds', {'events': [[0, 'obstruct'], [20, 'obstruct']]}, ['reopen', 'nudge']), ('control 10', {'events': [[8, 'edge'], [13, 'obstruct'], [18, 'edge'], [30, 'unblock'], [35, 'obstruct'], [40, 'obstruct'], [42, 'unblock']]}, ['reopen', 'reopen', 'reopen', 'reopen', 'nudge']), ('control 64', {'events': [[8, 'obstruct'], [13, 'edge'], [18, 'unblock'], [26, 'unblock'], [34, 'obstruct'], [36, 'obstruct']]}, ['reopen', 'reopen', 'reopen', 'nudge']), ('boundary: third obstruction', {'events': [[1, 'obstruct'], [2, 'unblock'], [3, 'obstruct'], [4, 'unblock'], [5, 'obstruct']]}, ['reopen', 'reopen', 'nudge']), ('boundary: safety edge while nudging', {'events': [[1, 'obstruct'], [2, 'obstruct'], [3, 'obstruct'], [4, 'edge'], [5, 'obstruct']]}, ['reopen', 'reopen', 'nudge', 'reopen', 'ignored']), ('control 1', {'events': [[8, 'obstruct'], [13, 'closed'], [18, 'obstruct'], [26, 'edge'], [28, 'obstruct'], [29, 'obstruct'], [41, 'obstruct'], [42, 'obstruct'], [54, 'obstruct'], [66, 'closed']]}, ['reopen', 'done', 'reopen', 'reopen', 'reopen', 'nudge', 'ignored', 'ignored', 'ignored', 'done']), ('control 4', {'events': [[5, 'edge'], [10, 'unblock'], [11, 'obstruct'], [19, 'closed']]}, ['reopen', 'reopen', 'done']), ('control 7', {'events': [[2, 'unblock'], [10, 'edge'], [18, 'obstruct'], [23, 'unblock'], [28, 'edge'], [33, 'obstruct']]}, ['reopen', 'reopen', 'reopen', 'reopen'])], [('regression: curtain held for twenty seconds', {'events': [[0, 'obstruct'], [20, 'obstruct']]}, ['reopen', 'nudge']), ('control 64', {'events': [[8, 'obstruct'], [13, 'edge'], [18, 'unblock'], [26, 'unblock'], [34, 'obstruct'], [36, 'obstruct']]}, ['reopen', 'reopen', 'reopen', 'nudge']), ('sampled regression 3', {'events': [[1, 'obstruct'], [13, 'edge'], [21, 'obstruct'], [26, 'unblock'], [27, 'obstruct'], [32, 'edge'], [40, 'obstruct'], [48, 'obstruct'], [56, 'unblock'], [64, 'closed']]}, ['reopen', 'reopen', 'nudge', 'ignored', 'reopen', 'ignored', 'ignored', 'done']), ('control 10', {'events': [[8, 'edge'], [13, 'obstruct'], [18, 'edge'], [30, 'unblock'], [35, 'obstruct'], [40, 'obstruct'], [42, 'unblock']]}, ['reopen', 'reopen', 'reopen', 'reopen', 'nudge']), ('boundary: edge contacts do not count', {'events': [[1, 'obstruct'], [2, 'edge'], [3, 'unblock'], [4, 'obstruct'], [5, 'edge']]}, ['reopen', 'reopen', 'reopen', 'reopen']), ('control 12', {'events': [[5, 'obstruct'], [13, 'edge'], [15, 'unblock'], [16, 'obstruct'], [21, 'unblock'], [22, 'edge'], [30, 'closed'], [32, 'obstruct'], [44, 'edge']]}, ['reopen', 'reopen', 'reopen', 'reopen', 'done', 'reopen', 'reopen']), ('control 15', {'events': [[8, 'obstruct'], [9, 'obstruct'], [10, 'obstruct'], [11, 'unblock'], [16, 'obstruct'], [24, 'obstruct'], [29, 'edge']]}, ['reopen', 'reopen', 'nudge', 'ignored', 'ignored', 'reopen']), ('control 18', {'events': [[12, 'obstruct'], [20, 'obstruct'], [22, 'obstruct']]}, ['reopen', 'reopen', 'nudge'])], [('regression: curtain held for twenty seconds', {'events': [[0, 'obstruct'], [20, 'obstruct']]}, ['reopen', 'nudge']), ('control 10', {'events': [[8, 'edge'], [13, 'obstruct'], [18, 'edge'], [30, 'unblock'], [35, 'obstruct'], [40, 'obstruct'], [42, 'unblock']]}, ['reopen', 'reopen', 'reopen', 'reopen', 'nudge']), ('sampled regression 65', {'events': [[1, 'obstruct'], [13, 'edge'], [25, 'obstruct'], [37, 'unblock']]}, ['reopen', 'reopen', 'nudge']), ('control 64', {'events': [[8, 'obstruct'], [13, 'edge'], [18, 'unblock'], [26, 'unblock'], [34, 'obstruct'], [36, 'obstruct']]}, ['reopen', 'reopen', 'reopen', 'nudge']), ('boundary: curtain broken then blocked again', {'events': [[0, 'obstruct'], [5, 'unblock'], [15, 'obstruct'], [26, 'obstruct']]}, ['reopen', 'reopen', 'nudge']), ('control 23', {'events': [[1, 'unblock'], [6, 'unblock'], [18, 'obstruct'], [30, 'closed']]}, ['reopen', 'done']), ('control 26', {'events': [[12, 'closed'], [13, 'closed'], [15, 'obstruct'], [17, 'obstruct'], [19, 'obstruct']]}, ['done', 'done', 'reopen', 'reopen', 'nudge']), ('control 29', {'events': [[8, 'edge'], [10, 'obstruct'], [12, 'obstruct'], [20, 'closed']]}, ['reopen', 'reopen', 'reopen', 'done'])], [('regression: curtain held for twenty seconds', {'events': [[0, 'obstruct'], [20, 'obstruct']]}, ['reopen', 'nudge']), ('control 64', {'events': [[8, 'obstruct'], [13, 'edge'], [18, 'unblock'], [26, 'unblock'], [34, 'obstruct'], [36, 'obstruct']]}, ['reopen', 'reopen', 'reopen', 'nudge']), ('control 10', {'events': [[8, 'edge'], [13, 'obstruct'], [18, 'edge'], [30, 'unblock'], [35, 'obstruct'], [40, 'obstruct'], [42, 'unblock']]}, ['reopen', 'reopen', 'reopen', 'reopen', 'nudge']), ('boundary: closing clears nudging', {'events': [[0, 'obstruct'], [1, 'obstruct'], [2, 'obstruct'], [3, 'closed'], [4, 'obstruct']]}, ['reopen', 'reopen', 'nudge', 'done', 'reopen']), ('boundary: third obstruction', {'events': [[1, 'obstruct'], [2, 'unblock'], [3, 'obstruct'], [4, 'unblock'], [5, 'obstruct']]}, ['reopen', 'reopen', 'nudge']), ('control 34', {'events': [[8, 'edge'], [16, 'obstruct'], [24, 'obstruct'], [36, 'closed'], [48, 'obstruct'], [60, 'obstruct'], [62, 'obstruct'], [64, 'unblock'], [72, 'obstruct'], [80, 'unblock']]}, ['reopen', 'reopen', 'reopen', 'done', 'reopen', 'reopen', 'nudge', 'ignored']), ('control 37', {'events': [[2, 'closed'], [4, 'closed'], [9, 'obstruct'], [21, 'edge']]}, ['done', 'done', 'reopen', 'reopen']), ('control 40', {'events': [[2, 'closed'], [7, 'obstruct'], [15, 'edge'], [16, 'obstruct'], [18, 'closed']]}, ['done', 'reopen', 'reopen', 'reopen', 'done'])], [('regression: curtain held for twenty seconds', {'events': [[0, 'obstruct'], [20, 'obstruct']]}, ['reopen', 'nudge']), ('control 10', {'events': [[8, 'edge'], [13, 'obstruct'], [18, 'edge'], [30, 'unblock'], [35, 'obstruct'], [40, 'obstruct'], [42, 'unblock']]}, ['reopen', 'reopen', 'reopen', 'reopen', 'nudge']), ('sampled regression 3', {'events': [[1, 'obstruct'], [13, 'edge'], [21, 'obstruct'], [26, 'unblock'], [27, 'obstruct'], [32, 'edge'], [40, 'obstruct'], [48, 'obstruct'], [56, 'unblock'], [64, 'closed']]}, ['reopen', 'reopen', 'nudge', 'ignored', 'reopen', 'ignored', 'ignored', 'done']), ('control 64', {'events': [[8, 'obstruct'], [13, 'edge'], [18, 'unblock'], [26, 'unblock'], [34, 'obstruct'], [36, 'obstruct']]}, ['reopen', 'reopen', 'reopen', 'nudge']), ('boundary: safety edge while nudging', {'events': [[1, 'obstruct'], [2, 'obstruct'], [3, 'obstruct'], [4, 'edge'], [5, 'obstruct']]}, ['reopen', 'reopen', 'nudge', 'reopen', 'ignored']), ('control 45', {'events': [[5, 'edge'], [17, 'closed'], [22, 'obstruct'], [24, 'closed']]}, ['reopen', 'done', 'reopen', 'done']), ('control 48', {'events': [[2, 'obstruct'], [7, 'obstruct'], [15, 'obstruct'], [27, 'obstruct'], [35, 'unblock']]}, ['reopen', 'reopen', 'nudge', 'ignored']), ('control 51', {'events': [[8, 'closed'], [9, 'closed'], [14, 'obstruct'], [26, 'closed'], [38, 'obstruct']]}, ['done', 'done', 'reopen', 'done', 'reopen'])]]
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):
    count = 0
    nudge = False
    block_start = None
    out = []
    for t, ev in x['events']:
        if ev == 'obstruct':
            if block_start is None:
                block_start = t
            if nudge:
                out.append('ignored')
            else:
                count += 1
                if count >= 3 or t - block_start >= 20:
                    nudge = True
                    out.append('nudge')
                else:
                    out.append('reopen')
        elif ev == 'unblock':
            pass
        elif ev == 'edge':
            out.append('reopen')
        elif ev == 'closed':
            count = 0
            nudge = False
            block_start = None
            out.append('done')
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: curtain held for twenty seconds', {'events': [[0, 'obstruct'], [20, 'obstruct']]}, ['reopen', 'nudge']), ('control 10', {'events': [[8, 'edge'], [13, 'obstruct'], [18, 'edge'], [30, 'unblock'], [35, 'obstruct'], [40, 'obstruct'], [42, 'unblock']]}, ['reopen', 'reopen', 'reopen', 'reopen', 'nudge']), ('control 64', {'events': [[8, 'obstruct'], [13, 'edge'], [18, 'unblock'], [26, 'unblock'], [34, 'obstruct'], [36, 'obstruct']]}, ['reopen', 'reopen', 'reopen', 'nudge']), ('boundary: third obstruction', {'events': [[1, 'obstruct'], [2, 'unblock'], [3, 'obstruct'], [4, 'unblock'], [5, 'obstruct']]}, ['reopen', 'reopen', 'nudge']), ('boundary: safety edge while nudging', {'events': [[1, 'obstruct'], [2, 'obstruct'], [3, 'obstruct'], [4, 'edge'], [5, 'obstruct']]}, ['reopen', 'reopen', 'nudge', 'reopen', 'ignored']), ('control 1', {'events': [[8, 'obstruct'], [13, 'closed'], [18, 'obstruct'], [26, 'edge'], [28, 'obstruct'], [29, 'obstruct'], [41, 'obstruct'], [42, 'obstruct'], [54, 'obstruct'], [66, 'closed']]}, ['reopen', 'done', 'reopen', 'reopen', 'reopen', 'nudge', 'ignored', 'ignored', 'ignored', 'done']), ('control 4', {'events': [[5, 'edge'], [10, 'unblock'], [11, 'obstruct'], [19, 'closed']]}, ['reopen', 'reopen', 'done']), ('control 7', {'events': [[2, 'unblock'], [10, 'edge'], [18, 'obstruct'], [23, 'unblock'], [28, 'edge'], [33, 'obstruct']]}, ['reopen', 'reopen', 'reopen', 'reopen'])], [('regression: curtain held for twenty seconds', {'events': [[0, 'obstruct'], [20, 'obstruct']]}, ['reopen', 'nudge']), ('control 64', {'events': [[8, 'obstruct'], [13, 'edge'], [18, 'unblock'], [26, 'unblock'], [34, 'obstruct'], [36, 'obstruct']]}, ['reopen', 'reopen', 'reopen', 'nudge']), ('sampled regression 3', {'events': [[1, 'obstruct'], [13, 'edge'], [21, 'obstruct'], [26, 'unblock'], [27, 'obstruct'], [32, 'edge'], [40, 'obstruct'], [48, 'obstruct'], [56, 'unblock'], [64, 'closed']]}, ['reopen', 'reopen', 'nudge', 'ignored', 'reopen', 'ignored', 'ignored', 'done']), ('control 10', {'events': [[8, 'edge'], [13, 'obstruct'], [18, 'edge'], [30, 'unblock'], [35, 'obstruct'], [40, 'obstruct'], [42, 'unblock']]}, ['reopen', 'reopen', 'reopen', 'reopen', 'nudge']), ('boundary: edge contacts do not count', {'events': [[1, 'obstruct'], [2, 'edge'], [3, 'unblock'], [4, 'obstruct'], [5, 'edge']]}, ['reopen', 'reopen', 'reopen', 'reopen']), ('control 12', {'events': [[5, 'obstruct'], [13, 'edge'], [15, 'unblock'], [16, 'obstruct'], [21, 'unblock'], [22, 'edge'], [30, 'closed'], [32, 'obstruct'], [44, 'edge']]}, ['reopen', 'reopen', 'reopen', 'reopen', 'done', 'reopen', 'reopen']), ('control 15', {'events': [[8, 'obstruct'], [9, 'obstruct'], [10, 'obstruct'], [11, 'unblock'], [16, 'obstruct'], [24, 'obstruct'], [29, 'edge']]}, ['reopen', 'reopen', 'nudge', 'ignored', 'ignored', 'reopen']), ('control 18', {'events': [[12, 'obstruct'], [20, 'obstruct'], [22, 'obstruct']]}, ['reopen', 'reopen', 'nudge'])], [('regression: curtain held for twenty seconds', {'events': [[0, 'obstruct'], [20, 'obstruct']]}, ['reopen', 'nudge']), ('control 10', {'events': [[8, 'edge'], [13, 'obstruct'], [18, 'edge'], [30, 'unblock'], [35, 'obstruct'], [40, 'obstruct'], [42, 'unblock']]}, ['reopen', 'reopen', 'reopen', 'reopen', 'nudge']), ('sampled regression 65', {'events': [[1, 'obstruct'], [13, 'edge'], [25, 'obstruct'], [37, 'unblock']]}, ['reopen', 'reopen', 'nudge']), ('control 64', {'events': [[8, 'obstruct'], [13, 'edge'], [18, 'unblock'], [26, 'unblock'], [34, 'obstruct'], [36, 'obstruct']]}, ['reopen', 'reopen', 'reopen', 'nudge']), ('boundary: curtain broken then blocked again', {'events': [[0, 'obstruct'], [5, 'unblock'], [15, 'obstruct'], [26, 'obstruct']]}, ['reopen', 'reopen', 'nudge']), ('control 23', {'events': [[1, 'unblock'], [6, 'unblock'], [18, 'obstruct'], [30, 'closed']]}, ['reopen', 'done']), ('control 26', {'events': [[12, 'closed'], [13, 'closed'], [15, 'obstruct'], [17, 'obstruct'], [19, 'obstruct']]}, ['done', 'done', 'reopen', 'reopen', 'nudge']), ('control 29', {'events': [[8, 'edge'], [10, 'obstruct'], [12, 'obstruct'], [20, 'closed']]}, ['reopen', 'reopen', 'reopen', 'done'])], [('regression: curtain held for twenty seconds', {'events': [[0, 'obstruct'], [20, 'obstruct']]}, ['reopen', 'nudge']), ('control 64', {'events': [[8, 'obstruct'], [13, 'edge'], [18, 'unblock'], [26, 'unblock'], [34, 'obstruct'], [36, 'obstruct']]}, ['reopen', 'reopen', 'reopen', 'nudge']), ('control 10', {'events': [[8, 'edge'], [13, 'obstruct'], [18, 'edge'], [30, 'unblock'], [35, 'obstruct'], [40, 'obstruct'], [42, 'unblock']]}, ['reopen', 'reopen', 'reopen', 'reopen', 'nudge']), ('boundary: closing clears nudging', {'events': [[0, 'obstruct'], [1, 'obstruct'], [2, 'obstruct'], [3, 'closed'], [4, 'obstruct']]}, ['reopen', 'reopen', 'nudge', 'done', 'reopen']), ('boundary: third obstruction', {'events': [[1, 'obstruct'], [2, 'unblock'], [3, 'obstruct'], [4, 'unblock'], [5, 'obstruct']]}, ['reopen', 'reopen', 'nudge']), ('control 34', {'events': [[8, 'edge'], [16, 'obstruct'], [24, 'obstruct'], [36, 'closed'], [48, 'obstruct'], [60, 'obstruct'], [62, 'obstruct'], [64, 'unblock'], [72, 'obstruct'], [80, 'unblock']]}, ['reopen', 'reopen', 'reopen', 'done', 'reopen', 'reopen', 'nudge', 'ignored']), ('control 37', {'events': [[2, 'closed'], [4, 'closed'], [9, 'obstruct'], [21, 'edge']]}, ['done', 'done', 'reopen', 'reopen']), ('control 40', {'events': [[2, 'closed'], [7, 'obstruct'], [15, 'edge'], [16, 'obstruct'], [18, 'closed']]}, ['done', 'reopen', 'reopen', 'reopen', 'done'])], [('regression: curtain held for twenty seconds', {'events': [[0, 'obstruct'], [20, 'obstruct']]}, ['reopen', 'nudge']), ('control 10', {'events': [[8, 'edge'], [13, 'obstruct'], [18, 'edge'], [30, 'unblock'], [35, 'obstruct'], [40, 'obstruct'], [42, 'unblock']]}, ['reopen', 'reopen', 'reopen', 'reopen', 'nudge']), ('sampled regression 3', {'events': [[1, 'obstruct'], [13, 'edge'], [21, 'obstruct'], [26, 'unblock'], [27, 'obstruct'], [32, 'edge'], [40, 'obstruct'], [48, 'obstruct'], [56, 'unblock'], [64, 'closed']]}, ['reopen', 'reopen', 'nudge', 'ignored', 'reopen', 'ignored', 'ignored', 'done']), ('control 64', {'events': [[8, 'obstruct'], [13, 'edge'], [18, 'unblock'], [26, 'unblock'], [34, 'obstruct'], [36, 'obstruct']]}, ['reopen', 'reopen', 'reopen', 'nudge']), ('boundary: safety edge while nudging', {'events': [[1, 'obstruct'], [2, 'obstruct'], [3, 'obstruct'], [4, 'edge'], [5, 'obstruct']]}, ['reopen', 'reopen', 'nudge', 'reopen', 'ignored']), ('control 45', {'events': [[5, 'edge'], [17, 'closed'], [22, 'obstruct'], [24, 'closed']]}, ['reopen', 'done', 'reopen', 'done']), ('control 48', {'events': [[2, 'obstruct'], [7, 'obstruct'], [15, 'obstruct'], [27, 'obstruct'], [35, 'unblock']]}, ['reopen', 'reopen', 'nudge', 'ignored']), ('control 51', {'events': [[8, 'closed'], [9, 'closed'], [14, 'obstruct'], [26, 'closed'], [38, 'obstruct']]}, ['done', 'done', 'reopen', 'done', 'reopen'])]]
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 curtain held blocked never triggers nudging, or brief separate obstructions add up to a long blockage.

During a door cycle each light-curtain obstruction reopens the doors and counts; the third obstruction, or an obstruction while the curtain has been blocked continuously for 20 s or more since the first unbroken obstruction, starts nudging (slow close, curtain ignored). While nudging, curtain obstructions are ignored. The mechanical safety edge always reopens and does not affect counting. unblock ends a continuous blockage. closed ends the cycle and resets everything.

split: open-access


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

N = 1
observations = []
def solve(x):
    active = False
    out = []
    for off in x['samples']:
        a = abs(off)
        if a > 200:
            out.append('fault')
            active = False
            continue
        if active:
            if a <= 10:
                active = False
                out.append('hold')
            else:
                out.append('relevel' if a <= 75 else 'close-relevel')
        elif a > 10:
            active = True
            out.append('relevel' if a <= 75 else 'close-relevel')
        else:
            out.append('hold')
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: hysteresis band', {'samples': [11, 8, 4, 3]}, ['relevel', 'relevel', 'relevel', 'hold']), ('sampled regression 3', {'samples': [76, -250, 201, -11, 10, 201, 4]}, ['close-relevel', 'fault', 'fault', 'relevel', 'relevel', 'fault', 'hold']), ('regression: negative offsets', {'samples': [-11, -4, -3]}, ['relevel', 'relevel', 'hold']), ('boundary: large offset while relevelling', {'samples': [20, 90, 30]}, ['relevel', 'close-relevel', 'relevel']), ('boundary: fault clears relevelling', {'samples': [20, 250, 5]}, ['relevel', 'fault', 'hold']), ('sampled regression 1', {'samples': [200, 40, 200, 9, 4]}, ['close-relevel', 'relevel', 'close-relevel', 'relevel', 'relevel']), ('sampled regression 4', {'samples': [150, 4, 200, 201, 4, -250, 9, 0]}, ['close-relevel', 'relevel', 'close-relevel', 'fault', 'hold', 'fault', 'hold', 'hold']), ('sampled regression 7', {'samples': [-250, 201, 4, 2, 4, 11, 76, 75, 10]}, ['fault', 'fault', 'hold', 'hold', 'hold', 'relevel', 'close-relevel', 'relevel', 'relevel'])], [('regression: negative offsets', {'samples': [-11, -4, -3]}, ['relevel', 'relevel', 'hold']), ('sampled regression 16', {'samples': [200, 75, -76, 10, 0, 40]}, ['close-relevel', 'relevel', 'close-relevel', 'relevel', 'hold', 'relevel']), ('control 19', {'samples': [75, 76, 3, -3, -3]}, ['relevel', 'close-relevel', 'hold', 'hold', 'hold']), ('boundary: fault clears relevelling', {'samples': [20, 250, 5]}, ['relevel', 'fault', 'hold']), ('boundary: exactly at the fault limit', {'samples': [200, 201]}, ['close-relevel', 'fault']), ('control 12', {'samples': [-4, 150, 11]}, ['hold', 'close-relevel', 'relevel']), ('control 15', {'samples': [-3, 2, 75, 201, 75, 200]}, ['hold', 'hold', 'relevel', 'fault', 'relevel', 'close-relevel']), ('sampled regression 18', {'samples': [-76, 10, 10, -250, 201, -4, 40]}, ['close-relevel', 'relevel', 'relevel', 'fault', 'fault', 'hold', 'relevel'])], [('regression: hysteresis band', {'samples': [11, 8, 4, 3]}, ['relevel', 'relevel', 'relevel', 'hold']), ('sampled regression 31', {'samples': [-3, -250, -76, 150, 10, 75, 75, -76, 75, 10]}, ['hold', 'fault', 'close-relevel', 'close-relevel', 'relevel', 'relevel', 'relevel', 'close-relevel', 'relevel', 'relevel']), ('sampled regression 45', {'samples': [150, 75, 4, 75, -11, 75, 40, -4, 3, 9]}, ['close-relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'hold', 'hold']), ('regression: negative offsets', {'samples': [-11, -4, -3]}, ['relevel', 'relevel', 'hold']), ('boundary: open door limit', {'samples': [75, 76]}, ['relevel', 'close-relevel']), ('sampled regression 23', {'samples': [3, 10, 200, 0, 3, -4, 0, 200, -4, 150]}, ['hold', 'hold', 'close-relevel', 'hold', 'hold', 'hold', 'hold', 'close-relevel', 'relevel', 'close-relevel']), ('control 26', {'samples': [76, 201, 3, 3]}, ['close-relevel', 'fault', 'hold', 'hold']), ('control 29', {'samples': [2, 4, 75, 0, 11, -3, -3, 4]}, ['hold', 'hold', 'relevel', 'hold', 'relevel', 'hold', 'hold', 'hold'])], [('regression: negative offsets', {'samples': [-11, -4, -3]}, ['relevel', 'relevel', 'hold']), ('sampled regression 46', {'samples': [-4, 150, -4, 200, 200, -3, 9]}, ['hold', 'close-relevel', 'relevel', 'close-relevel', 'close-relevel', 'hold', 'hold']), ('control 64', {'samples': [201, -3, 11, 200, 3, 0]}, ['fault', 'hold', 'relevel', 'close-relevel', 'hold', 'hold']), ('regression: hysteresis band', {'samples': [11, 8, 4, 3]}, ['relevel', 'relevel', 'relevel', 'hold']), ('boundary: large offset while relevelling', {'samples': [20, 90, 30]}, ['relevel', 'close-relevel', 'relevel']), ('sampled regression 34', {'samples': [150, 10, 200]}, ['close-relevel', 'relevel', 'close-relevel']), ('sampled regression 37', {'samples': [-76, 0, 76, 11, -11, 200, 150, 9]}, ['close-relevel', 'hold', 'close-relevel', 'relevel', 'relevel', 'close-relevel', 'close-relevel', 'relevel']), ('sampled regression 40', {'samples': [40, 76, -4]}, ['relevel', 'close-relevel', 'relevel'])], [('regression: hysteresis band', {'samples': [11, 8, 4, 3]}, ['relevel', 'relevel', 'relevel', 'hold']), ('sampled regression 58', {'samples': [75, 2, 10, 0, -11, 2, -11, 10]}, ['relevel', 'hold', 'hold', 'hold', 'relevel', 'hold', 'relevel', 'relevel']), ('control 78', {'samples': [3, 201, 2, 75, 3, 10, 2]}, ['hold', 'fault', 'hold', 'relevel', 'hold', 'hold', 'hold']), ('boundary: fault clears relevelling', {'samples': [20, 250, 5]}, ['relevel', 'fault', 'hold']), ('boundary: exactly at the fault limit', {'samples': [200, 201]}, ['close-relevel', 'fault']), ('sampled regression 45', {'samples': [150, 75, 4, 75, -11, 75, 40, -4, 3, 9]}, ['close-relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'hold', 'hold']), ('sampled regression 48', {'samples': [150, -76, 10, 4, -250, 40, 10]}, ['close-relevel', 'close-relevel', 'relevel', 'relevel', 'fault', 'relevel', 'relevel']), ('sampled regression 51', {'samples': [200, -4, -4, 76, 75, 76]}, ['close-relevel', 'relevel', 'relevel', 'close-relevel', 'relevel', 'close-relevel'])]]
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):
    active = False
    out = []
    for off in x['samples']:
        a = abs(off)
        if a > 200:
            out.append('fault')
            active = False
            continue
        if active:
            if a < 3:
                active = False
                out.append('hold')
            else:
                out.append('relevel' if a <= 75 else 'close-relevel')
        elif a > 10:
            active = True
            out.append('relevel' if a <= 75 else 'close-relevel')
        else:
            out.append('hold')
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: hysteresis band', {'samples': [11, 8, 4, 3]}, ['relevel', 'relevel', 'relevel', 'hold']), ('sampled regression 3', {'samples': [76, -250, 201, -11, 10, 201, 4]}, ['close-relevel', 'fault', 'fault', 'relevel', 'relevel', 'fault', 'hold']), ('regression: negative offsets', {'samples': [-11, -4, -3]}, ['relevel', 'relevel', 'hold']), ('boundary: large offset while relevelling', {'samples': [20, 90, 30]}, ['relevel', 'close-relevel', 'relevel']), ('boundary: fault clears relevelling', {'samples': [20, 250, 5]}, ['relevel', 'fault', 'hold']), ('sampled regression 1', {'samples': [200, 40, 200, 9, 4]}, ['close-relevel', 'relevel', 'close-relevel', 'relevel', 'relevel']), ('sampled regression 4', {'samples': [150, 4, 200, 201, 4, -250, 9, 0]}, ['close-relevel', 'relevel', 'close-relevel', 'fault', 'hold', 'fault', 'hold', 'hold']), ('sampled regression 7', {'samples': [-250, 201, 4, 2, 4, 11, 76, 75, 10]}, ['fault', 'fault', 'hold', 'hold', 'hold', 'relevel', 'close-relevel', 'relevel', 'relevel'])], [('regression: negative offsets', {'samples': [-11, -4, -3]}, ['relevel', 'relevel', 'hold']), ('sampled regression 16', {'samples': [200, 75, -76, 10, 0, 40]}, ['close-relevel', 'relevel', 'close-relevel', 'relevel', 'hold', 'relevel']), ('control 19', {'samples': [75, 76, 3, -3, -3]}, ['relevel', 'close-relevel', 'hold', 'hold', 'hold']), ('boundary: fault clears relevelling', {'samples': [20, 250, 5]}, ['relevel', 'fault', 'hold']), ('boundary: exactly at the fault limit', {'samples': [200, 201]}, ['close-relevel', 'fault']), ('control 12', {'samples': [-4, 150, 11]}, ['hold', 'close-relevel', 'relevel']), ('control 15', {'samples': [-3, 2, 75, 201, 75, 200]}, ['hold', 'hold', 'relevel', 'fault', 'relevel', 'close-relevel']), ('sampled regression 18', {'samples': [-76, 10, 10, -250, 201, -4, 40]}, ['close-relevel', 'relevel', 'relevel', 'fault', 'fault', 'hold', 'relevel'])], [('regression: hysteresis band', {'samples': [11, 8, 4, 3]}, ['relevel', 'relevel', 'relevel', 'hold']), ('sampled regression 31', {'samples': [-3, -250, -76, 150, 10, 75, 75, -76, 75, 10]}, ['hold', 'fault', 'close-relevel', 'close-relevel', 'relevel', 'relevel', 'relevel', 'close-relevel', 'relevel', 'relevel']), ('sampled regression 45', {'samples': [150, 75, 4, 75, -11, 75, 40, -4, 3, 9]}, ['close-relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'hold', 'hold']), ('regression: negative offsets', {'samples': [-11, -4, -3]}, ['relevel', 'relevel', 'hold']), ('boundary: open door limit', {'samples': [75, 76]}, ['relevel', 'close-relevel']), ('sampled regression 23', {'samples': [3, 10, 200, 0, 3, -4, 0, 200, -4, 150]}, ['hold', 'hold', 'close-relevel', 'hold', 'hold', 'hold', 'hold', 'close-relevel', 'relevel', 'close-relevel']), ('control 26', {'samples': [76, 201, 3, 3]}, ['close-relevel', 'fault', 'hold', 'hold']), ('control 29', {'samples': [2, 4, 75, 0, 11, -3, -3, 4]}, ['hold', 'hold', 'relevel', 'hold', 'relevel', 'hold', 'hold', 'hold'])], [('regression: negative offsets', {'samples': [-11, -4, -3]}, ['relevel', 'relevel', 'hold']), ('sampled regression 46', {'samples': [-4, 150, -4, 200, 200, -3, 9]}, ['hold', 'close-relevel', 'relevel', 'close-relevel', 'close-relevel', 'hold', 'hold']), ('control 64', {'samples': [201, -3, 11, 200, 3, 0]}, ['fault', 'hold', 'relevel', 'close-relevel', 'hold', 'hold']), ('regression: hysteresis band', {'samples': [11, 8, 4, 3]}, ['relevel', 'relevel', 'relevel', 'hold']), ('boundary: large offset while relevelling', {'samples': [20, 90, 30]}, ['relevel', 'close-relevel', 'relevel']), ('sampled regression 34', {'samples': [150, 10, 200]}, ['close-relevel', 'relevel', 'close-relevel']), ('sampled regression 37', {'samples': [-76, 0, 76, 11, -11, 200, 150, 9]}, ['close-relevel', 'hold', 'close-relevel', 'relevel', 'relevel', 'close-relevel', 'close-relevel', 'relevel']), ('sampled regression 40', {'samples': [40, 76, -4]}, ['relevel', 'close-relevel', 'relevel'])], [('regression: hysteresis band', {'samples': [11, 8, 4, 3]}, ['relevel', 'relevel', 'relevel', 'hold']), ('sampled regression 58', {'samples': [75, 2, 10, 0, -11, 2, -11, 10]}, ['relevel', 'hold', 'hold', 'hold', 'relevel', 'hold', 'relevel', 'relevel']), ('control 78', {'samples': [3, 201, 2, 75, 3, 10, 2]}, ['hold', 'fault', 'hold', 'relevel', 'hold', 'hold', 'hold']), ('boundary: fault clears relevelling', {'samples': [20, 250, 5]}, ['relevel', 'fault', 'hold']), ('boundary: exactly at the fault limit', {'samples': [200, 201]}, ['close-relevel', 'fault']), ('sampled regression 45', {'samples': [150, 75, 4, 75, -11, 75, 40, -4, 3, 9]}, ['close-relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'hold', 'hold']), ('sampled regression 48', {'samples': [150, -76, 10, 4, -250, 40, 10]}, ['close-relevel', 'close-relevel', 'relevel', 'relevel', 'fault', 'relevel', 'relevel']), ('sampled regression 51', {'samples': [200, -4, -4, 76, 75, 76]}, ['close-relevel', 'relevel', 'relevel', 'close-relevel', 'relevel', 'close-relevel'])]]
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:
Relevelling stops as soon as the offset is back inside the start band.

While standing at a floor the level offset (mm) is sampled. Beyond +-200 mm the sample is a fault and any relevel stops. Relevelling starts when |offset| > 10 and continues until |offset| <= 3 (hysteresis). A relevel runs with doors open when |offset| <= 75, otherwise the doors close first (close-relevel). Output hold, relevel, close-relevel or fault per sample.

split: open-access


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

N = 1
observations = []
def solve(x):
    active = False
    out = []
    for off in x['samples']:
        a = abs(off)
        if a > 200:
            out.append('fault')
            active = False
            continue
        if active:
            if a <= 3:
                active = False
                out.append('hold')
            else:
                out.append('relevel' if a <= 200 else 'close-relevel')
        elif a > 10:
            active = True
            out.append('relevel' if a <= 75 else 'close-relevel')
        else:
            out.append('hold')
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: large offset while relevelling', {'samples': [20, 90, 30]}, ['relevel', 'close-relevel', 'relevel']), ('sampled regression 4', {'samples': [150, 4, 200, 201, 4, -250, 9, 0]}, ['close-relevel', 'relevel', 'close-relevel', 'fault', 'hold', 'fault', 'hold', 'hold']), ('regression: open door limit', {'samples': [75, 76]}, ['relevel', 'close-relevel']), ('boundary: hysteresis band', {'samples': [11, 8, 4, 3]}, ['relevel', 'relevel', 'relevel', 'hold']), ('boundary: fault clears relevelling', {'samples': [20, 250, 5]}, ['relevel', 'fault', 'hold']), ('sampled regression 1', {'samples': [200, 40, 200, 9, 4]}, ['close-relevel', 'relevel', 'close-relevel', 'relevel', 'relevel']), ('sampled regression 7', {'samples': [-250, 201, 4, 2, 4, 11, 76, 75, 10]}, ['fault', 'fault', 'hold', 'hold', 'hold', 'relevel', 'close-relevel', 'relevel', 'relevel']), ('sampled regression 10', {'samples': [10, 9, -11, 150, 3, 201]}, ['hold', 'hold', 'relevel', 'close-relevel', 'hold', 'fault'])], [('regression: open door limit', {'samples': [75, 76]}, ['relevel', 'close-relevel']), ('sampled regression 15', {'samples': [-3, 2, 75, 201, 75, 200]}, ['hold', 'hold', 'relevel', 'fault', 'relevel', 'close-relevel']), ('sampled regression 7', {'samples': [-250, 201, 4, 2, 4, 11, 76, 75, 10]}, ['fault', 'fault', 'hold', 'hold', 'hold', 'relevel', 'close-relevel', 'relevel', 'relevel']), ('boundary: fault clears relevelling', {'samples': [20, 250, 5]}, ['relevel', 'fault', 'hold']), ('boundary: exactly at the fault limit', {'samples': [200, 201]}, ['close-relevel', 'fault']), ('control 12', {'samples': [-4, 150, 11]}, ['hold', 'close-relevel', 'relevel']), ('control 18', {'samples': [-76, 10, 10, -250, 201, -4, 40]}, ['close-relevel', 'relevel', 'relevel', 'fault', 'fault', 'hold', 'relevel']), ('control 21', {'samples': [75, 40, 201, 9, 11, 4]}, ['relevel', 'relevel', 'fault', 'hold', 'relevel', 'relevel'])], [('regression: large offset while relevelling', {'samples': [20, 90, 30]}, ['relevel', 'close-relevel', 'relevel']), ('sampled regression 27', {'samples': [3, 11, 11, 4, 201, 150, 150, -4, 10]}, ['hold', 'relevel', 'relevel', 'relevel', 'fault', 'close-relevel', 'close-relevel', 'relevel', 'relevel']), ('sampled regression 16', {'samples': [200, 75, -76, 10, 0, 40]}, ['close-relevel', 'relevel', 'close-relevel', 'relevel', 'hold', 'relevel']), ('boundary: negative offsets', {'samples': [-11, -4, -3]}, ['relevel', 'relevel', 'hold']), ('regression: open door limit', {'samples': [75, 76]}, ['relevel', 'close-relevel']), ('sampled regression 23', {'samples': [3, 10, 200, 0, 3, -4, 0, 200, -4, 150]}, ['hold', 'hold', 'close-relevel', 'hold', 'hold', 'hold', 'hold', 'close-relevel', 'relevel', 'close-relevel']), ('control 26', {'samples': [76, 201, 3, 3]}, ['close-relevel', 'fault', 'hold', 'hold']), ('control 29', {'samples': [2, 4, 75, 0, 11, -3, -3, 4]}, ['hold', 'hold', 'relevel', 'hold', 'relevel', 'hold', 'hold', 'hold'])], [('regression: open door limit', {'samples': [75, 76]}, ['relevel', 'close-relevel']), ('sampled regression 42', {'samples': [-3, -76, -76, 11, 2, 150, 75, 76]}, ['hold', 'close-relevel', 'close-relevel', 'relevel', 'hold', 'close-relevel', 'relevel', 'close-relevel']), ('sampled regression 25', {'samples': [200, 150, 2, 11, -250, 75, 0, 11]}, ['close-relevel', 'close-relevel', 'hold', 'relevel', 'fault', 'relevel', 'hold', 'relevel']), ('boundary: hysteresis band', {'samples': [11, 8, 4, 3]}, ['relevel', 'relevel', 'relevel', 'hold']), ('regression: large offset while relevelling', {'samples': [20, 90, 30]}, ['relevel', 'close-relevel', 'relevel']), ('sampled regression 34', {'samples': [150, 10, 200]}, ['close-relevel', 'relevel', 'close-relevel']), ('sampled regression 37', {'samples': [-76, 0, 76, 11, -11, 200, 150, 9]}, ['close-relevel', 'hold', 'close-relevel', 'relevel', 'relevel', 'close-relevel', 'close-relevel', 'relevel']), ('sampled regression 40', {'samples': [40, 76, -4]}, ['relevel', 'close-relevel', 'relevel'])], [('regression: large offset while relevelling', {'samples': [20, 90, 30]}, ['relevel', 'close-relevel', 'relevel']), ('sampled regression 60', {'samples': [-250, 200, 40, -4, 150, 3, 3, 3]}, ['fault', 'close-relevel', 'relevel', 'relevel', 'close-relevel', 'hold', 'hold', 'hold']), ('sampled regression 36', {'samples': [11, 150, 11, 3]}, ['relevel', 'close-relevel', 'relevel', 'hold']), ('boundary: fault clears relevelling', {'samples': [20, 250, 5]}, ['relevel', 'fault', 'hold']), ('boundary: exactly at the fault limit', {'samples': [200, 201]}, ['close-relevel', 'fault']), ('control 45', {'samples': [150, 75, 4, 75, -11, 75, 40, -4, 3, 9]}, ['close-relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'hold', 'hold']), ('sampled regression 48', {'samples': [150, -76, 10, 4, -250, 40, 10]}, ['close-relevel', 'close-relevel', 'relevel', 'relevel', 'fault', 'relevel', 'relevel']), ('sampled regression 51', {'samples': [200, -4, -4, 76, 75, 76]}, ['close-relevel', 'relevel', 'relevel', 'close-relevel', 'relevel', 'close-relevel'])]]
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):
    active = False
    out = []
    for off in x['samples']:
        a = abs(off)
        if a > 200:
            out.append('fault')
            active = False
            continue
        if active:
            if a <= 3:
                active = False
                out.append('hold')
            else:
                out.append('relevel')
        elif a > 10:
            active = True
            out.append('relevel' if a <= 75 else 'close-relevel')
        else:
            out.append('hold')
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: large offset while relevelling', {'samples': [20, 90, 30]}, ['relevel', 'close-relevel', 'relevel']), ('sampled regression 4', {'samples': [150, 4, 200, 201, 4, -250, 9, 0]}, ['close-relevel', 'relevel', 'close-relevel', 'fault', 'hold', 'fault', 'hold', 'hold']), ('regression: open door limit', {'samples': [75, 76]}, ['relevel', 'close-relevel']), ('boundary: hysteresis band', {'samples': [11, 8, 4, 3]}, ['relevel', 'relevel', 'relevel', 'hold']), ('boundary: fault clears relevelling', {'samples': [20, 250, 5]}, ['relevel', 'fault', 'hold']), ('sampled regression 1', {'samples': [200, 40, 200, 9, 4]}, ['close-relevel', 'relevel', 'close-relevel', 'relevel', 'relevel']), ('sampled regression 7', {'samples': [-250, 201, 4, 2, 4, 11, 76, 75, 10]}, ['fault', 'fault', 'hold', 'hold', 'hold', 'relevel', 'close-relevel', 'relevel', 'relevel']), ('sampled regression 10', {'samples': [10, 9, -11, 150, 3, 201]}, ['hold', 'hold', 'relevel', 'close-relevel', 'hold', 'fault'])], [('regression: open door limit', {'samples': [75, 76]}, ['relevel', 'close-relevel']), ('sampled regression 15', {'samples': [-3, 2, 75, 201, 75, 200]}, ['hold', 'hold', 'relevel', 'fault', 'relevel', 'close-relevel']), ('sampled regression 7', {'samples': [-250, 201, 4, 2, 4, 11, 76, 75, 10]}, ['fault', 'fault', 'hold', 'hold', 'hold', 'relevel', 'close-relevel', 'relevel', 'relevel']), ('boundary: fault clears relevelling', {'samples': [20, 250, 5]}, ['relevel', 'fault', 'hold']), ('boundary: exactly at the fault limit', {'samples': [200, 201]}, ['close-relevel', 'fault']), ('control 12', {'samples': [-4, 150, 11]}, ['hold', 'close-relevel', 'relevel']), ('control 18', {'samples': [-76, 10, 10, -250, 201, -4, 40]}, ['close-relevel', 'relevel', 'relevel', 'fault', 'fault', 'hold', 'relevel']), ('control 21', {'samples': [75, 40, 201, 9, 11, 4]}, ['relevel', 'relevel', 'fault', 'hold', 'relevel', 'relevel'])], [('regression: large offset while relevelling', {'samples': [20, 90, 30]}, ['relevel', 'close-relevel', 'relevel']), ('sampled regression 27', {'samples': [3, 11, 11, 4, 201, 150, 150, -4, 10]}, ['hold', 'relevel', 'relevel', 'relevel', 'fault', 'close-relevel', 'close-relevel', 'relevel', 'relevel']), ('sampled regression 16', {'samples': [200, 75, -76, 10, 0, 40]}, ['close-relevel', 'relevel', 'close-relevel', 'relevel', 'hold', 'relevel']), ('boundary: negative offsets', {'samples': [-11, -4, -3]}, ['relevel', 'relevel', 'hold']), ('regression: open door limit', {'samples': [75, 76]}, ['relevel', 'close-relevel']), ('sampled regression 23', {'samples': [3, 10, 200, 0, 3, -4, 0, 200, -4, 150]}, ['hold', 'hold', 'close-relevel', 'hold', 'hold', 'hold', 'hold', 'close-relevel', 'relevel', 'close-relevel']), ('control 26', {'samples': [76, 201, 3, 3]}, ['close-relevel', 'fault', 'hold', 'hold']), ('control 29', {'samples': [2, 4, 75, 0, 11, -3, -3, 4]}, ['hold', 'hold', 'relevel', 'hold', 'relevel', 'hold', 'hold', 'hold'])], [('regression: open door limit', {'samples': [75, 76]}, ['relevel', 'close-relevel']), ('sampled regression 42', {'samples': [-3, -76, -76, 11, 2, 150, 75, 76]}, ['hold', 'close-relevel', 'close-relevel', 'relevel', 'hold', 'close-relevel', 'relevel', 'close-relevel']), ('sampled regression 25', {'samples': [200, 150, 2, 11, -250, 75, 0, 11]}, ['close-relevel', 'close-relevel', 'hold', 'relevel', 'fault', 'relevel', 'hold', 'relevel']), ('boundary: hysteresis band', {'samples': [11, 8, 4, 3]}, ['relevel', 'relevel', 'relevel', 'hold']), ('regression: large offset while relevelling', {'samples': [20, 90, 30]}, ['relevel', 'close-relevel', 'relevel']), ('sampled regression 34', {'samples': [150, 10, 200]}, ['close-relevel', 'relevel', 'close-relevel']), ('sampled regression 37', {'samples': [-76, 0, 76, 11, -11, 200, 150, 9]}, ['close-relevel', 'hold', 'close-relevel', 'relevel', 'relevel', 'close-relevel', 'close-relevel', 'relevel']), ('sampled regression 40', {'samples': [40, 76, -4]}, ['relevel', 'close-relevel', 'relevel'])], [('regression: large offset while relevelling', {'samples': [20, 90, 30]}, ['relevel', 'close-relevel', 'relevel']), ('sampled regression 60', {'samples': [-250, 200, 40, -4, 150, 3, 3, 3]}, ['fault', 'close-relevel', 'relevel', 'relevel', 'close-relevel', 'hold', 'hold', 'hold']), ('sampled regression 36', {'samples': [11, 150, 11, 3]}, ['relevel', 'close-relevel', 'relevel', 'hold']), ('boundary: fault clears relevelling', {'samples': [20, 250, 5]}, ['relevel', 'fault', 'hold']), ('boundary: exactly at the fault limit', {'samples': [200, 201]}, ['close-relevel', 'fault']), ('control 45', {'samples': [150, 75, 4, 75, -11, 75, 40, -4, 3, 9]}, ['close-relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'hold', 'hold']), ('sampled regression 48', {'samples': [150, -76, 10, 4, -250, 40, 10]}, ['close-relevel', 'close-relevel', 'relevel', 'relevel', 'fault', 'relevel', 'relevel']), ('sampled regression 51', {'samples': [200, -4, -4, 76, 75, 76]}, ['close-relevel', 'relevel', 'relevel', 'close-relevel', 'relevel', 'close-relevel'])]]
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 car keeps relevelling with doors open after the offset grows large.

While standing at a floor the level offset (mm) is sampled. Beyond +-200 mm the sample is a fault and any relevel stops. Relevelling starts when |offset| > 10 and continues until |offset| <= 3 (hysteresis). A relevel runs with doors open when |offset| <= 75, otherwise the doors close first (close-relevel). Output hold, relevel, close-relevel or fault per sample.

split: open-access


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

N = 1
observations = []
def solve(x):
    active = False
    out = []
    for off in x['samples']:
        a = abs(off)
        if a > 200:
            out.append('fault')
            continue
        if active:
            if a <= 3:
                active = False
                out.append('hold')
            else:
                out.append('relevel' if a <= 75 else 'close-relevel')
        elif a > 10:
            active = True
            out.append('relevel' if a <= 75 else 'close-relevel')
        else:
            out.append('hold')
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: fault clears relevelling', {'samples': [20, 250, 5]}, ['relevel', 'fault', 'hold']), ('sampled regression 14', {'samples': [-11, 9, -11, 2, -76, 200, -4, -250, 201, -4]}, ['relevel', 'relevel', 'relevel', 'hold', 'close-relevel', 'close-relevel', 'relevel', 'fault', 'fault', 'hold']), ('sampled regression 3', {'samples': [76, -250, 201, -11, 10, 201, 4]}, ['close-relevel', 'fault', 'fault', 'relevel', 'relevel', 'fault', 'hold']), ('boundary: hysteresis band', {'samples': [11, 8, 4, 3]}, ['relevel', 'relevel', 'relevel', 'hold']), ('boundary: large offset while relevelling', {'samples': [20, 90, 30]}, ['relevel', 'close-relevel', 'relevel']), ('control 1', {'samples': [200, 40, 200, 9, 4]}, ['close-relevel', 'relevel', 'close-relevel', 'relevel', 'relevel']), ('sampled regression 4', {'samples': [150, 4, 200, 201, 4, -250, 9, 0]}, ['close-relevel', 'relevel', 'close-relevel', 'fault', 'hold', 'fault', 'hold', 'hold']), ('control 7', {'samples': [-250, 201, 4, 2, 4, 11, 76, 75, 10]}, ['fault', 'fault', 'hold', 'hold', 'hold', 'relevel', 'close-relevel', 'relevel', 'relevel'])], [('regression: fault clears relevelling', {'samples': [20, 250, 5]}, ['relevel', 'fault', 'hold']), ('sampled regression 75', {'samples': [11, 9, -250, 10, 10, 0, -11]}, ['relevel', 'relevel', 'fault', 'hold', 'hold', 'hold', 'relevel']), ('sampled regression 21', {'samples': [75, 40, 201, 9, 11, 4]}, ['relevel', 'relevel', 'fault', 'hold', 'relevel', 'relevel']), ('boundary: exactly at the fault limit', {'samples': [200, 201]}, ['close-relevel', 'fault']), ('boundary: negative offsets', {'samples': [-11, -4, -3]}, ['relevel', 'relevel', 'hold']), ('control 12', {'samples': [-4, 150, 11]}, ['hold', 'close-relevel', 'relevel']), ('control 15', {'samples': [-3, 2, 75, 201, 75, 200]}, ['hold', 'hold', 'relevel', 'fault', 'relevel', 'close-relevel']), ('sampled regression 18', {'samples': [-76, 10, 10, -250, 201, -4, 40]}, ['close-relevel', 'relevel', 'relevel', 'fault', 'fault', 'hold', 'relevel'])], [('regression: fault clears relevelling', {'samples': [20, 250, 5]}, ['relevel', 'fault', 'hold']), ('sampled regression 21', {'samples': [75, 40, 201, 9, 11, 4]}, ['relevel', 'relevel', 'fault', 'hold', 'relevel', 'relevel']), ('sampled regression 55', {'samples': [75, 10, -250, 10, -76, -4, 4, 4]}, ['relevel', 'relevel', 'fault', 'hold', 'close-relevel', 'relevel', 'relevel', 'relevel']), ('boundary: negative offsets', {'samples': [-11, -4, -3]}, ['relevel', 'relevel', 'hold']), ('boundary: open door limit', {'samples': [75, 76]}, ['relevel', 'close-relevel']), ('control 23', {'samples': [3, 10, 200, 0, 3, -4, 0, 200, -4, 150]}, ['hold', 'hold', 'close-relevel', 'hold', 'hold', 'hold', 'hold', 'close-relevel', 'relevel', 'close-relevel']), ('control 26', {'samples': [76, 201, 3, 3]}, ['close-relevel', 'fault', 'hold', 'hold']), ('control 29', {'samples': [2, 4, 75, 0, 11, -3, -3, 4]}, ['hold', 'hold', 'relevel', 'hold', 'relevel', 'hold', 'hold', 'hold'])], [('regression: fault clears relevelling', {'samples': [20, 250, 5]}, ['relevel', 'fault', 'hold']), ('sampled regression 3', {'samples': [76, -250, 201, -11, 10, 201, 4]}, ['close-relevel', 'fault', 'fault', 'relevel', 'relevel', 'fault', 'hold']), ('boundary: hysteresis band', {'samples': [11, 8, 4, 3]}, ['relevel', 'relevel', 'relevel', 'hold']), ('boundary: large offset while relevelling', {'samples': [20, 90, 30]}, ['relevel', 'close-relevel', 'relevel']), ('boundary: exactly at the fault limit', {'samples': [200, 201]}, ['close-relevel', 'fault']), ('control 34', {'samples': [150, 10, 200]}, ['close-relevel', 'relevel', 'close-relevel']), ('control 37', {'samples': [-76, 0, 76, 11, -11, 200, 150, 9]}, ['close-relevel', 'hold', 'close-relevel', 'relevel', 'relevel', 'close-relevel', 'close-relevel', 'relevel']), ('control 40', {'samples': [40, 76, -4]}, ['relevel', 'close-relevel', 'relevel'])], [('regression: fault clears relevelling', {'samples': [20, 250, 5]}, ['relevel', 'fault', 'hold']), ('sampled regression 33', {'samples': [4, -11, -11, 40, 11, 201, 9, -4]}, ['hold', 'relevel', 'relevel', 'relevel', 'relevel', 'fault', 'hold', 'hold']), ('sampled regression 21', {'samples': [75, 40, 201, 9, 11, 4]}, ['relevel', 'relevel', 'fault', 'hold', 'relevel', 'relevel']), ('boundary: exactly at the fault limit', {'samples': [200, 201]}, ['close-relevel', 'fault']), ('boundary: negative offsets', {'samples': [-11, -4, -3]}, ['relevel', 'relevel', 'hold']), ('control 45', {'samples': [150, 75, 4, 75, -11, 75, 40, -4, 3, 9]}, ['close-relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'hold', 'hold']), ('control 48', {'samples': [150, -76, 10, 4, -250, 40, 10]}, ['close-relevel', 'close-relevel', 'relevel', 'relevel', 'fault', 'relevel', 'relevel']), ('control 51', {'samples': [200, -4, -4, 76, 75, 76]}, ['close-relevel', 'relevel', 'relevel', 'close-relevel', 'relevel', 'close-relevel'])]]
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):
    active = False
    out = []
    for off in x['samples']:
        a = abs(off)
        if a > 200:
            out.append('fault')
            active = a > 10
            continue
        if active:
            if a <= 3:
                active = False
                out.append('hold')
            else:
                out.append('relevel' if a <= 75 else 'close-relevel')
        elif a > 10:
            active = True
            out.append('relevel' if a <= 75 else 'close-relevel')
        else:
            out.append('hold')
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: fault clears relevelling', {'samples': [20, 250, 5]}, ['relevel', 'fault', 'hold']), ('sampled regression 14', {'samples': [-11, 9, -11, 2, -76, 200, -4, -250, 201, -4]}, ['relevel', 'relevel', 'relevel', 'hold', 'close-relevel', 'close-relevel', 'relevel', 'fault', 'fault', 'hold']), ('sampled regression 3', {'samples': [76, -250, 201, -11, 10, 201, 4]}, ['close-relevel', 'fault', 'fault', 'relevel', 'relevel', 'fault', 'hold']), ('boundary: hysteresis band', {'samples': [11, 8, 4, 3]}, ['relevel', 'relevel', 'relevel', 'hold']), ('boundary: large offset while relevelling', {'samples': [20, 90, 30]}, ['relevel', 'close-relevel', 'relevel']), ('control 1', {'samples': [200, 40, 200, 9, 4]}, ['close-relevel', 'relevel', 'close-relevel', 'relevel', 'relevel']), ('sampled regression 4', {'samples': [150, 4, 200, 201, 4, -250, 9, 0]}, ['close-relevel', 'relevel', 'close-relevel', 'fault', 'hold', 'fault', 'hold', 'hold']), ('control 7', {'samples': [-250, 201, 4, 2, 4, 11, 76, 75, 10]}, ['fault', 'fault', 'hold', 'hold', 'hold', 'relevel', 'close-relevel', 'relevel', 'relevel'])], [('regression: fault clears relevelling', {'samples': [20, 250, 5]}, ['relevel', 'fault', 'hold']), ('sampled regression 75', {'samples': [11, 9, -250, 10, 10, 0, -11]}, ['relevel', 'relevel', 'fault', 'hold', 'hold', 'hold', 'relevel']), ('sampled regression 21', {'samples': [75, 40, 201, 9, 11, 4]}, ['relevel', 'relevel', 'fault', 'hold', 'relevel', 'relevel']), ('boundary: exactly at the fault limit', {'samples': [200, 201]}, ['close-relevel', 'fault']), ('boundary: negative offsets', {'samples': [-11, -4, -3]}, ['relevel', 'relevel', 'hold']), ('control 12', {'samples': [-4, 150, 11]}, ['hold', 'close-relevel', 'relevel']), ('control 15', {'samples': [-3, 2, 75, 201, 75, 200]}, ['hold', 'hold', 'relevel', 'fault', 'relevel', 'close-relevel']), ('sampled regression 18', {'samples': [-76, 10, 10, -250, 201, -4, 40]}, ['close-relevel', 'relevel', 'relevel', 'fault', 'fault', 'hold', 'relevel'])], [('regression: fault clears relevelling', {'samples': [20, 250, 5]}, ['relevel', 'fault', 'hold']), ('sampled regression 21', {'samples': [75, 40, 201, 9, 11, 4]}, ['relevel', 'relevel', 'fault', 'hold', 'relevel', 'relevel']), ('sampled regression 55', {'samples': [75, 10, -250, 10, -76, -4, 4, 4]}, ['relevel', 'relevel', 'fault', 'hold', 'close-relevel', 'relevel', 'relevel', 'relevel']), ('boundary: negative offsets', {'samples': [-11, -4, -3]}, ['relevel', 'relevel', 'hold']), ('boundary: open door limit', {'samples': [75, 76]}, ['relevel', 'close-relevel']), ('control 23', {'samples': [3, 10, 200, 0, 3, -4, 0, 200, -4, 150]}, ['hold', 'hold', 'close-relevel', 'hold', 'hold', 'hold', 'hold', 'close-relevel', 'relevel', 'close-relevel']), ('control 26', {'samples': [76, 201, 3, 3]}, ['close-relevel', 'fault', 'hold', 'hold']), ('control 29', {'samples': [2, 4, 75, 0, 11, -3, -3, 4]}, ['hold', 'hold', 'relevel', 'hold', 'relevel', 'hold', 'hold', 'hold'])], [('regression: fault clears relevelling', {'samples': [20, 250, 5]}, ['relevel', 'fault', 'hold']), ('sampled regression 3', {'samples': [76, -250, 201, -11, 10, 201, 4]}, ['close-relevel', 'fault', 'fault', 'relevel', 'relevel', 'fault', 'hold']), ('boundary: hysteresis band', {'samples': [11, 8, 4, 3]}, ['relevel', 'relevel', 'relevel', 'hold']), ('boundary: large offset while relevelling', {'samples': [20, 90, 30]}, ['relevel', 'close-relevel', 'relevel']), ('boundary: exactly at the fault limit', {'samples': [200, 201]}, ['close-relevel', 'fault']), ('control 34', {'samples': [150, 10, 200]}, ['close-relevel', 'relevel', 'close-relevel']), ('control 37', {'samples': [-76, 0, 76, 11, -11, 200, 150, 9]}, ['close-relevel', 'hold', 'close-relevel', 'relevel', 'relevel', 'close-relevel', 'close-relevel', 'relevel']), ('control 40', {'samples': [40, 76, -4]}, ['relevel', 'close-relevel', 'relevel'])], [('regression: fault clears relevelling', {'samples': [20, 250, 5]}, ['relevel', 'fault', 'hold']), ('sampled regression 33', {'samples': [4, -11, -11, 40, 11, 201, 9, -4]}, ['hold', 'relevel', 'relevel', 'relevel', 'relevel', 'fault', 'hold', 'hold']), ('sampled regression 21', {'samples': [75, 40, 201, 9, 11, 4]}, ['relevel', 'relevel', 'fault', 'hold', 'relevel', 'relevel']), ('boundary: exactly at the fault limit', {'samples': [200, 201]}, ['close-relevel', 'fault']), ('boundary: negative offsets', {'samples': [-11, -4, -3]}, ['relevel', 'relevel', 'hold']), ('control 45', {'samples': [150, 75, 4, 75, -11, 75, 40, -4, 3, 9]}, ['close-relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'relevel', 'hold', 'hold']), ('control 48', {'samples': [150, -76, 10, 4, -250, 40, 10]}, ['close-relevel', 'close-relevel', 'relevel', 'relevel', 'fault', 'relevel', 'relevel']), ('control 51', {'samples': [200, -4, -4, 76, 75, 76]}, ['close-relevel', 'relevel', 'relevel', 'close-relevel', 'relevel', 'close-relevel'])]]
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 relevel continues after a fault sample.

While standing at a floor the level offset (mm) is sampled. Beyond +-200 mm the sample is a fault and any relevel stops. Relevelling starts when |offset| > 10 and continues until |offset| <= 3 (hysteresis). A relevel runs with doors open when |offset| <= 75, otherwise the doors close first (close-relevel). Output hold, relevel, close-relevel or fault per sample.

split: open-access