FA-94791 / Exam timetabling constraints / Open access
Next-morning check looks at the same slot next day · case 01
An evening exam followed by the next day's first exam is not reported.
ROOT CAUSE
The following morning is computed as p + spd.
VERIFIED REPAIR
The next morning is period p + 1.
Unsuccessful approach: Also accepting p + 2 reports evening-then-midday sequences.
Case contract
sits [student, period] with spd periods per day (day = p // spd). Report ["day", student, day] when a student has more than maxday distinct periods on a day, and ["eve_morn", student, day] when a student sits the last period of a day and the first period of the next day. Rows by student: day findings by day, then evening-morning findings.
Why this case matters
Daily exam limits and evening-then-morning sequences are common student-welfare rules.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(sits, spd, maxday):
by = {}
for st, p in sits:
by.setdefault(st, set()).add(p)
out = []
for st in sorted(by):
ps = by[st]
days = {}
for p in ps:
days[p // spd] = days.get(p // spd, 0) + 1
for d in sorted(days):
if days[d] > maxday:
out.append(['day', st, d])
for p in sorted(ps):
if p % spd == spd - 1 and p + spd in ps:
out.append(['eve_morn', st, p // spd])
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: next morning period 1', [[['s1', 2], ['s1', 3]], 3, 2], [['eve_morn', 's1', 0]]),
('regression variant: next morning period 2',
[[['s2', 8], ['s3', 2], ['s2', 1], ['s2', 1], ['s3', 3]], 3, 1], [['eve_morn', 's3', 0]]),
('partial repair guard 3',
[[['s1', 3], ['s3', 7], ['s3', 11], ['s3', 9], ['s2', 0], ['s1', 6], ['s3', 7], ['s1', 6]], 4, 2], []),
('boundary control 4', [[['s1', 0], ['s1', 1], ['s1', 2]], 3, 2], [['day', 's1', 0]]),
('normal control 5', [[['s2', 3], ['s1', 6]], 3, 2], []),
('normal control 6', [[['s1', 3], ['s3', 2], ['s3', 2]], 4, 1], []),
('normal control 7', [[['s3', 2], ['s1', 4], ['s3', 11], ['s1', 3], ['s1', 11]], 4, 2],
[['eve_morn', 's1', 0]]),
('normal control 8', [[['s3', 0], ['s3', 0], ['s1', 1], ['s3', 3], ['s1', 0]], 2, 2], [])],
[('regression: next morning period 1', [[['s1', 5], ['s1', 6]], 3, 2], [['eve_morn', 's1', 1]]),
('regression variant: next morning period 2',
[[['s1', 7], ['s3', 8], ['s1', 9], ['s1', 11], ['s1', 4], ['s3', 6], ['s3', 7]], 4, 1],
[['day', 's1', 1], ['day', 's1', 2], ['day', 's3', 1], ['eve_morn', 's3', 1]]),
('partial repair guard 3',
[[['s2', 4], ['s2', 9], ['s1', 10], ['s1', 10], ['s2', 11], ['s2', 1], ['s2', 7], ['s3', 7]], 4, 1],
[['day', 's2', 1], ['day', 's2', 2]]),
('boundary control 4', [[['s1', 1], ['s1', 2]], 3, 2], []),
('normal control 5', [[['s3', 2], ['s2', 2], ['s1', 6], ['s2', 4], ['s2', 4], ['s2', 8], ['s1', 2]], 3, 1],
[]),
('normal control 6', [[['s3', 5], ['s3', 5]], 3, 2], []),
('normal control 7', [[['s2', 2], ['s1', 8], ['s3', 1], ['s3', 5], ['s2', 0], ['s1', 1]], 3, 1],
[['day', 's2', 0]]),
('normal control 8', [[['s1', 1], ['s2', 1], ['s2', 2], ['s1', 1], ['s3', 8]], 3, 1], [['day', 's2', 0]])],
[('regression: next morning period 1', [[['s3', 3], ['s1', 1], ['s2', 7], ['s3', 5], ['s3', 8]], 3, 1],
[['day', 's3', 1]]),
('regression variant: next morning period 2', [[['s2', 3], ['s1', 4], ['s2', 4]], 2, 2],
[['eve_morn', 's2', 1]]),
('partial repair guard 3', [[['s2', 4], ['s1', 1], ['s2', 5], ['s2', 7]], 3, 1], [['day', 's2', 1]]),
('boundary control 4', [[['s1', 5], ['s1', 6]], 3, 2], [['eve_morn', 's1', 1]]),
('normal control 5', [[['s1', 0], ['s1', 6], ['s1', 0], ['s2', 5], ['s2', 5], ['s3', 0]], 4, 1], []),
('normal control 6', [[['s2', 3], ['s3', 4], ['s3', 0], ['s2', 3], ['s2', 2]], 2, 1], [['day', 's2', 1]]),
('normal control 7', [[['s3', 1], ['s3', 5]], 3, 2], []),
('normal control 8',
[[['s2', 3], ['s3', 5], ['s3', 2], ['s3', 0], ['s2', 1], ['s1', 2], ['s3', 1], ['s3', 4]], 2, 2],
[['eve_morn', 's3', 0]])],
[('regression: next morning period 1',
[[['s1', 5], ['s3', 2], ['s1', 5], ['s2', 5], ['s1', 3], ['s1', 1], ['s1', 4]], 2, 1],
[['day', 's1', 2], ['eve_morn', 's1', 1]]),
('regression variant: next morning period 2', [[['s1', 3], ['s3', 2], ['s1', 1], ['s3', 2]], 2, 2], []),
('partial repair guard 3',
[[['s1', 1], ['s3', 3], ['s1', 4], ['s3', 6], ['s1', 8], ['s2', 5], ['s1', 2], ['s3', 0]], 3, 2], []),
('boundary control 4', [[['s1', 0], ['s1', 1]], 3, 2], []),
('normal control 5', [[['s3', 0], ['s2', 1], ['s1', 3], ['s2', 5], ['s3', 1], ['s3', 3]], 2, 1],
[['day', 's3', 0]]),
('normal control 6', [[['s3', 4], ['s2', 5], ['s3', 6], ['s3', 5], ['s2', 0], ['s3', 4], ['s1', 0]], 3, 2],
[['eve_morn', 's3', 1]]),
('normal control 7', [[['s1', 1], ['s1', 2]], 4, 1], [['day', 's1', 0]]),
('normal control 8', [[['s3', 4], ['s2', 8], ['s3', 1], ['s1', 1], ['s2', 3]], 3, 1], [])],
[('regression: next morning period 1',
[[['s3', 1], ['s2', 4], ['s1', 11], ['s1', 7], ['s2', 1], ['s2', 5], ['s3', 2], ['s3', 4]], 4, 1],
[['day', 's2', 1], ['day', 's3', 0]]),
('regression variant: next morning period 2',
[[['s1', 2], ['s2', 6], ['s3', 4], ['s3', 4], ['s1', 5], ['s3', 8], ['s3', 2], ['s1', 6]], 3, 2],
[['eve_morn', 's1', 1]]),
('partial repair guard 3',
[[['s2', 0], ['s3', 2], ['s1', 3], ['s2', 3], ['s2', 5], ['s3', 0], ['s1', 4], ['s3', 0]], 2, 2],
[['eve_morn', 's1', 1]]),
('boundary control 4', [[['s1', 2], ['s1', 3]], 3, 2], [['eve_morn', 's1', 0]]),
('normal control 5',
[[['s2', 5], ['s2', 1], ['s1', 2], ['s2', 3], ['s1', 4], ['s2', 1], ['s3', 2], ['s2', 0]], 2, 1],
[['day', 's2', 0]]),
('normal control 6', [[['s1', 3], ['s3', 2], ['s1', 3]], 3, 1], []),
('normal control 7', [[['s1', 4], ['s1', 0], ['s1', 3], ['s1', 0], ['s1', 2], ['s3', 4], ['s2', 2]], 2, 1],
[['day', 's1', 1], ['eve_morn', 's1', 1]]),
('normal control 8', [[['s1', 3], ['s3', 2], ['s1', 1], ['s3', 2]], 2, 2], [])]]
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 |
|---|---|---|---|
| regression: next morning period 1 | [] | [['eve_morn', 's1', 0]] | Failed |
| regression variant: next morning period 2 | [] | [['eve_morn', 's3', 0]] | Failed |
| partial repair guard 3 | [['eve_morn', 's3', 1]] | [] | Failed |
| boundary control 4 | [['day', 's1', 0]] | [['day', 's1', 0]] | Passed |
| normal control 5 | [] | [] | Passed |
| normal control 6 | [] | [] | Passed |
| normal control 7 | [] | [['eve_morn', 's1', 0]] | Failed |
| normal control 8 | [] | [] | Passed |
SHA-256 / 1767dceb7f74dced61a0e2e615aeecced7042686322a5e398d8b18f029f07fd5
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(sits, spd, maxday):
by = {}
for st, p in sits:
by.setdefault(st, set()).add(p)
out = []
for st in sorted(by):
ps = by[st]
days = {}
for p in ps:
days[p // spd] = days.get(p // spd, 0) + 1
for d in sorted(days):
if days[d] > maxday:
out.append(['day', st, d])
for p in sorted(ps):
if p % spd == spd - 1 and (p + 1 in ps or p + 2 in ps):
out.append(['eve_morn', st, p // spd])
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: next morning period 1', [[['s1', 2], ['s1', 3]], 3, 2], [['eve_morn', 's1', 0]]),
('regression variant: next morning period 2',
[[['s2', 8], ['s3', 2], ['s2', 1], ['s2', 1], ['s3', 3]], 3, 1], [['eve_morn', 's3', 0]]),
('partial repair guard 3',
[[['s1', 3], ['s3', 7], ['s3', 11], ['s3', 9], ['s2', 0], ['s1', 6], ['s3', 7], ['s1', 6]], 4, 2], []),
('boundary control 4', [[['s1', 0], ['s1', 1], ['s1', 2]], 3, 2], [['day', 's1', 0]]),
('normal control 5', [[['s2', 3], ['s1', 6]], 3, 2], []),
('normal control 6', [[['s1', 3], ['s3', 2], ['s3', 2]], 4, 1], []),
('normal control 7', [[['s3', 2], ['s1', 4], ['s3', 11], ['s1', 3], ['s1', 11]], 4, 2],
[['eve_morn', 's1', 0]]),
('normal control 8', [[['s3', 0], ['s3', 0], ['s1', 1], ['s3', 3], ['s1', 0]], 2, 2], [])],
[('regression: next morning period 1', [[['s1', 5], ['s1', 6]], 3, 2], [['eve_morn', 's1', 1]]),
('regression variant: next morning period 2',
[[['s1', 7], ['s3', 8], ['s1', 9], ['s1', 11], ['s1', 4], ['s3', 6], ['s3', 7]], 4, 1],
[['day', 's1', 1], ['day', 's1', 2], ['day', 's3', 1], ['eve_morn', 's3', 1]]),
('partial repair guard 3',
[[['s2', 4], ['s2', 9], ['s1', 10], ['s1', 10], ['s2', 11], ['s2', 1], ['s2', 7], ['s3', 7]], 4, 1],
[['day', 's2', 1], ['day', 's2', 2]]),
('boundary control 4', [[['s1', 1], ['s1', 2]], 3, 2], []),
('normal control 5', [[['s3', 2], ['s2', 2], ['s1', 6], ['s2', 4], ['s2', 4], ['s2', 8], ['s1', 2]], 3, 1],
[]),
('normal control 6', [[['s3', 5], ['s3', 5]], 3, 2], []),
('normal control 7', [[['s2', 2], ['s1', 8], ['s3', 1], ['s3', 5], ['s2', 0], ['s1', 1]], 3, 1],
[['day', 's2', 0]]),
('normal control 8', [[['s1', 1], ['s2', 1], ['s2', 2], ['s1', 1], ['s3', 8]], 3, 1], [['day', 's2', 0]])],
[('regression: next morning period 1', [[['s3', 3], ['s1', 1], ['s2', 7], ['s3', 5], ['s3', 8]], 3, 1],
[['day', 's3', 1]]),
('regression variant: next morning period 2', [[['s2', 3], ['s1', 4], ['s2', 4]], 2, 2],
[['eve_morn', 's2', 1]]),
('partial repair guard 3', [[['s2', 4], ['s1', 1], ['s2', 5], ['s2', 7]], 3, 1], [['day', 's2', 1]]),
('boundary control 4', [[['s1', 5], ['s1', 6]], 3, 2], [['eve_morn', 's1', 1]]),
('normal control 5', [[['s1', 0], ['s1', 6], ['s1', 0], ['s2', 5], ['s2', 5], ['s3', 0]], 4, 1], []),
('normal control 6', [[['s2', 3], ['s3', 4], ['s3', 0], ['s2', 3], ['s2', 2]], 2, 1], [['day', 's2', 1]]),
('normal control 7', [[['s3', 1], ['s3', 5]], 3, 2], []),
('normal control 8',
[[['s2', 3], ['s3', 5], ['s3', 2], ['s3', 0], ['s2', 1], ['s1', 2], ['s3', 1], ['s3', 4]], 2, 2],
[['eve_morn', 's3', 0]])],
[('regression: next morning period 1',
[[['s1', 5], ['s3', 2], ['s1', 5], ['s2', 5], ['s1', 3], ['s1', 1], ['s1', 4]], 2, 1],
[['day', 's1', 2], ['eve_morn', 's1', 1]]),
('regression variant: next morning period 2', [[['s1', 3], ['s3', 2], ['s1', 1], ['s3', 2]], 2, 2], []),
('partial repair guard 3',
[[['s1', 1], ['s3', 3], ['s1', 4], ['s3', 6], ['s1', 8], ['s2', 5], ['s1', 2], ['s3', 0]], 3, 2], []),
('boundary control 4', [[['s1', 0], ['s1', 1]], 3, 2], []),
('normal control 5', [[['s3', 0], ['s2', 1], ['s1', 3], ['s2', 5], ['s3', 1], ['s3', 3]], 2, 1],
[['day', 's3', 0]]),
('normal control 6', [[['s3', 4], ['s2', 5], ['s3', 6], ['s3', 5], ['s2', 0], ['s3', 4], ['s1', 0]], 3, 2],
[['eve_morn', 's3', 1]]),
('normal control 7', [[['s1', 1], ['s1', 2]], 4, 1], [['day', 's1', 0]]),
('normal control 8', [[['s3', 4], ['s2', 8], ['s3', 1], ['s1', 1], ['s2', 3]], 3, 1], [])],
[('regression: next morning period 1',
[[['s3', 1], ['s2', 4], ['s1', 11], ['s1', 7], ['s2', 1], ['s2', 5], ['s3', 2], ['s3', 4]], 4, 1],
[['day', 's2', 1], ['day', 's3', 0]]),
('regression variant: next morning period 2',
[[['s1', 2], ['s2', 6], ['s3', 4], ['s3', 4], ['s1', 5], ['s3', 8], ['s3', 2], ['s1', 6]], 3, 2],
[['eve_morn', 's1', 1]]),
('partial repair guard 3',
[[['s2', 0], ['s3', 2], ['s1', 3], ['s2', 3], ['s2', 5], ['s3', 0], ['s1', 4], ['s3', 0]], 2, 2],
[['eve_morn', 's1', 1]]),
('boundary control 4', [[['s1', 2], ['s1', 3]], 3, 2], [['eve_morn', 's1', 0]]),
('normal control 5',
[[['s2', 5], ['s2', 1], ['s1', 2], ['s2', 3], ['s1', 4], ['s2', 1], ['s3', 2], ['s2', 0]], 2, 1],
[['day', 's2', 0]]),
('normal control 6', [[['s1', 3], ['s3', 2], ['s1', 3]], 3, 1], []),
('normal control 7', [[['s1', 4], ['s1', 0], ['s1', 3], ['s1', 0], ['s1', 2], ['s3', 4], ['s2', 2]], 2, 1],
[['day', 's1', 1], ['eve_morn', 's1', 1]]),
('normal control 8', [[['s1', 3], ['s3', 2], ['s1', 1], ['s3', 2]], 2, 2], [])]]
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 |
|---|---|---|---|
| regression: next morning period 1 | [['eve_morn', 's1', 0]] | [['eve_morn', 's1', 0]] | Passed |
| regression variant: next morning period 2 | [['eve_morn', 's3', 0]] | [['eve_morn', 's3', 0]] | Passed |
| partial repair guard 3 | [['eve_morn', 's3', 1]] | [] | Failed |
| boundary control 4 | [['day', 's1', 0]] | [['day', 's1', 0]] | Passed |
| normal control 5 | [] | [] | Passed |
| normal control 6 | [] | [] | Passed |
| normal control 7 | [['eve_morn', 's1', 0]] | [['eve_morn', 's1', 0]] | Passed |
| normal control 8 | [] | [] | Passed |
SHA-256 / 65938d1b71bbbc395908f9ab2621fe90ad1eedb29e9a506d0dea49b81f5c04c0
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(sits, spd, maxday):
by = {}
for st, p in sits:
by.setdefault(st, set()).add(p)
out = []
for st in sorted(by):
ps = by[st]
days = {}
for p in ps:
days[p // spd] = days.get(p // spd, 0) + 1
for d in sorted(days):
if days[d] > maxday:
out.append(['day', st, d])
for p in sorted(ps):
if p % spd == spd - 1 and p + 1 in ps:
out.append(['eve_morn', st, p // spd])
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: next morning period 1', [[['s1', 2], ['s1', 3]], 3, 2], [['eve_morn', 's1', 0]]),
('regression variant: next morning period 2',
[[['s2', 8], ['s3', 2], ['s2', 1], ['s2', 1], ['s3', 3]], 3, 1], [['eve_morn', 's3', 0]]),
('partial repair guard 3',
[[['s1', 3], ['s3', 7], ['s3', 11], ['s3', 9], ['s2', 0], ['s1', 6], ['s3', 7], ['s1', 6]], 4, 2], []),
('boundary control 4', [[['s1', 0], ['s1', 1], ['s1', 2]], 3, 2], [['day', 's1', 0]]),
('normal control 5', [[['s2', 3], ['s1', 6]], 3, 2], []),
('normal control 6', [[['s1', 3], ['s3', 2], ['s3', 2]], 4, 1], []),
('normal control 7', [[['s3', 2], ['s1', 4], ['s3', 11], ['s1', 3], ['s1', 11]], 4, 2],
[['eve_morn', 's1', 0]]),
('normal control 8', [[['s3', 0], ['s3', 0], ['s1', 1], ['s3', 3], ['s1', 0]], 2, 2], [])],
[('regression: next morning period 1', [[['s1', 5], ['s1', 6]], 3, 2], [['eve_morn', 's1', 1]]),
('regression variant: next morning period 2',
[[['s1', 7], ['s3', 8], ['s1', 9], ['s1', 11], ['s1', 4], ['s3', 6], ['s3', 7]], 4, 1],
[['day', 's1', 1], ['day', 's1', 2], ['day', 's3', 1], ['eve_morn', 's3', 1]]),
('partial repair guard 3',
[[['s2', 4], ['s2', 9], ['s1', 10], ['s1', 10], ['s2', 11], ['s2', 1], ['s2', 7], ['s3', 7]], 4, 1],
[['day', 's2', 1], ['day', 's2', 2]]),
('boundary control 4', [[['s1', 1], ['s1', 2]], 3, 2], []),
('normal control 5', [[['s3', 2], ['s2', 2], ['s1', 6], ['s2', 4], ['s2', 4], ['s2', 8], ['s1', 2]], 3, 1],
[]),
('normal control 6', [[['s3', 5], ['s3', 5]], 3, 2], []),
('normal control 7', [[['s2', 2], ['s1', 8], ['s3', 1], ['s3', 5], ['s2', 0], ['s1', 1]], 3, 1],
[['day', 's2', 0]]),
('normal control 8', [[['s1', 1], ['s2', 1], ['s2', 2], ['s1', 1], ['s3', 8]], 3, 1], [['day', 's2', 0]])],
[('regression: next morning period 1', [[['s3', 3], ['s1', 1], ['s2', 7], ['s3', 5], ['s3', 8]], 3, 1],
[['day', 's3', 1]]),
('regression variant: next morning period 2', [[['s2', 3], ['s1', 4], ['s2', 4]], 2, 2],
[['eve_morn', 's2', 1]]),
('partial repair guard 3', [[['s2', 4], ['s1', 1], ['s2', 5], ['s2', 7]], 3, 1], [['day', 's2', 1]]),
('boundary control 4', [[['s1', 5], ['s1', 6]], 3, 2], [['eve_morn', 's1', 1]]),
('normal control 5', [[['s1', 0], ['s1', 6], ['s1', 0], ['s2', 5], ['s2', 5], ['s3', 0]], 4, 1], []),
('normal control 6', [[['s2', 3], ['s3', 4], ['s3', 0], ['s2', 3], ['s2', 2]], 2, 1], [['day', 's2', 1]]),
('normal control 7', [[['s3', 1], ['s3', 5]], 3, 2], []),
('normal control 8',
[[['s2', 3], ['s3', 5], ['s3', 2], ['s3', 0], ['s2', 1], ['s1', 2], ['s3', 1], ['s3', 4]], 2, 2],
[['eve_morn', 's3', 0]])],
[('regression: next morning period 1',
[[['s1', 5], ['s3', 2], ['s1', 5], ['s2', 5], ['s1', 3], ['s1', 1], ['s1', 4]], 2, 1],
[['day', 's1', 2], ['eve_morn', 's1', 1]]),
('regression variant: next morning period 2', [[['s1', 3], ['s3', 2], ['s1', 1], ['s3', 2]], 2, 2], []),
('partial repair guard 3',
[[['s1', 1], ['s3', 3], ['s1', 4], ['s3', 6], ['s1', 8], ['s2', 5], ['s1', 2], ['s3', 0]], 3, 2], []),
('boundary control 4', [[['s1', 0], ['s1', 1]], 3, 2], []),
('normal control 5', [[['s3', 0], ['s2', 1], ['s1', 3], ['s2', 5], ['s3', 1], ['s3', 3]], 2, 1],
[['day', 's3', 0]]),
('normal control 6', [[['s3', 4], ['s2', 5], ['s3', 6], ['s3', 5], ['s2', 0], ['s3', 4], ['s1', 0]], 3, 2],
[['eve_morn', 's3', 1]]),
('normal control 7', [[['s1', 1], ['s1', 2]], 4, 1], [['day', 's1', 0]]),
('normal control 8', [[['s3', 4], ['s2', 8], ['s3', 1], ['s1', 1], ['s2', 3]], 3, 1], [])],
[('regression: next morning period 1',
[[['s3', 1], ['s2', 4], ['s1', 11], ['s1', 7], ['s2', 1], ['s2', 5], ['s3', 2], ['s3', 4]], 4, 1],
[['day', 's2', 1], ['day', 's3', 0]]),
('regression variant: next morning period 2',
[[['s1', 2], ['s2', 6], ['s3', 4], ['s3', 4], ['s1', 5], ['s3', 8], ['s3', 2], ['s1', 6]], 3, 2],
[['eve_morn', 's1', 1]]),
('partial repair guard 3',
[[['s2', 0], ['s3', 2], ['s1', 3], ['s2', 3], ['s2', 5], ['s3', 0], ['s1', 4], ['s3', 0]], 2, 2],
[['eve_morn', 's1', 1]]),
('boundary control 4', [[['s1', 2], ['s1', 3]], 3, 2], [['eve_morn', 's1', 0]]),
('normal control 5',
[[['s2', 5], ['s2', 1], ['s1', 2], ['s2', 3], ['s1', 4], ['s2', 1], ['s3', 2], ['s2', 0]], 2, 1],
[['day', 's2', 0]]),
('normal control 6', [[['s1', 3], ['s3', 2], ['s1', 3]], 3, 1], []),
('normal control 7', [[['s1', 4], ['s1', 0], ['s1', 3], ['s1', 0], ['s1', 2], ['s3', 4], ['s2', 2]], 2, 1],
[['day', 's1', 1], ['eve_morn', 's1', 1]]),
('normal control 8', [[['s1', 3], ['s3', 2], ['s1', 1], ['s3', 2]], 2, 2], [])]]
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 |
|---|---|---|---|
| regression: next morning period 1 | [['eve_morn', 's1', 0]] | [['eve_morn', 's1', 0]] | Passed |
| regression variant: next morning period 2 | [['eve_morn', 's3', 0]] | [['eve_morn', 's3', 0]] | Passed |
| partial repair guard 3 | [] | [] | Passed |
| boundary control 4 | [['day', 's1', 0]] | [['day', 's1', 0]] | Passed |
| normal control 5 | [] | [] | Passed |
| normal control 6 | [] | [] | Passed |
| normal control 7 | [['eve_morn', 's1', 0]] | [['eve_morn', 's1', 0]] | Passed |
| normal control 8 | [] | [] | Passed |
SHA-256 / 67a1232c20da6f8cb7c6896a94746dbd4e1e0c83114ead5003f68bca9c5d0611
Verification & scope
Stipulated toy exam-timetabling rule set for a bounded model; it does not claim conformance with any institution's regulations or a benchmark specification, and it performs no search or optimisation. 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:07.789066+00:00.
Case digest / 893c8f90d86f3bede91cea3b2fdf586905dcb6c86490af02b079dd55b6ad86cd