FA-97296 / Recipe scaling and nutrition / Open access
Backward recipe step scheduler: step duration offset · case 01
Every step is shown starting at the moment it must finish.
ROOT CAUSE
The step duration is not subtracted from its deadline.
VERIFIED REPAIR
Start = deadline - duration.
Unsuccessful approach: Adding one minute of slack makes every step late.
Case contract
Steps [name, minutes, depends_on]; a step must finish before any step depending on it starts. Latest start = min(latest start of dependents, serve time) - minutes. Unknown dependency -> "error: unknown step X"; a cycle -> "error: cycle". Serve "HH:MM"; starts print as "HH:MM" modulo 24h (previous day wraps). Output [[name, time]] sorted by absolute start then name.
Why this case matters
Dinner-party and restaurant prep planners schedule long marinades and roasts backward from service.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(steps, serve):
by = {s[0]: s for s in steps}
for s in steps:
for d in s[2]:
if d not in by:
return 'error: unknown step ' + d
h, m = serve.split(':')
T = int(h) * 60 + int(m)
latest = {}
visiting = set()
def ls(n):
if n in latest:
return latest[n]
if n in visiting:
return None
visiting.add(n)
finish = T
for s in steps:
if n in s[2]:
v = ls(s[0])
if v is None:
return None
finish = min(finish, v)
visiting.discard(n)
latest[n] = finish
return latest[n]
rows = []
for s in steps:
v = ls(s[0])
if v is None:
return 'error: cycle'
rows.append((v, s[0]))
rows.sort()
return [[n, '%02d:%02d' % divmod(v % 1440, 60)] for v, n in rows]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['chain', [[['prep', 10, []], ['roast', 90, ['prep']], ['rest', 15, ['roast']]], '18:30'],
[['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']]],
['overnight marinade', [[['marinate', 480, []], ['grill', 20, ['marinate']]], '12:00'],
[['marinate', '03:40'], ['grill', '11:40']]],
['cycle', [[['a', 5, ['b']], ['b', 5, ['a']]], '18:00'], 'error: cycle'],
['regression: step duration offset',
[[['roast', 240, ['marinate']], ['sauce', 240, ['prep']], ['marinate', 30, []], ['prep', 10, []]],
'19:45'],
[['marinate', '15:15'], ['prep', '15:35'], ['roast', '15:45'], ['sauce', '15:45']]],
['repair check: step duration offset',
[[['sauce', 15, ['prep']], ['prep', 45, []], ['rest', 240, []], ['roast', 15, ['prep']],
['marinate', 45, ['prep']]],
'00:30'],
[['rest', '20:30'], ['prep', '23:00'], ['marinate', '23:45'], ['roast', '00:15'], ['sauce', '00:15']]],
['generated control 1',
[[['sauce', 45, ['shop']], ['roast', 45, ['prep', 'marinate']], ['marinate', 90, []], ['prep', 15, []],
['rest', 10, ['sauce']]],
'00:30'],
'error: unknown step shop'],
['generated control 2',
[[['sauce', 30, ['prep', 'marinate', 'shop']], ['rest', 45, ['roast']], ['marinate', 5, []],
['prep', 5, []], ['roast', 5, ['prep']]],
'19:45'],
'error: unknown step shop'],
['generated control 3',
[[['roast', 10, ['prep', 'marinate']], ['marinate', 15, []], ['prep', 45, ['roast']]], '12:00'],
'error: cycle']],
[['overnight marinade', [[['marinate', 480, []], ['grill', 20, ['marinate']]], '12:00'],
[['marinate', '03:40'], ['grill', '11:40']]],
['cycle', [[['a', 5, ['b']], ['b', 5, ['a']]], '18:00'], 'error: cycle'],
['unknown dependency', [[['a', 5, ['shop']]], '18:00'], 'error: unknown step shop'],
['regression: step duration offset',
[[['marinate', 240, []], ['plate', 5, ['prep', 'roast', 'rest']], ['sauce', 5, ['prep']],
['roast', 30, ['prep', 'marinate']], ['prep', 45, []], ['rest', 30, ['roast', 'sauce']]],
'01:15'],
[['marinate', '20:10'], ['prep', '23:25'], ['roast', '00:10'], ['sauce', '00:35'], ['rest', '00:40'],
['plate', '01:10']]],
['repair check: step duration offset',
[[['prep', 15, []], ['plate', 10, ['rest']], ['rest', 10, ['marinate']], ['marinate', 240, ['prep']],
['sauce', 45, ['roast']], ['roast', 15, ['marinate']]],
'18:30'],
[['prep', '13:15'], ['marinate', '13:30'], ['roast', '17:30'], ['sauce', '17:45'], ['rest', '18:10'],
['plate', '18:20']]],
['generated control 1',
[[['marinate', 10, []], ['plate', 45, ['prep', 'sauce']], ['rest', 90, ['prep', 'marinate', 'sauce']],
['sauce', 45, ['marinate']], ['prep', 90, []], ['roast', 15, ['prep']]],
'19:45'],
[['prep', '16:45'], ['marinate', '17:20'], ['sauce', '17:30'], ['rest', '18:15'], ['plate', '19:00'],
['roast', '19:30']]],
['generated control 2',
[[['prep', 90, []], ['sauce', 10, ['prep', 'marinate']], ['roast', 30, ['prep']],
['marinate', 15, ['prep']]],
'12:00'],
[['prep', '10:00'], ['roast', '11:30'], ['marinate', '11:35'], ['sauce', '11:50']]],
['generated control 3',
[[['prep', 15, []], ['sauce', 30, []], ['marinate', 10, []], ['rest', 10, ['shop']],
['roast', 240, ['prep', 'marinate']]],
'19:45'],
'error: unknown step shop']],
[['cycle', [[['a', 5, ['b']], ['b', 5, ['a']]], '18:00'], 'error: cycle'],
['unknown dependency', [[['a', 5, ['shop']]], '18:00'], 'error: unknown step shop'],
['chain', [[['prep', 10, []], ['roast', 90, ['prep']], ['rest', 15, ['roast']]], '18:30'],
[['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']]],
['regression: step duration offset',
[[['prep', 240, []], ['roast', 90, []], ['marinate', 45, ['prep']]], '12:00'],
[['prep', '07:15'], ['roast', '10:30'], ['marinate', '11:15']]],
['repair check: step duration offset',
[[['prep', 30, []], ['roast', 5, []], ['sauce', 15, ['prep', 'marinate']], ['marinate', 30, ['prep']]],
'01:15'],
[['prep', '00:00'], ['marinate', '00:30'], ['sauce', '01:00'], ['roast', '01:10']]],
['generated control 1',
[[['roast', 45, ['prep', 'marinate']], ['marinate', 30, ['prep']], ['sauce', 5, ['prep', 'marinate']],
['prep', 240, ['sauce']]],
'02:00'],
'error: cycle'],
['generated control 2',
[[['rest', 15, ['roast', 'sauce']], ['roast', 90, []], ['prep', 15, []],
['marinate', 45, ['prep', 'shop']], ['sauce', 10, ['roast']]],
'02:00'],
'error: unknown step shop'],
['generated control 3',
[[['marinate', 15, []], ['roast', 15, ['prep', 'marinate']], ['prep', 15, []],
['rest', 90, ['prep', 'marinate', 'roast']], ['sauce', 45, ['shop']]],
'02:00'],
'error: unknown step shop']],
[['unknown dependency', [[['a', 5, ['shop']]], '18:00'], 'error: unknown step shop'],
['chain', [[['prep', 10, []], ['roast', 90, ['prep']], ['rest', 15, ['roast']]], '18:30'],
[['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']]],
['overnight marinade', [[['marinate', 480, []], ['grill', 20, ['marinate']]], '12:00'],
[['marinate', '03:40'], ['grill', '11:40']]],
['regression: step duration offset',
[[['sauce', 5, []], ['roast', 15, ['prep', 'marinate']], ['prep', 15, []], ['rest', 10, ['prep']],
['marinate', 10, ['prep']]],
'01:15'],
[['prep', '00:35'], ['marinate', '00:50'], ['roast', '01:00'], ['rest', '01:05'], ['sauce', '01:10']]],
['repair check: step duration offset',
[[['roast', 10, ['prep', 'marinate']], ['prep', 30, []], ['sauce', 90, ['marinate', 'roast']],
['marinate', 240, []], ['rest', 10, ['prep', 'sauce']]],
'19:45'],
[['marinate', '13:55'], ['prep', '17:25'], ['roast', '17:55'], ['sauce', '18:05'], ['rest', '19:35']]],
['generated control 1',
[[['rest', 240, ['prep', 'roast', 'sauce']], ['marinate', 90, []], ['sauce', 5, ['prep', 'marinate']],
['roast', 45, []], ['prep', 15, ['rest']]],
'18:30'],
'error: cycle'],
['generated control 2', [[['roast', 15, ['prep']], ['prep', 15, []], ['marinate', 10, []]], '00:30'],
[['prep', '00:00'], ['roast', '00:15'], ['marinate', '00:20']]],
['generated control 3',
[[['rest', 240, ['roast']], ['roast', 45, ['prep', 'shop']], ['marinate', 10, []],
['sauce', 45, ['prep', 'roast']], ['prep', 240, []]],
'01:15'],
'error: unknown step shop']],
[['chain', [[['prep', 10, []], ['roast', 90, ['prep']], ['rest', 15, ['roast']]], '18:30'],
[['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']]],
['overnight marinade', [[['marinate', 480, []], ['grill', 20, ['marinate']]], '12:00'],
[['marinate', '03:40'], ['grill', '11:40']]],
['cycle', [[['a', 5, ['b']], ['b', 5, ['a']]], '18:00'], 'error: cycle'],
['regression: step duration offset',
[[['prep', 10, []], ['rest', 30, ['marinate', 'roast', 'sauce']], ['sauce', 30, []],
['plate', 90, ['prep', 'roast', 'sauce', 'rest']], ['marinate', 30, ['prep']],
['roast', 30, ['marinate']]],
'01:15'],
[['prep', '22:05'], ['marinate', '22:15'], ['roast', '22:45'], ['sauce', '22:45'], ['rest', '23:15'],
['plate', '23:45']]],
['repair check: step duration offset',
[[['roast', 45, ['prep', 'marinate']], ['rest', 90, ['prep']], ['prep', 10, []],
['marinate', 15, ['prep']], ['plate', 10, ['roast']], ['sauce', 5, ['prep', 'marinate']]],
'19:45'],
[['prep', '18:05'], ['rest', '18:15'], ['marinate', '18:35'], ['roast', '18:50'], ['plate', '19:35'],
['sauce', '19:40']]],
['generated control 1',
[[['prep', 45, []], ['marinate', 5, []], ['roast', 240, []], ['sauce', 30, ['roast']]], '02:00'],
[['roast', '21:30'], ['prep', '01:15'], ['sauce', '01:30'], ['marinate', '01:55']]],
['generated control 2',
[[['plate', 15, []], ['marinate', 240, ['prep']], ['prep', 15, []], ['roast', 15, []],
['rest', 15, ['marinate']], ['sauce', 45, ['marinate']]],
'18:30'],
[['prep', '13:30'], ['marinate', '13:45'], ['sauce', '17:45'], ['plate', '18:15'], ['rest', '18:15'],
['roast', '18:15']]],
['generated control 3',
[[['marinate', 240, ['shop']], ['plate', 45, ['prep', 'sauce']], ['rest', 90, []], ['prep', 90, ['plate']],
['sauce', 240, ['marinate', 'roast']], ['roast', 15, ['prep', 'marinate']]],
'19:45'],
'error: unknown step shop']]]
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)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| chain | [['prep', '18:30'], ['rest', '18:30'], ['roast', '18:30']] | [['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']] | Failed |
| overnight marinade | [['grill', '12:00'], ['marinate', '12:00']] | [['marinate', '03:40'], ['grill', '11:40']] | Failed |
| cycle | error: cycle | error: cycle | Passed |
| regression: step duration offset | [['marinate', '19:45'], ['prep', '19:45'], ['roast', '19:45'], ['sauce', '19:45']] | [['marinate', '15:15'], ['prep', '15:35'], ['roast', '15:45'], ['sauce', '15:45']] | Failed |
| repair check: step duration offset | [['marinate', '00:30'], ['prep', '00:30'], ['rest', '00:30'], ['roast', '00:30'], ['sauce', '00:30']] | [['rest', '20:30'], ['prep', '23:00'], ['marinate', '23:45'], ['roast', '00:15'], ['sauce', '00:15']] | Failed |
| generated control 1 | error: unknown step shop | error: unknown step shop | Passed |
| generated control 2 | error: unknown step shop | error: unknown step shop | Passed |
| generated control 3 | error: cycle | error: cycle | Passed |
SHA-256 / 935c8abe821b2b9ddab2d1c0236d1d10d2b8350477ec33901a07cd3fa5031d99
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(steps, serve):
by = {s[0]: s for s in steps}
for s in steps:
for d in s[2]:
if d not in by:
return 'error: unknown step ' + d
h, m = serve.split(':')
T = int(h) * 60 + int(m)
latest = {}
visiting = set()
def ls(n):
if n in latest:
return latest[n]
if n in visiting:
return None
visiting.add(n)
finish = T
for s in steps:
if n in s[2]:
v = ls(s[0])
if v is None:
return None
finish = min(finish, v)
visiting.discard(n)
latest[n] = finish - by[n][1] + 1
return latest[n]
rows = []
for s in steps:
v = ls(s[0])
if v is None:
return 'error: cycle'
rows.append((v, s[0]))
rows.sort()
return [[n, '%02d:%02d' % divmod(v % 1440, 60)] for v, n in rows]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['chain', [[['prep', 10, []], ['roast', 90, ['prep']], ['rest', 15, ['roast']]], '18:30'],
[['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']]],
['overnight marinade', [[['marinate', 480, []], ['grill', 20, ['marinate']]], '12:00'],
[['marinate', '03:40'], ['grill', '11:40']]],
['cycle', [[['a', 5, ['b']], ['b', 5, ['a']]], '18:00'], 'error: cycle'],
['regression: step duration offset',
[[['roast', 240, ['marinate']], ['sauce', 240, ['prep']], ['marinate', 30, []], ['prep', 10, []]],
'19:45'],
[['marinate', '15:15'], ['prep', '15:35'], ['roast', '15:45'], ['sauce', '15:45']]],
['repair check: step duration offset',
[[['sauce', 15, ['prep']], ['prep', 45, []], ['rest', 240, []], ['roast', 15, ['prep']],
['marinate', 45, ['prep']]],
'00:30'],
[['rest', '20:30'], ['prep', '23:00'], ['marinate', '23:45'], ['roast', '00:15'], ['sauce', '00:15']]],
['generated control 1',
[[['sauce', 45, ['shop']], ['roast', 45, ['prep', 'marinate']], ['marinate', 90, []], ['prep', 15, []],
['rest', 10, ['sauce']]],
'00:30'],
'error: unknown step shop'],
['generated control 2',
[[['sauce', 30, ['prep', 'marinate', 'shop']], ['rest', 45, ['roast']], ['marinate', 5, []],
['prep', 5, []], ['roast', 5, ['prep']]],
'19:45'],
'error: unknown step shop'],
['generated control 3',
[[['roast', 10, ['prep', 'marinate']], ['marinate', 15, []], ['prep', 45, ['roast']]], '12:00'],
'error: cycle']],
[['overnight marinade', [[['marinate', 480, []], ['grill', 20, ['marinate']]], '12:00'],
[['marinate', '03:40'], ['grill', '11:40']]],
['cycle', [[['a', 5, ['b']], ['b', 5, ['a']]], '18:00'], 'error: cycle'],
['unknown dependency', [[['a', 5, ['shop']]], '18:00'], 'error: unknown step shop'],
['regression: step duration offset',
[[['marinate', 240, []], ['plate', 5, ['prep', 'roast', 'rest']], ['sauce', 5, ['prep']],
['roast', 30, ['prep', 'marinate']], ['prep', 45, []], ['rest', 30, ['roast', 'sauce']]],
'01:15'],
[['marinate', '20:10'], ['prep', '23:25'], ['roast', '00:10'], ['sauce', '00:35'], ['rest', '00:40'],
['plate', '01:10']]],
['repair check: step duration offset',
[[['prep', 15, []], ['plate', 10, ['rest']], ['rest', 10, ['marinate']], ['marinate', 240, ['prep']],
['sauce', 45, ['roast']], ['roast', 15, ['marinate']]],
'18:30'],
[['prep', '13:15'], ['marinate', '13:30'], ['roast', '17:30'], ['sauce', '17:45'], ['rest', '18:10'],
['plate', '18:20']]],
['generated control 1',
[[['marinate', 10, []], ['plate', 45, ['prep', 'sauce']], ['rest', 90, ['prep', 'marinate', 'sauce']],
['sauce', 45, ['marinate']], ['prep', 90, []], ['roast', 15, ['prep']]],
'19:45'],
[['prep', '16:45'], ['marinate', '17:20'], ['sauce', '17:30'], ['rest', '18:15'], ['plate', '19:00'],
['roast', '19:30']]],
['generated control 2',
[[['prep', 90, []], ['sauce', 10, ['prep', 'marinate']], ['roast', 30, ['prep']],
['marinate', 15, ['prep']]],
'12:00'],
[['prep', '10:00'], ['roast', '11:30'], ['marinate', '11:35'], ['sauce', '11:50']]],
['generated control 3',
[[['prep', 15, []], ['sauce', 30, []], ['marinate', 10, []], ['rest', 10, ['shop']],
['roast', 240, ['prep', 'marinate']]],
'19:45'],
'error: unknown step shop']],
[['cycle', [[['a', 5, ['b']], ['b', 5, ['a']]], '18:00'], 'error: cycle'],
['unknown dependency', [[['a', 5, ['shop']]], '18:00'], 'error: unknown step shop'],
['chain', [[['prep', 10, []], ['roast', 90, ['prep']], ['rest', 15, ['roast']]], '18:30'],
[['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']]],
['regression: step duration offset',
[[['prep', 240, []], ['roast', 90, []], ['marinate', 45, ['prep']]], '12:00'],
[['prep', '07:15'], ['roast', '10:30'], ['marinate', '11:15']]],
['repair check: step duration offset',
[[['prep', 30, []], ['roast', 5, []], ['sauce', 15, ['prep', 'marinate']], ['marinate', 30, ['prep']]],
'01:15'],
[['prep', '00:00'], ['marinate', '00:30'], ['sauce', '01:00'], ['roast', '01:10']]],
['generated control 1',
[[['roast', 45, ['prep', 'marinate']], ['marinate', 30, ['prep']], ['sauce', 5, ['prep', 'marinate']],
['prep', 240, ['sauce']]],
'02:00'],
'error: cycle'],
['generated control 2',
[[['rest', 15, ['roast', 'sauce']], ['roast', 90, []], ['prep', 15, []],
['marinate', 45, ['prep', 'shop']], ['sauce', 10, ['roast']]],
'02:00'],
'error: unknown step shop'],
['generated control 3',
[[['marinate', 15, []], ['roast', 15, ['prep', 'marinate']], ['prep', 15, []],
['rest', 90, ['prep', 'marinate', 'roast']], ['sauce', 45, ['shop']]],
'02:00'],
'error: unknown step shop']],
[['unknown dependency', [[['a', 5, ['shop']]], '18:00'], 'error: unknown step shop'],
['chain', [[['prep', 10, []], ['roast', 90, ['prep']], ['rest', 15, ['roast']]], '18:30'],
[['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']]],
['overnight marinade', [[['marinate', 480, []], ['grill', 20, ['marinate']]], '12:00'],
[['marinate', '03:40'], ['grill', '11:40']]],
['regression: step duration offset',
[[['sauce', 5, []], ['roast', 15, ['prep', 'marinate']], ['prep', 15, []], ['rest', 10, ['prep']],
['marinate', 10, ['prep']]],
'01:15'],
[['prep', '00:35'], ['marinate', '00:50'], ['roast', '01:00'], ['rest', '01:05'], ['sauce', '01:10']]],
['repair check: step duration offset',
[[['roast', 10, ['prep', 'marinate']], ['prep', 30, []], ['sauce', 90, ['marinate', 'roast']],
['marinate', 240, []], ['rest', 10, ['prep', 'sauce']]],
'19:45'],
[['marinate', '13:55'], ['prep', '17:25'], ['roast', '17:55'], ['sauce', '18:05'], ['rest', '19:35']]],
['generated control 1',
[[['rest', 240, ['prep', 'roast', 'sauce']], ['marinate', 90, []], ['sauce', 5, ['prep', 'marinate']],
['roast', 45, []], ['prep', 15, ['rest']]],
'18:30'],
'error: cycle'],
['generated control 2', [[['roast', 15, ['prep']], ['prep', 15, []], ['marinate', 10, []]], '00:30'],
[['prep', '00:00'], ['roast', '00:15'], ['marinate', '00:20']]],
['generated control 3',
[[['rest', 240, ['roast']], ['roast', 45, ['prep', 'shop']], ['marinate', 10, []],
['sauce', 45, ['prep', 'roast']], ['prep', 240, []]],
'01:15'],
'error: unknown step shop']],
[['chain', [[['prep', 10, []], ['roast', 90, ['prep']], ['rest', 15, ['roast']]], '18:30'],
[['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']]],
['overnight marinade', [[['marinate', 480, []], ['grill', 20, ['marinate']]], '12:00'],
[['marinate', '03:40'], ['grill', '11:40']]],
['cycle', [[['a', 5, ['b']], ['b', 5, ['a']]], '18:00'], 'error: cycle'],
['regression: step duration offset',
[[['prep', 10, []], ['rest', 30, ['marinate', 'roast', 'sauce']], ['sauce', 30, []],
['plate', 90, ['prep', 'roast', 'sauce', 'rest']], ['marinate', 30, ['prep']],
['roast', 30, ['marinate']]],
'01:15'],
[['prep', '22:05'], ['marinate', '22:15'], ['roast', '22:45'], ['sauce', '22:45'], ['rest', '23:15'],
['plate', '23:45']]],
['repair check: step duration offset',
[[['roast', 45, ['prep', 'marinate']], ['rest', 90, ['prep']], ['prep', 10, []],
['marinate', 15, ['prep']], ['plate', 10, ['roast']], ['sauce', 5, ['prep', 'marinate']]],
'19:45'],
[['prep', '18:05'], ['rest', '18:15'], ['marinate', '18:35'], ['roast', '18:50'], ['plate', '19:35'],
['sauce', '19:40']]],
['generated control 1',
[[['prep', 45, []], ['marinate', 5, []], ['roast', 240, []], ['sauce', 30, ['roast']]], '02:00'],
[['roast', '21:30'], ['prep', '01:15'], ['sauce', '01:30'], ['marinate', '01:55']]],
['generated control 2',
[[['plate', 15, []], ['marinate', 240, ['prep']], ['prep', 15, []], ['roast', 15, []],
['rest', 15, ['marinate']], ['sauce', 45, ['marinate']]],
'18:30'],
[['prep', '13:30'], ['marinate', '13:45'], ['sauce', '17:45'], ['plate', '18:15'], ['rest', '18:15'],
['roast', '18:15']]],
['generated control 3',
[[['marinate', 240, ['shop']], ['plate', 45, ['prep', 'sauce']], ['rest', 90, []], ['prep', 90, ['plate']],
['sauce', 240, ['marinate', 'roast']], ['roast', 15, ['prep', 'marinate']]],
'19:45'],
'error: unknown step shop']]]
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)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| chain | [['prep', '16:38'], ['roast', '16:47'], ['rest', '18:16']] | [['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']] | Failed |
| overnight marinade | [['marinate', '03:42'], ['grill', '11:41']] | [['marinate', '03:40'], ['grill', '11:40']] | Failed |
| cycle | error: cycle | error: cycle | Passed |
| regression: step duration offset | [['marinate', '15:17'], ['prep', '15:37'], ['roast', '15:46'], ['sauce', '15:46']] | [['marinate', '15:15'], ['prep', '15:35'], ['roast', '15:45'], ['sauce', '15:45']] | Failed |
| repair check: step duration offset | [['rest', '20:31'], ['prep', '23:02'], ['marinate', '23:46'], ['roast', '00:16'], ['sauce', '00:16']] | [['rest', '20:30'], ['prep', '23:00'], ['marinate', '23:45'], ['roast', '00:15'], ['sauce', '00:15']] | Failed |
| generated control 1 | error: unknown step shop | error: unknown step shop | Passed |
| generated control 2 | error: unknown step shop | error: unknown step shop | Passed |
| generated control 3 | error: cycle | error: cycle | Passed |
SHA-256 / e26b276f36f690f1d2cde192499ffbfe01c95fc151b9a62fa979a5d6076f7b1f
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(steps, serve):
by = {s[0]: s for s in steps}
for s in steps:
for d in s[2]:
if d not in by:
return 'error: unknown step ' + d
h, m = serve.split(':')
T = int(h) * 60 + int(m)
latest = {}
visiting = set()
def ls(n):
if n in latest:
return latest[n]
if n in visiting:
return None
visiting.add(n)
finish = T
for s in steps:
if n in s[2]:
v = ls(s[0])
if v is None:
return None
finish = min(finish, v)
visiting.discard(n)
latest[n] = finish - by[n][1]
return latest[n]
rows = []
for s in steps:
v = ls(s[0])
if v is None:
return 'error: cycle'
rows.append((v, s[0]))
rows.sort()
return [[n, '%02d:%02d' % divmod(v % 1440, 60)] for v, n in rows]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['chain', [[['prep', 10, []], ['roast', 90, ['prep']], ['rest', 15, ['roast']]], '18:30'],
[['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']]],
['overnight marinade', [[['marinate', 480, []], ['grill', 20, ['marinate']]], '12:00'],
[['marinate', '03:40'], ['grill', '11:40']]],
['cycle', [[['a', 5, ['b']], ['b', 5, ['a']]], '18:00'], 'error: cycle'],
['regression: step duration offset',
[[['roast', 240, ['marinate']], ['sauce', 240, ['prep']], ['marinate', 30, []], ['prep', 10, []]],
'19:45'],
[['marinate', '15:15'], ['prep', '15:35'], ['roast', '15:45'], ['sauce', '15:45']]],
['repair check: step duration offset',
[[['sauce', 15, ['prep']], ['prep', 45, []], ['rest', 240, []], ['roast', 15, ['prep']],
['marinate', 45, ['prep']]],
'00:30'],
[['rest', '20:30'], ['prep', '23:00'], ['marinate', '23:45'], ['roast', '00:15'], ['sauce', '00:15']]],
['generated control 1',
[[['sauce', 45, ['shop']], ['roast', 45, ['prep', 'marinate']], ['marinate', 90, []], ['prep', 15, []],
['rest', 10, ['sauce']]],
'00:30'],
'error: unknown step shop'],
['generated control 2',
[[['sauce', 30, ['prep', 'marinate', 'shop']], ['rest', 45, ['roast']], ['marinate', 5, []],
['prep', 5, []], ['roast', 5, ['prep']]],
'19:45'],
'error: unknown step shop'],
['generated control 3',
[[['roast', 10, ['prep', 'marinate']], ['marinate', 15, []], ['prep', 45, ['roast']]], '12:00'],
'error: cycle']],
[['overnight marinade', [[['marinate', 480, []], ['grill', 20, ['marinate']]], '12:00'],
[['marinate', '03:40'], ['grill', '11:40']]],
['cycle', [[['a', 5, ['b']], ['b', 5, ['a']]], '18:00'], 'error: cycle'],
['unknown dependency', [[['a', 5, ['shop']]], '18:00'], 'error: unknown step shop'],
['regression: step duration offset',
[[['marinate', 240, []], ['plate', 5, ['prep', 'roast', 'rest']], ['sauce', 5, ['prep']],
['roast', 30, ['prep', 'marinate']], ['prep', 45, []], ['rest', 30, ['roast', 'sauce']]],
'01:15'],
[['marinate', '20:10'], ['prep', '23:25'], ['roast', '00:10'], ['sauce', '00:35'], ['rest', '00:40'],
['plate', '01:10']]],
['repair check: step duration offset',
[[['prep', 15, []], ['plate', 10, ['rest']], ['rest', 10, ['marinate']], ['marinate', 240, ['prep']],
['sauce', 45, ['roast']], ['roast', 15, ['marinate']]],
'18:30'],
[['prep', '13:15'], ['marinate', '13:30'], ['roast', '17:30'], ['sauce', '17:45'], ['rest', '18:10'],
['plate', '18:20']]],
['generated control 1',
[[['marinate', 10, []], ['plate', 45, ['prep', 'sauce']], ['rest', 90, ['prep', 'marinate', 'sauce']],
['sauce', 45, ['marinate']], ['prep', 90, []], ['roast', 15, ['prep']]],
'19:45'],
[['prep', '16:45'], ['marinate', '17:20'], ['sauce', '17:30'], ['rest', '18:15'], ['plate', '19:00'],
['roast', '19:30']]],
['generated control 2',
[[['prep', 90, []], ['sauce', 10, ['prep', 'marinate']], ['roast', 30, ['prep']],
['marinate', 15, ['prep']]],
'12:00'],
[['prep', '10:00'], ['roast', '11:30'], ['marinate', '11:35'], ['sauce', '11:50']]],
['generated control 3',
[[['prep', 15, []], ['sauce', 30, []], ['marinate', 10, []], ['rest', 10, ['shop']],
['roast', 240, ['prep', 'marinate']]],
'19:45'],
'error: unknown step shop']],
[['cycle', [[['a', 5, ['b']], ['b', 5, ['a']]], '18:00'], 'error: cycle'],
['unknown dependency', [[['a', 5, ['shop']]], '18:00'], 'error: unknown step shop'],
['chain', [[['prep', 10, []], ['roast', 90, ['prep']], ['rest', 15, ['roast']]], '18:30'],
[['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']]],
['regression: step duration offset',
[[['prep', 240, []], ['roast', 90, []], ['marinate', 45, ['prep']]], '12:00'],
[['prep', '07:15'], ['roast', '10:30'], ['marinate', '11:15']]],
['repair check: step duration offset',
[[['prep', 30, []], ['roast', 5, []], ['sauce', 15, ['prep', 'marinate']], ['marinate', 30, ['prep']]],
'01:15'],
[['prep', '00:00'], ['marinate', '00:30'], ['sauce', '01:00'], ['roast', '01:10']]],
['generated control 1',
[[['roast', 45, ['prep', 'marinate']], ['marinate', 30, ['prep']], ['sauce', 5, ['prep', 'marinate']],
['prep', 240, ['sauce']]],
'02:00'],
'error: cycle'],
['generated control 2',
[[['rest', 15, ['roast', 'sauce']], ['roast', 90, []], ['prep', 15, []],
['marinate', 45, ['prep', 'shop']], ['sauce', 10, ['roast']]],
'02:00'],
'error: unknown step shop'],
['generated control 3',
[[['marinate', 15, []], ['roast', 15, ['prep', 'marinate']], ['prep', 15, []],
['rest', 90, ['prep', 'marinate', 'roast']], ['sauce', 45, ['shop']]],
'02:00'],
'error: unknown step shop']],
[['unknown dependency', [[['a', 5, ['shop']]], '18:00'], 'error: unknown step shop'],
['chain', [[['prep', 10, []], ['roast', 90, ['prep']], ['rest', 15, ['roast']]], '18:30'],
[['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']]],
['overnight marinade', [[['marinate', 480, []], ['grill', 20, ['marinate']]], '12:00'],
[['marinate', '03:40'], ['grill', '11:40']]],
['regression: step duration offset',
[[['sauce', 5, []], ['roast', 15, ['prep', 'marinate']], ['prep', 15, []], ['rest', 10, ['prep']],
['marinate', 10, ['prep']]],
'01:15'],
[['prep', '00:35'], ['marinate', '00:50'], ['roast', '01:00'], ['rest', '01:05'], ['sauce', '01:10']]],
['repair check: step duration offset',
[[['roast', 10, ['prep', 'marinate']], ['prep', 30, []], ['sauce', 90, ['marinate', 'roast']],
['marinate', 240, []], ['rest', 10, ['prep', 'sauce']]],
'19:45'],
[['marinate', '13:55'], ['prep', '17:25'], ['roast', '17:55'], ['sauce', '18:05'], ['rest', '19:35']]],
['generated control 1',
[[['rest', 240, ['prep', 'roast', 'sauce']], ['marinate', 90, []], ['sauce', 5, ['prep', 'marinate']],
['roast', 45, []], ['prep', 15, ['rest']]],
'18:30'],
'error: cycle'],
['generated control 2', [[['roast', 15, ['prep']], ['prep', 15, []], ['marinate', 10, []]], '00:30'],
[['prep', '00:00'], ['roast', '00:15'], ['marinate', '00:20']]],
['generated control 3',
[[['rest', 240, ['roast']], ['roast', 45, ['prep', 'shop']], ['marinate', 10, []],
['sauce', 45, ['prep', 'roast']], ['prep', 240, []]],
'01:15'],
'error: unknown step shop']],
[['chain', [[['prep', 10, []], ['roast', 90, ['prep']], ['rest', 15, ['roast']]], '18:30'],
[['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']]],
['overnight marinade', [[['marinate', 480, []], ['grill', 20, ['marinate']]], '12:00'],
[['marinate', '03:40'], ['grill', '11:40']]],
['cycle', [[['a', 5, ['b']], ['b', 5, ['a']]], '18:00'], 'error: cycle'],
['regression: step duration offset',
[[['prep', 10, []], ['rest', 30, ['marinate', 'roast', 'sauce']], ['sauce', 30, []],
['plate', 90, ['prep', 'roast', 'sauce', 'rest']], ['marinate', 30, ['prep']],
['roast', 30, ['marinate']]],
'01:15'],
[['prep', '22:05'], ['marinate', '22:15'], ['roast', '22:45'], ['sauce', '22:45'], ['rest', '23:15'],
['plate', '23:45']]],
['repair check: step duration offset',
[[['roast', 45, ['prep', 'marinate']], ['rest', 90, ['prep']], ['prep', 10, []],
['marinate', 15, ['prep']], ['plate', 10, ['roast']], ['sauce', 5, ['prep', 'marinate']]],
'19:45'],
[['prep', '18:05'], ['rest', '18:15'], ['marinate', '18:35'], ['roast', '18:50'], ['plate', '19:35'],
['sauce', '19:40']]],
['generated control 1',
[[['prep', 45, []], ['marinate', 5, []], ['roast', 240, []], ['sauce', 30, ['roast']]], '02:00'],
[['roast', '21:30'], ['prep', '01:15'], ['sauce', '01:30'], ['marinate', '01:55']]],
['generated control 2',
[[['plate', 15, []], ['marinate', 240, ['prep']], ['prep', 15, []], ['roast', 15, []],
['rest', 15, ['marinate']], ['sauce', 45, ['marinate']]],
'18:30'],
[['prep', '13:30'], ['marinate', '13:45'], ['sauce', '17:45'], ['plate', '18:15'], ['rest', '18:15'],
['roast', '18:15']]],
['generated control 3',
[[['marinate', 240, ['shop']], ['plate', 45, ['prep', 'sauce']], ['rest', 90, []], ['prep', 90, ['plate']],
['sauce', 240, ['marinate', 'roast']], ['roast', 15, ['prep', 'marinate']]],
'19:45'],
'error: unknown step shop']]]
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)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| chain | [['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']] | [['prep', '16:35'], ['roast', '16:45'], ['rest', '18:15']] | Passed |
| overnight marinade | [['marinate', '03:40'], ['grill', '11:40']] | [['marinate', '03:40'], ['grill', '11:40']] | Passed |
| cycle | error: cycle | error: cycle | Passed |
| regression: step duration offset | [['marinate', '15:15'], ['prep', '15:35'], ['roast', '15:45'], ['sauce', '15:45']] | [['marinate', '15:15'], ['prep', '15:35'], ['roast', '15:45'], ['sauce', '15:45']] | Passed |
| repair check: step duration offset | [['rest', '20:30'], ['prep', '23:00'], ['marinate', '23:45'], ['roast', '00:15'], ['sauce', '00:15']] | [['rest', '20:30'], ['prep', '23:00'], ['marinate', '23:45'], ['roast', '00:15'], ['sauce', '00:15']] | Passed |
| generated control 1 | error: unknown step shop | error: unknown step shop | Passed |
| generated control 2 | error: unknown step shop | error: unknown step shop | Passed |
| generated control 3 | error: cycle | error: cycle | Passed |
SHA-256 / 7f2af23bb23330970c63e6da52f90a0e2fe28c7a747975197a2a862fe6382795
Verification & scope
A deterministic toy contract stated in full here; it is a bounded teaching model, not an authoritative reference or standards implementation. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:52:30.769197+00:00.
Case digest / d7d8f9891d27903aa413475bde0a881dfdb90585cbf893bf2a34e1755eb6987f