FA-94481 / Exam timetabling constraints / Open access
Precedence constraint satisfied by sharing a period · case 01
An exam required to follow another is accepted in the same period.
ROOT CAUSE
The after test only rejects a strictly earlier period.
VERIFIED REPAIR
Require the dependent exam to be in a strictly later period.
Unsuccessful approach: Reversing the operands enforces the opposite precedence.
Case contract
timetable maps exam -> period index, exams exam -> duration, periods -> duration. Duration violations (exam longer than its period) are listed first by exam id; then for each constraint in order: after (a must be in a strictly later period than b), exclusion (different periods), coincidence (same period), exclusive (a must be alone in its period). Return violation rows.
Why this case matters
Hard-constraint validation gates every candidate exam timetable.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(timetable, exams, periods, cons):
out = []
for e in sorted(timetable):
if exams[e] > periods[timetable[e]]:
out.append(['duration', e])
for kind, a, b in cons:
pa, pb = timetable[a], timetable[b]
if kind == 'after' and pa < pb:
out.append([kind, a, b])
elif kind == 'exclusion' and pa == pb:
out.append([kind, a, b])
elif kind == 'coincidence' and pa != pb:
out.append([kind, a, b])
elif kind == 'exclusive' and sum(1 for e in timetable if timetable[e] == pa) > 1:
out.append([kind, a, b])
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: after direction 1', [{'A': 1, 'B': 1}, {'A': 90, 'B': 90}, [90, 120], [['after', 'A', 'B']]],
[['after', 'A', 'B']]),
('regression variant: after direction 2',
[{'MATH101H': 3, 'MATH101': 3, 'PHYS110': 3}, {'MATH101': 180, 'MATH101H': 90, 'PHYS110': 180},
[180, 90, 120, 90], [['after', 'MATH101H', 'PHYS110'], ['after', 'MATH101H', 'PHYS110']]],
[['duration', 'MATH101'], ['duration', 'PHYS110'], ['after', 'MATH101H', 'PHYS110'],
['after', 'MATH101H', 'PHYS110']]),
('partial repair guard 3',
[{'MATH101': 2, 'PHYS110': 0, 'MATH101H': 0}, {'MATH101': 120, 'MATH101H': 120, 'PHYS110': 90},
[120, 90, 180, 180],
[['coincidence', 'MATH101', 'PHYS110'], ['exclusive', 'PHYS110', 'MATH101H'],
['after', 'PHYS110', 'MATH101'], ['coincidence', 'MATH101H', 'MATH101']]],
[['coincidence', 'MATH101', 'PHYS110'], ['exclusive', 'PHYS110', 'MATH101H'],
['after', 'PHYS110', 'MATH101'], ['coincidence', 'MATH101H', 'MATH101']]),
('boundary control 4', [{'A': 1, 'B': 0}, {'A': 120, 'B': 90}, [90, 120], [['exclusive', 'A', 'B']]], []),
('normal control 5',
[{'PHYS110': 0, 'MATH101': 2, 'MATH101H': 0, 'CHEM120': 1},
{'MATH101': 90, 'MATH101H': 180, 'PHYS110': 180, 'CHEM120': 90}, [90, 120, 120, 120],
[['coincidence', 'MATH101', 'PHYS110'], ['coincidence', 'PHYS110', 'MATH101'],
['after', 'CHEM120', 'MATH101'], ['exclusive', 'CHEM120', 'MATH101']]],
[['duration', 'MATH101H'], ['duration', 'PHYS110'], ['coincidence', 'MATH101', 'PHYS110'],
['coincidence', 'PHYS110', 'MATH101'], ['after', 'CHEM120', 'MATH101']]),
('normal control 6',
[{'PHYS110': 1, 'MATH101': 0, 'CHEM120': 3, 'MATH101H': 0},
{'MATH101': 180, 'MATH101H': 90, 'PHYS110': 120, 'CHEM120': 120}, [90, 120, 120, 120],
[['after', 'MATH101', 'MATH101H'], ['after', 'CHEM120', 'MATH101H'],
['coincidence', 'CHEM120', 'MATH101H'], ['coincidence', 'MATH101H', 'CHEM120']]],
[['duration', 'MATH101'], ['after', 'MATH101', 'MATH101H'], ['coincidence', 'CHEM120', 'MATH101H'],
['coincidence', 'MATH101H', 'CHEM120']]),
('normal control 7',
[{'MATH101H': 1, 'HIST140': 3, 'PHYS110': 2, 'BIO130': 3, 'CHEM120': 1, 'MATH101': 2},
{'MATH101': 180, 'MATH101H': 180, 'PHYS110': 90, 'CHEM120': 90, 'BIO130': 120, 'HIST140': 90},
[180, 180, 180, 90], [['after', 'BIO130', 'PHYS110'], ['exclusion', 'CHEM120', 'MATH101']]],
[['duration', 'BIO130']]),
('normal control 8',
[{'CHEM120': 0, 'PHYS110': 2, 'MATH101H': 2, 'MATH101': 2, 'HIST140': 0, 'BIO130': 1},
{'MATH101': 90, 'MATH101H': 90, 'PHYS110': 90, 'CHEM120': 120, 'BIO130': 120, 'HIST140': 90},
[90, 120, 180, 120],
[['exclusion', 'BIO130', 'MATH101'], ['coincidence', 'CHEM120', 'MATH101H'],
['exclusive', 'CHEM120', 'MATH101'], ['coincidence', 'HIST140', 'MATH101']]],
[['duration', 'CHEM120'], ['coincidence', 'CHEM120', 'MATH101H'], ['exclusive', 'CHEM120', 'MATH101'],
['coincidence', 'HIST140', 'MATH101']])],
[('regression: after direction 1',
[{'BIO130': 0, 'PHYS110': 3, 'MATH101': 1, 'CHEM120': 0, 'MATH101H': 1},
{'MATH101': 180, 'MATH101H': 120, 'PHYS110': 180, 'CHEM120': 90, 'BIO130': 90}, [120, 120, 180, 90],
[['coincidence', 'CHEM120', 'BIO130'], ['after', 'CHEM120', 'BIO130'],
['exclusive', 'MATH101H', 'MATH101']]],
[['duration', 'MATH101'], ['duration', 'PHYS110'], ['after', 'CHEM120', 'BIO130'],
['exclusive', 'MATH101H', 'MATH101']]),
('regression variant: after direction 2',
[{'PHYS110': 3, 'MATH101': 3, 'MATH101H': 3}, {'MATH101': 120, 'MATH101H': 120, 'PHYS110': 90},
[120, 120, 180, 180],
[['coincidence', 'PHYS110', 'MATH101H'], ['exclusion', 'MATH101H', 'PHYS110'],
['after', 'MATH101', 'PHYS110'], ['exclusive', 'MATH101', 'MATH101H']]],
[['exclusion', 'MATH101H', 'PHYS110'], ['after', 'MATH101', 'PHYS110'],
['exclusive', 'MATH101', 'MATH101H']]),
('partial repair guard 3',
[{'MATH101': 0, 'MATH101H': 1, 'PHYS110': 3}, {'MATH101': 180, 'MATH101H': 90, 'PHYS110': 120},
[120, 90, 90, 180],
[['after', 'PHYS110', 'MATH101H'], ['exclusive', 'MATH101', 'PHYS110'],
['coincidence', 'MATH101', 'MATH101H']]],
[['duration', 'MATH101'], ['coincidence', 'MATH101', 'MATH101H']]),
('boundary control 4', [{'A': 2, 'B': 1}, {'A': 90, 'B': 90}, [90, 120, 120], [['after', 'A', 'B']]], []),
('normal control 5',
[{'MATH101': 1, 'PHYS110': 2, 'HIST140': 1, 'BIO130': 2, 'CHEM120': 1, 'MATH101H': 1},
{'MATH101': 90, 'MATH101H': 120, 'PHYS110': 90, 'CHEM120': 120, 'BIO130': 180, 'HIST140': 120},
[90, 120, 180, 120], [['exclusive', 'HIST140', 'PHYS110']]],
[['exclusive', 'HIST140', 'PHYS110']]),
('normal control 6',
[{'MATH101H': 3, 'CHEM120': 1, 'PHYS110': 0, 'MATH101': 1, 'BIO130': 0},
{'MATH101': 90, 'MATH101H': 120, 'PHYS110': 180, 'CHEM120': 180, 'BIO130': 90}, [90, 90, 120, 180],
[['after', 'MATH101H', 'PHYS110']]],
[['duration', 'CHEM120'], ['duration', 'PHYS110']]),
('normal control 7',
[{'MATH101': 3, 'BIO130': 1, 'PHYS110': 0, 'CHEM120': 2, 'MATH101H': 2, 'HIST140': 2},
{'MATH101': 90, 'MATH101H': 120, 'PHYS110': 90, 'CHEM120': 180, 'BIO130': 180, 'HIST140': 180},
[180, 90, 180, 120], [['after', 'HIST140', 'MATH101H'], ['coincidence', 'PHYS110', 'MATH101H']]],
[['duration', 'BIO130'], ['after', 'HIST140', 'MATH101H'], ['coincidence', 'PHYS110', 'MATH101H']]),
('normal control 8',
[{'MATH101H': 3, 'MATH101': 3, 'PHYS110': 3}, {'MATH101': 90, 'MATH101H': 180, 'PHYS110': 90},
[90, 180, 90, 90],
[['after', 'MATH101H', 'PHYS110'], ['coincidence', 'PHYS110', 'MATH101H'],
['coincidence', 'MATH101H', 'MATH101']]],
[['duration', 'MATH101H'], ['after', 'MATH101H', 'PHYS110']])],
[('regression: after direction 1',
[{'PHYS110': 3, 'CHEM120': 1, 'MATH101': 1, 'MATH101H': 1},
{'MATH101': 120, 'MATH101H': 120, 'PHYS110': 180, 'CHEM120': 90}, [180, 120, 120, 90],
[['after', 'MATH101', 'CHEM120'], ['exclusive', 'MATH101', 'CHEM120']]],
[['duration', 'PHYS110'], ['after', 'MATH101', 'CHEM120'], ['exclusive', 'MATH101', 'CHEM120']]),
('regression variant: after direction 2',
[{'CHEM120': 3, 'BIO130': 3, 'MATH101': 2, 'HIST140': 2, 'PHYS110': 0, 'MATH101H': 0},
{'MATH101': 180, 'MATH101H': 180, 'PHYS110': 90, 'CHEM120': 180, 'BIO130': 180, 'HIST140': 180},
[90, 180, 90, 120],
[['after', 'BIO130', 'CHEM120'], ['exclusion', 'MATH101H', 'PHYS110'],
['coincidence', 'MATH101', 'PHYS110'], ['exclusion', 'MATH101', 'PHYS110']]],
[['duration', 'BIO130'], ['duration', 'CHEM120'], ['duration', 'HIST140'], ['duration', 'MATH101'],
['duration', 'MATH101H'], ['after', 'BIO130', 'CHEM120'], ['exclusion', 'MATH101H', 'PHYS110'],
['coincidence', 'MATH101', 'PHYS110']]),
('partial repair guard 3',
[{'PHYS110': 3, 'CHEM120': 0, 'MATH101': 3, 'MATH101H': 2},
{'MATH101': 120, 'MATH101H': 90, 'PHYS110': 180, 'CHEM120': 180}, [120, 120, 90, 120],
[['coincidence', 'CHEM120', 'PHYS110'], ['coincidence', 'MATH101H', 'MATH101'],
['after', 'MATH101H', 'MATH101']]],
[['duration', 'CHEM120'], ['duration', 'PHYS110'], ['coincidence', 'CHEM120', 'PHYS110'],
['coincidence', 'MATH101H', 'MATH101'], ['after', 'MATH101H', 'MATH101']]),
('boundary control 4', [{'B': 0, 'A': 1}, {'A': 180, 'B': 180}, [120, 120], []],
[['duration', 'A'], ['duration', 'B']]),
('normal control 5',
[{'MATH101H': 3, 'MATH101': 1, 'CHEM120': 0, 'PHYS110': 0},
{'MATH101': 90, 'MATH101H': 180, 'PHYS110': 90, 'CHEM120': 90}, [180, 90, 180, 180],
[['exclusive', 'MATH101H', 'CHEM120']]],
[]),
('normal control 6',
[{'MATH101': 0, 'PHYS110': 1, 'MATH101H': 2}, {'MATH101': 90, 'MATH101H': 180, 'PHYS110': 90},
[180, 90, 120, 90], [['exclusive', 'MATH101H', 'PHYS110']]],
[['duration', 'MATH101H']]),
('normal control 7',
[{'MATH101H': 2, 'CHEM120': 1, 'BIO130': 3, 'MATH101': 3, 'PHYS110': 2},
{'MATH101': 120, 'MATH101H': 180, 'PHYS110': 120, 'CHEM120': 120, 'BIO130': 120}, [120, 120, 120, 90],
[['exclusion', 'CHEM120', 'MATH101'], ['after', 'MATH101H', 'MATH101'], ['after', 'CHEM120', 'MATH101H'],
['coincidence', 'PHYS110', 'MATH101H']]],
[['duration', 'BIO130'], ['duration', 'MATH101'], ['duration', 'MATH101H'],
['after', 'MATH101H', 'MATH101'], ['after', 'CHEM120', 'MATH101H']]),
('normal control 8',
[{'MATH101H': 0, 'MATH101': 0, 'PHYS110': 3}, {'MATH101': 180, 'MATH101H': 120, 'PHYS110': 180},
[180, 90, 120, 90],
[['coincidence', 'PHYS110', 'MATH101H'], ['exclusive', 'MATH101', 'PHYS110'],
['after', 'PHYS110', 'MATH101H']]],
[['duration', 'PHYS110'], ['coincidence', 'PHYS110', 'MATH101H'], ['exclusive', 'MATH101', 'PHYS110']])],
[('regression: after direction 1',
[{'CHEM120': 3, 'HIST140': 0, 'PHYS110': 1, 'BIO130': 3, 'MATH101': 0, 'MATH101H': 2},
{'MATH101': 120, 'MATH101H': 120, 'PHYS110': 90, 'CHEM120': 120, 'BIO130': 120, 'HIST140': 180},
[90, 90, 90, 90],
[['exclusion', 'HIST140', 'BIO130'], ['exclusion', 'MATH101', 'MATH101H'],
['exclusive', 'BIO130', 'MATH101H'], ['after', 'HIST140', 'MATH101']]],
[['duration', 'BIO130'], ['duration', 'CHEM120'], ['duration', 'HIST140'], ['duration', 'MATH101'],
['duration', 'MATH101H'], ['exclusive', 'BIO130', 'MATH101H'], ['after', 'HIST140', 'MATH101']]),
('regression variant: after direction 2',
[{'MATH101': 1, 'MATH101H': 1, 'PHYS110': 0}, {'MATH101': 90, 'MATH101H': 90, 'PHYS110': 90},
[180, 90, 120, 180],
[['after', 'MATH101', 'MATH101H'], ['exclusion', 'PHYS110', 'MATH101'],
['coincidence', 'PHYS110', 'MATH101'], ['exclusive', 'PHYS110', 'MATH101H']]],
[['after', 'MATH101', 'MATH101H'], ['coincidence', 'PHYS110', 'MATH101']]),
('partial repair guard 3',
[{'BIO130': 1, 'PHYS110': 0, 'MATH101': 0, 'MATH101H': 1, 'CHEM120': 2},
{'MATH101': 120, 'MATH101H': 180, 'PHYS110': 120, 'CHEM120': 120, 'BIO130': 180}, [90, 90, 90, 120],
[['exclusive', 'MATH101', 'BIO130'], ['after', 'PHYS110', 'MATH101H'],
['exclusion', 'MATH101', 'PHYS110'], ['after', 'PHYS110', 'BIO130']]],
[['duration', 'BIO130'], ['duration', 'CHEM120'], ['duration', 'MATH101'], ['duration', 'MATH101H'],
['duration', 'PHYS110'], ['exclusive', 'MATH101', 'BIO130'], ['after', 'PHYS110', 'MATH101H'],
['exclusion', 'MATH101', 'PHYS110'], ['after', 'PHYS110', 'BIO130']]),
('boundary control 4', [{'A': 0}, {'A': 120}, [120], []], []),
('normal control 5',
[{'HIST140': 1, 'MATH101H': 3, 'BIO130': 3, 'MATH101': 1, 'CHEM120': 3, 'PHYS110': 1},
{'MATH101': 90, 'MATH101H': 90, 'PHYS110': 90, 'CHEM120': 120, 'BIO130': 120, 'HIST140': 180},
[180, 120, 180, 90], [['exclusion', 'MATH101H', 'PHYS110']]],
[['duration', 'BIO130'], ['duration', 'CHEM120'], ['duration', 'HIST140']]),
('normal control 6',
[{'CHEM120': 1, 'MATH101H': 1, 'MATH101': 2, 'PHYS110': 3},
{'MATH101': 90, 'MATH101H': 90, 'PHYS110': 180, 'CHEM120': 180}, [120, 120, 120, 180],
[['exclusive', 'CHEM120', 'MATH101']]],
[['duration', 'CHEM120'], ['exclusive', 'CHEM120', 'MATH101']]),
('normal control 7',
[{'MATH101H': 2, 'PHYS110': 3, 'MATH101': 3}, {'MATH101': 120, 'MATH101H': 90, 'PHYS110': 180},
[90, 180, 120, 120], [['coincidence', 'PHYS110', 'MATH101'], ['after', 'MATH101H', 'MATH101']]],
[['duration', 'PHYS110'], ['after', 'MATH101H', 'MATH101']]),
('normal control 8',
[{'MATH101H': 2, 'PHYS110': 0, 'MATH101': 1}, {'MATH101': 180, 'MATH101H': 90, 'PHYS110': 180},
[120, 90, 180, 180], [['exclusive', 'MATH101H', 'PHYS110'], ['exclusive', 'MATH101', 'PHYS110']]],
[['duration', 'MATH101'], ['duration', 'PHYS110']])],
[('regression: after direction 1',
[{'PHYS110': 1, 'CHEM120': 0, 'MATH101': 3, 'MATH101H': 3, 'BIO130': 3},
{'MATH101': 120, 'MATH101H': 120, 'PHYS110': 180, 'CHEM120': 90, 'BIO130': 180}, [90, 90, 90, 180],
[['after', 'MATH101', 'MATH101H'], ['exclusion', 'CHEM120', 'BIO130']]],
[['duration', 'PHYS110'], ['after', 'MATH101', 'MATH101H']]),
('regression variant: after direction 2',
[{'MATH101': 2, 'PHYS110': 3, 'MATH101H': 3, 'CHEM120': 3},
{'MATH101': 90, 'MATH101H': 90, 'PHYS110': 90, 'CHEM120': 120}, [90, 120, 90, 90],
[['after', 'MATH101H', 'PHYS110'], ['after', 'MATH101H', 'CHEM120'],
['exclusive', 'PHYS110', 'MATH101']]],
[['duration', 'CHEM120'], ['after', 'MATH101H', 'PHYS110'], ['after', 'MATH101H', 'CHEM120'],
['exclusive', 'PHYS110', 'MATH101']]),
('partial repair guard 3',
[{'MATH101': 3, 'HIST140': 2, 'MATH101H': 0, 'PHYS110': 1, 'BIO130': 1, 'CHEM120': 0},
{'MATH101': 90, 'MATH101H': 90, 'PHYS110': 90, 'CHEM120': 180, 'BIO130': 180, 'HIST140': 180},
[180, 90, 180, 120],
[['after', 'CHEM120', 'BIO130'], ['after', 'MATH101', 'CHEM120'], ['coincidence', 'BIO130', 'MATH101H']]],
[['duration', 'BIO130'], ['after', 'CHEM120', 'BIO130'], ['coincidence', 'BIO130', 'MATH101H']]),
('boundary control 4', [{'A': 1, 'B': 1}, {'A': 90, 'B': 90}, [90, 120], [['after', 'A', 'B']]],
[['after', 'A', 'B']]),
('normal control 5',
[{'CHEM120': 0, 'MATH101H': 1, 'MATH101': 2, 'HIST140': 3, 'BIO130': 3, 'PHYS110': 1},
{'MATH101': 90, 'MATH101H': 120, 'PHYS110': 180, 'CHEM120': 90, 'BIO130': 90, 'HIST140': 180},
[180, 90, 120, 90], [['exclusive', 'HIST140', 'BIO130']]],
[['duration', 'HIST140'], ['duration', 'MATH101H'], ['duration', 'PHYS110'],
['exclusive', 'HIST140', 'BIO130']]),
('normal control 6',
[{'MATH101H': 2, 'PHYS110': 1, 'MATH101': 1}, {'MATH101': 120, 'MATH101H': 90, 'PHYS110': 90},
[180, 120, 90, 120],
[['exclusion', 'PHYS110', 'MATH101'], ['exclusion', 'MATH101H', 'MATH101'],
['exclusive', 'PHYS110', 'MATH101'], ['after', 'PHYS110', 'MATH101H']]],
[['exclusion', 'PHYS110', 'MATH101'], ['exclusive', 'PHYS110', 'MATH101'],
['after', 'PHYS110', 'MATH101H']]),
('normal control 7',
[{'MATH101': 2, 'CHEM120': 3, 'MATH101H': 3, 'PHYS110': 3},
{'MATH101': 120, 'MATH101H': 180, 'PHYS110': 180, 'CHEM120': 180}, [90, 120, 180, 90],
[['coincidence', 'MATH101H', 'CHEM120'], ['exclusion', 'PHYS110', 'MATH101']]],
[['duration', 'CHEM120'], ['duration', 'MATH101H'], ['duration', 'PHYS110']]),
('normal control 8',
[{'PHYS110': 3, 'MATH101H': 3, 'BIO130': 1, 'CHEM120': 2, 'HIST140': 0, 'MATH101': 1},
{'MATH101': 180, 'MATH101H': 90, 'PHYS110': 120, 'CHEM120': 90, 'BIO130': 180, 'HIST140': 120},
[120, 120, 120, 180],
[['after', 'MATH101H', 'BIO130'], ['exclusive', 'CHEM120', 'MATH101H'], ['after', 'BIO130', 'PHYS110']]],
[['duration', 'BIO130'], ['duration', 'MATH101'], ['after', 'BIO130', 'PHYS110']])]]
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: after direction 1 | [] | [['after', 'A', 'B']] | Failed |
| regression variant: after direction 2 | [['duration', 'MATH101'], ['duration', 'PHYS110']] | [['duration', 'MATH101'], ['duration', 'PHYS110'], ['after', 'MATH101H', 'PHYS110'], ['after', 'MATH101H', 'PHYS110']] | Failed |
| partial repair guard 3 | [['coincidence', 'MATH101', 'PHYS110'], ['exclusive', 'PHYS110', 'MATH101H'], ['after', 'PHYS110', 'MATH101'], ['coincidence', 'MATH101H', 'MATH101']] | [['coincidence', 'MATH101', 'PHYS110'], ['exclusive', 'PHYS110', 'MATH101H'], ['after', 'PHYS110', 'MATH101'], ['coincidence', 'MATH101H', 'MATH101']] | Passed |
| boundary control 4 | [] | [] | Passed |
| normal control 5 | [['duration', 'MATH101H'], ['duration', 'PHYS110'], ['coincidence', 'MATH101', 'PHYS110'], ['coincidence', 'PHYS110', 'MATH101'], ['after', 'CHEM120', 'MATH101']] | [['duration', 'MATH101H'], ['duration', 'PHYS110'], ['coincidence', 'MATH101', 'PHYS110'], ['coincidence', 'PHYS110', 'MATH101'], ['after', 'CHEM120', 'MATH101']] | Passed |
| normal control 6 | [['duration', 'MATH101'], ['coincidence', 'CHEM120', 'MATH101H'], ['coincidence', 'MATH101H', 'CHEM120']] | [['duration', 'MATH101'], ['after', 'MATH101', 'MATH101H'], ['coincidence', 'CHEM120', 'MATH101H'], ['coincidence', 'MATH101H', 'CHEM120']] | Failed |
| normal control 7 | [['duration', 'BIO130']] | [['duration', 'BIO130']] | Passed |
| normal control 8 | [['duration', 'CHEM120'], ['coincidence', 'CHEM120', 'MATH101H'], ['exclusive', 'CHEM120', 'MATH101'], ['coincidence', 'HIST140', 'MATH101']] | [['duration', 'CHEM120'], ['coincidence', 'CHEM120', 'MATH101H'], ['exclusive', 'CHEM120', 'MATH101'], ['coincidence', 'HIST140', 'MATH101']] | Passed |
SHA-256 / d01f01677c6b3f8ce09f786becae0f5007ddce4dd9c54f639ac86a266c646a8c
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(timetable, exams, periods, cons):
out = []
for e in sorted(timetable):
if exams[e] > periods[timetable[e]]:
out.append(['duration', e])
for kind, a, b in cons:
pa, pb = timetable[a], timetable[b]
if kind == 'after' and not pb > pa:
out.append([kind, a, b])
elif kind == 'exclusion' and pa == pb:
out.append([kind, a, b])
elif kind == 'coincidence' and pa != pb:
out.append([kind, a, b])
elif kind == 'exclusive' and sum(1 for e in timetable if timetable[e] == pa) > 1:
out.append([kind, a, b])
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: after direction 1', [{'A': 1, 'B': 1}, {'A': 90, 'B': 90}, [90, 120], [['after', 'A', 'B']]],
[['after', 'A', 'B']]),
('regression variant: after direction 2',
[{'MATH101H': 3, 'MATH101': 3, 'PHYS110': 3}, {'MATH101': 180, 'MATH101H': 90, 'PHYS110': 180},
[180, 90, 120, 90], [['after', 'MATH101H', 'PHYS110'], ['after', 'MATH101H', 'PHYS110']]],
[['duration', 'MATH101'], ['duration', 'PHYS110'], ['after', 'MATH101H', 'PHYS110'],
['after', 'MATH101H', 'PHYS110']]),
('partial repair guard 3',
[{'MATH101': 2, 'PHYS110': 0, 'MATH101H': 0}, {'MATH101': 120, 'MATH101H': 120, 'PHYS110': 90},
[120, 90, 180, 180],
[['coincidence', 'MATH101', 'PHYS110'], ['exclusive', 'PHYS110', 'MATH101H'],
['after', 'PHYS110', 'MATH101'], ['coincidence', 'MATH101H', 'MATH101']]],
[['coincidence', 'MATH101', 'PHYS110'], ['exclusive', 'PHYS110', 'MATH101H'],
['after', 'PHYS110', 'MATH101'], ['coincidence', 'MATH101H', 'MATH101']]),
('boundary control 4', [{'A': 1, 'B': 0}, {'A': 120, 'B': 90}, [90, 120], [['exclusive', 'A', 'B']]], []),
('normal control 5',
[{'PHYS110': 0, 'MATH101': 2, 'MATH101H': 0, 'CHEM120': 1},
{'MATH101': 90, 'MATH101H': 180, 'PHYS110': 180, 'CHEM120': 90}, [90, 120, 120, 120],
[['coincidence', 'MATH101', 'PHYS110'], ['coincidence', 'PHYS110', 'MATH101'],
['after', 'CHEM120', 'MATH101'], ['exclusive', 'CHEM120', 'MATH101']]],
[['duration', 'MATH101H'], ['duration', 'PHYS110'], ['coincidence', 'MATH101', 'PHYS110'],
['coincidence', 'PHYS110', 'MATH101'], ['after', 'CHEM120', 'MATH101']]),
('normal control 6',
[{'PHYS110': 1, 'MATH101': 0, 'CHEM120': 3, 'MATH101H': 0},
{'MATH101': 180, 'MATH101H': 90, 'PHYS110': 120, 'CHEM120': 120}, [90, 120, 120, 120],
[['after', 'MATH101', 'MATH101H'], ['after', 'CHEM120', 'MATH101H'],
['coincidence', 'CHEM120', 'MATH101H'], ['coincidence', 'MATH101H', 'CHEM120']]],
[['duration', 'MATH101'], ['after', 'MATH101', 'MATH101H'], ['coincidence', 'CHEM120', 'MATH101H'],
['coincidence', 'MATH101H', 'CHEM120']]),
('normal control 7',
[{'MATH101H': 1, 'HIST140': 3, 'PHYS110': 2, 'BIO130': 3, 'CHEM120': 1, 'MATH101': 2},
{'MATH101': 180, 'MATH101H': 180, 'PHYS110': 90, 'CHEM120': 90, 'BIO130': 120, 'HIST140': 90},
[180, 180, 180, 90], [['after', 'BIO130', 'PHYS110'], ['exclusion', 'CHEM120', 'MATH101']]],
[['duration', 'BIO130']]),
('normal control 8',
[{'CHEM120': 0, 'PHYS110': 2, 'MATH101H': 2, 'MATH101': 2, 'HIST140': 0, 'BIO130': 1},
{'MATH101': 90, 'MATH101H': 90, 'PHYS110': 90, 'CHEM120': 120, 'BIO130': 120, 'HIST140': 90},
[90, 120, 180, 120],
[['exclusion', 'BIO130', 'MATH101'], ['coincidence', 'CHEM120', 'MATH101H'],
['exclusive', 'CHEM120', 'MATH101'], ['coincidence', 'HIST140', 'MATH101']]],
[['duration', 'CHEM120'], ['coincidence', 'CHEM120', 'MATH101H'], ['exclusive', 'CHEM120', 'MATH101'],
['coincidence', 'HIST140', 'MATH101']])],
[('regression: after direction 1',
[{'BIO130': 0, 'PHYS110': 3, 'MATH101': 1, 'CHEM120': 0, 'MATH101H': 1},
{'MATH101': 180, 'MATH101H': 120, 'PHYS110': 180, 'CHEM120': 90, 'BIO130': 90}, [120, 120, 180, 90],
[['coincidence', 'CHEM120', 'BIO130'], ['after', 'CHEM120', 'BIO130'],
['exclusive', 'MATH101H', 'MATH101']]],
[['duration', 'MATH101'], ['duration', 'PHYS110'], ['after', 'CHEM120', 'BIO130'],
['exclusive', 'MATH101H', 'MATH101']]),
('regression variant: after direction 2',
[{'PHYS110': 3, 'MATH101': 3, 'MATH101H': 3}, {'MATH101': 120, 'MATH101H': 120, 'PHYS110': 90},
[120, 120, 180, 180],
[['coincidence', 'PHYS110', 'MATH101H'], ['exclusion', 'MATH101H', 'PHYS110'],
['after', 'MATH101', 'PHYS110'], ['exclusive', 'MATH101', 'MATH101H']]],
[['exclusion', 'MATH101H', 'PHYS110'], ['after', 'MATH101', 'PHYS110'],
['exclusive', 'MATH101', 'MATH101H']]),
('partial repair guard 3',
[{'MATH101': 0, 'MATH101H': 1, 'PHYS110': 3}, {'MATH101': 180, 'MATH101H': 90, 'PHYS110': 120},
[120, 90, 90, 180],
[['after', 'PHYS110', 'MATH101H'], ['exclusive', 'MATH101', 'PHYS110'],
['coincidence', 'MATH101', 'MATH101H']]],
[['duration', 'MATH101'], ['coincidence', 'MATH101', 'MATH101H']]),
('boundary control 4', [{'A': 2, 'B': 1}, {'A': 90, 'B': 90}, [90, 120, 120], [['after', 'A', 'B']]], []),
('normal control 5',
[{'MATH101': 1, 'PHYS110': 2, 'HIST140': 1, 'BIO130': 2, 'CHEM120': 1, 'MATH101H': 1},
{'MATH101': 90, 'MATH101H': 120, 'PHYS110': 90, 'CHEM120': 120, 'BIO130': 180, 'HIST140': 120},
[90, 120, 180, 120], [['exclusive', 'HIST140', 'PHYS110']]],
[['exclusive', 'HIST140', 'PHYS110']]),
('normal control 6',
[{'MATH101H': 3, 'CHEM120': 1, 'PHYS110': 0, 'MATH101': 1, 'BIO130': 0},
{'MATH101': 90, 'MATH101H': 120, 'PHYS110': 180, 'CHEM120': 180, 'BIO130': 90}, [90, 90, 120, 180],
[['after', 'MATH101H', 'PHYS110']]],
[['duration', 'CHEM120'], ['duration', 'PHYS110']]),
('normal control 7',
[{'MATH101': 3, 'BIO130': 1, 'PHYS110': 0, 'CHEM120': 2, 'MATH101H': 2, 'HIST140': 2},
{'MATH101': 90, 'MATH101H': 120, 'PHYS110': 90, 'CHEM120': 180, 'BIO130': 180, 'HIST140': 180},
[180, 90, 180, 120], [['after', 'HIST140', 'MATH101H'], ['coincidence', 'PHYS110', 'MATH101H']]],
[['duration', 'BIO130'], ['after', 'HIST140', 'MATH101H'], ['coincidence', 'PHYS110', 'MATH101H']]),
('normal control 8',
[{'MATH101H': 3, 'MATH101': 3, 'PHYS110': 3}, {'MATH101': 90, 'MATH101H': 180, 'PHYS110': 90},
[90, 180, 90, 90],
[['after', 'MATH101H', 'PHYS110'], ['coincidence', 'PHYS110', 'MATH101H'],
['coincidence', 'MATH101H', 'MATH101']]],
[['duration', 'MATH101H'], ['after', 'MATH101H', 'PHYS110']])],
[('regression: after direction 1',
[{'PHYS110': 3, 'CHEM120': 1, 'MATH101': 1, 'MATH101H': 1},
{'MATH101': 120, 'MATH101H': 120, 'PHYS110': 180, 'CHEM120': 90}, [180, 120, 120, 90],
[['after', 'MATH101', 'CHEM120'], ['exclusive', 'MATH101', 'CHEM120']]],
[['duration', 'PHYS110'], ['after', 'MATH101', 'CHEM120'], ['exclusive', 'MATH101', 'CHEM120']]),
('regression variant: after direction 2',
[{'CHEM120': 3, 'BIO130': 3, 'MATH101': 2, 'HIST140': 2, 'PHYS110': 0, 'MATH101H': 0},
{'MATH101': 180, 'MATH101H': 180, 'PHYS110': 90, 'CHEM120': 180, 'BIO130': 180, 'HIST140': 180},
[90, 180, 90, 120],
[['after', 'BIO130', 'CHEM120'], ['exclusion', 'MATH101H', 'PHYS110'],
['coincidence', 'MATH101', 'PHYS110'], ['exclusion', 'MATH101', 'PHYS110']]],
[['duration', 'BIO130'], ['duration', 'CHEM120'], ['duration', 'HIST140'], ['duration', 'MATH101'],
['duration', 'MATH101H'], ['after', 'BIO130', 'CHEM120'], ['exclusion', 'MATH101H', 'PHYS110'],
['coincidence', 'MATH101', 'PHYS110']]),
('partial repair guard 3',
[{'PHYS110': 3, 'CHEM120': 0, 'MATH101': 3, 'MATH101H': 2},
{'MATH101': 120, 'MATH101H': 90, 'PHYS110': 180, 'CHEM120': 180}, [120, 120, 90, 120],
[['coincidence', 'CHEM120', 'PHYS110'], ['coincidence', 'MATH101H', 'MATH101'],
['after', 'MATH101H', 'MATH101']]],
[['duration', 'CHEM120'], ['duration', 'PHYS110'], ['coincidence', 'CHEM120', 'PHYS110'],
['coincidence', 'MATH101H', 'MATH101'], ['after', 'MATH101H', 'MATH101']]),
('boundary control 4', [{'B': 0, 'A': 1}, {'A': 180, 'B': 180}, [120, 120], []],
[['duration', 'A'], ['duration', 'B']]),
('normal control 5',
[{'MATH101H': 3, 'MATH101': 1, 'CHEM120': 0, 'PHYS110': 0},
{'MATH101': 90, 'MATH101H': 180, 'PHYS110': 90, 'CHEM120': 90}, [180, 90, 180, 180],
[['exclusive', 'MATH101H', 'CHEM120']]],
[]),
('normal control 6',
[{'MATH101': 0, 'PHYS110': 1, 'MATH101H': 2}, {'MATH101': 90, 'MATH101H': 180, 'PHYS110': 90},
[180, 90, 120, 90], [['exclusive', 'MATH101H', 'PHYS110']]],
[['duration', 'MATH101H']]),
('normal control 7',
[{'MATH101H': 2, 'CHEM120': 1, 'BIO130': 3, 'MATH101': 3, 'PHYS110': 2},
{'MATH101': 120, 'MATH101H': 180, 'PHYS110': 120, 'CHEM120': 120, 'BIO130': 120}, [120, 120, 120, 90],
[['exclusion', 'CHEM120', 'MATH101'], ['after', 'MATH101H', 'MATH101'], ['after', 'CHEM120', 'MATH101H'],
['coincidence', 'PHYS110', 'MATH101H']]],
[['duration', 'BIO130'], ['duration', 'MATH101'], ['duration', 'MATH101H'],
['after', 'MATH101H', 'MATH101'], ['after', 'CHEM120', 'MATH101H']]),
('normal control 8',
[{'MATH101H': 0, 'MATH101': 0, 'PHYS110': 3}, {'MATH101': 180, 'MATH101H': 120, 'PHYS110': 180},
[180, 90, 120, 90],
[['coincidence', 'PHYS110', 'MATH101H'], ['exclusive', 'MATH101', 'PHYS110'],
['after', 'PHYS110', 'MATH101H']]],
[['duration', 'PHYS110'], ['coincidence', 'PHYS110', 'MATH101H'], ['exclusive', 'MATH101', 'PHYS110']])],
[('regression: after direction 1',
[{'CHEM120': 3, 'HIST140': 0, 'PHYS110': 1, 'BIO130': 3, 'MATH101': 0, 'MATH101H': 2},
{'MATH101': 120, 'MATH101H': 120, 'PHYS110': 90, 'CHEM120': 120, 'BIO130': 120, 'HIST140': 180},
[90, 90, 90, 90],
[['exclusion', 'HIST140', 'BIO130'], ['exclusion', 'MATH101', 'MATH101H'],
['exclusive', 'BIO130', 'MATH101H'], ['after', 'HIST140', 'MATH101']]],
[['duration', 'BIO130'], ['duration', 'CHEM120'], ['duration', 'HIST140'], ['duration', 'MATH101'],
['duration', 'MATH101H'], ['exclusive', 'BIO130', 'MATH101H'], ['after', 'HIST140', 'MATH101']]),
('regression variant: after direction 2',
[{'MATH101': 1, 'MATH101H': 1, 'PHYS110': 0}, {'MATH101': 90, 'MATH101H': 90, 'PHYS110': 90},
[180, 90, 120, 180],
[['after', 'MATH101', 'MATH101H'], ['exclusion', 'PHYS110', 'MATH101'],
['coincidence', 'PHYS110', 'MATH101'], ['exclusive', 'PHYS110', 'MATH101H']]],
[['after', 'MATH101', 'MATH101H'], ['coincidence', 'PHYS110', 'MATH101']]),
('partial repair guard 3',
[{'BIO130': 1, 'PHYS110': 0, 'MATH101': 0, 'MATH101H': 1, 'CHEM120': 2},
{'MATH101': 120, 'MATH101H': 180, 'PHYS110': 120, 'CHEM120': 120, 'BIO130': 180}, [90, 90, 90, 120],
[['exclusive', 'MATH101', 'BIO130'], ['after', 'PHYS110', 'MATH101H'],
['exclusion', 'MATH101', 'PHYS110'], ['after', 'PHYS110', 'BIO130']]],
[['duration', 'BIO130'], ['duration', 'CHEM120'], ['duration', 'MATH101'], ['duration', 'MATH101H'],
['duration', 'PHYS110'], ['exclusive', 'MATH101', 'BIO130'], ['after', 'PHYS110', 'MATH101H'],
['exclusion', 'MATH101', 'PHYS110'], ['after', 'PHYS110', 'BIO130']]),
('boundary control 4', [{'A': 0}, {'A': 120}, [120], []], []),
('normal control 5',
[{'HIST140': 1, 'MATH101H': 3, 'BIO130': 3, 'MATH101': 1, 'CHEM120': 3, 'PHYS110': 1},
{'MATH101': 90, 'MATH101H': 90, 'PHYS110': 90, 'CHEM120': 120, 'BIO130': 120, 'HIST140': 180},
[180, 120, 180, 90], [['exclusion', 'MATH101H', 'PHYS110']]],
[['duration', 'BIO130'], ['duration', 'CHEM120'], ['duration', 'HIST140']]),
('normal control 6',
[{'CHEM120': 1, 'MATH101H': 1, 'MATH101': 2, 'PHYS110': 3},
{'MATH101': 90, 'MATH101H': 90, 'PHYS110': 180, 'CHEM120': 180}, [120, 120, 120, 180],
[['exclusive', 'CHEM120', 'MATH101']]],
[['duration', 'CHEM120'], ['exclusive', 'CHEM120', 'MATH101']]),
('normal control 7',
[{'MATH101H': 2, 'PHYS110': 3, 'MATH101': 3}, {'MATH101': 120, 'MATH101H': 90, 'PHYS110': 180},
[90, 180, 120, 120], [['coincidence', 'PHYS110', 'MATH101'], ['after', 'MATH101H', 'MATH101']]],
[['duration', 'PHYS110'], ['after', 'MATH101H', 'MATH101']]),
('normal control 8',
[{'MATH101H': 2, 'PHYS110': 0, 'MATH101': 1}, {'MATH101': 180, 'MATH101H': 90, 'PHYS110': 180},
[120, 90, 180, 180], [['exclusive', 'MATH101H', 'PHYS110'], ['exclusive', 'MATH101', 'PHYS110']]],
[['duration', 'MATH101'], ['duration', 'PHYS110']])],
[('regression: after direction 1',
[{'PHYS110': 1, 'CHEM120': 0, 'MATH101': 3, 'MATH101H': 3, 'BIO130': 3},
{'MATH101': 120, 'MATH101H': 120, 'PHYS110': 180, 'CHEM120': 90, 'BIO130': 180}, [90, 90, 90, 180],
[['after', 'MATH101', 'MATH101H'], ['exclusion', 'CHEM120', 'BIO130']]],
[['duration', 'PHYS110'], ['after', 'MATH101', 'MATH101H']]),
('regression variant: after direction 2',
[{'MATH101': 2, 'PHYS110': 3, 'MATH101H': 3, 'CHEM120': 3},
{'MATH101': 90, 'MATH101H': 90, 'PHYS110': 90, 'CHEM120': 120}, [90, 120, 90, 90],
[['after', 'MATH101H', 'PHYS110'], ['after', 'MATH101H', 'CHEM120'],
['exclusive', 'PHYS110', 'MATH101']]],
[['duration', 'CHEM120'], ['after', 'MATH101H', 'PHYS110'], ['after', 'MATH101H', 'CHEM120'],
['exclusive', 'PHYS110', 'MATH101']]),
('partial repair guard 3',
[{'MATH101': 3, 'HIST140': 2, 'MATH101H': 0, 'PHYS110': 1, 'BIO130': 1, 'CHEM120': 0},
{'MATH101': 90, 'MATH101H': 90, 'PHYS110': 90, 'CHEM120': 180, 'BIO130': 180, 'HIST140': 180},
[180, 90, 180, 120],
[['after', 'CHEM120', 'BIO130'], ['after', 'MATH101', 'CHEM120'], ['coincidence', 'BIO130', 'MATH101H']]],
[['duration', 'BIO130'], ['after', 'CHEM120', 'BIO130'], ['coincidence', 'BIO130', 'MATH101H']]),
('boundary control 4', [{'A': 1, 'B': 1}, {'A': 90, 'B': 90}, [90, 120], [['after', 'A', 'B']]],
[['after', 'A', 'B']]),
('normal control 5',
[{'CHEM120': 0, 'MATH101H': 1, 'MATH101': 2, 'HIST140': 3, 'BIO130': 3, 'PHYS110': 1},
{'MATH101': 90, 'MATH101H': 120, 'PHYS110': 180, 'CHEM120': 90, 'BIO130': 90, 'HIST140': 180},
[180, 90, 120, 90], [['exclusive', 'HIST140', 'BIO130']]],
[['duration', 'HIST140'], ['duration', 'MATH101H'], ['duration', 'PHYS110'],
['exclusive', 'HIST140', 'BIO130']]),
('normal control 6',
[{'MATH101H': 2, 'PHYS110': 1, 'MATH101': 1}, {'MATH101': 120, 'MATH101H': 90, 'PHYS110': 90},
[180, 120, 90, 120],
[['exclusion', 'PHYS110', 'MATH101'], ['exclusion', 'MATH101H', 'MATH101'],
['exclusive', 'PHYS110', 'MATH101'], ['after', 'PHYS110', 'MATH101H']]],
[['exclusion', 'PHYS110', 'MATH101'], ['exclusive', 'PHYS110', 'MATH101'],
['after', 'PHYS110', 'MATH101H']]),
('normal control 7',
[{'MATH101': 2, 'CHEM120': 3, 'MATH101H': 3, 'PHYS110': 3},
{'MATH101': 120, 'MATH101H': 180, 'PHYS110': 180, 'CHEM120': 180}, [90, 120, 180, 90],
[['coincidence', 'MATH101H', 'CHEM120'], ['exclusion', 'PHYS110', 'MATH101']]],
[['duration', 'CHEM120'], ['duration', 'MATH101H'], ['duration', 'PHYS110']]),
('normal control 8',
[{'PHYS110': 3, 'MATH101H': 3, 'BIO130': 1, 'CHEM120': 2, 'HIST140': 0, 'MATH101': 1},
{'MATH101': 180, 'MATH101H': 90, 'PHYS110': 120, 'CHEM120': 90, 'BIO130': 180, 'HIST140': 120},
[120, 120, 120, 180],
[['after', 'MATH101H', 'BIO130'], ['exclusive', 'CHEM120', 'MATH101H'], ['after', 'BIO130', 'PHYS110']]],
[['duration', 'BIO130'], ['duration', 'MATH101'], ['after', 'BIO130', 'PHYS110']])]]
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: after direction 1 | [['after', 'A', 'B']] | [['after', 'A', 'B']] | Passed |
| regression variant: after direction 2 | [['duration', 'MATH101'], ['duration', 'PHYS110'], ['after', 'MATH101H', 'PHYS110'], ['after', 'MATH101H', 'PHYS110']] | [['duration', 'MATH101'], ['duration', 'PHYS110'], ['after', 'MATH101H', 'PHYS110'], ['after', 'MATH101H', 'PHYS110']] | Passed |
| partial repair guard 3 | [['coincidence', 'MATH101', 'PHYS110'], ['exclusive', 'PHYS110', 'MATH101H'], ['coincidence', 'MATH101H', 'MATH101']] | [['coincidence', 'MATH101', 'PHYS110'], ['exclusive', 'PHYS110', 'MATH101H'], ['after', 'PHYS110', 'MATH101'], ['coincidence', 'MATH101H', 'MATH101']] | Failed |
| boundary control 4 | [] | [] | Passed |
| normal control 5 | [['duration', 'MATH101H'], ['duration', 'PHYS110'], ['coincidence', 'MATH101', 'PHYS110'], ['coincidence', 'PHYS110', 'MATH101']] | [['duration', 'MATH101H'], ['duration', 'PHYS110'], ['coincidence', 'MATH101', 'PHYS110'], ['coincidence', 'PHYS110', 'MATH101'], ['after', 'CHEM120', 'MATH101']] | Failed |
| normal control 6 | [['duration', 'MATH101'], ['after', 'MATH101', 'MATH101H'], ['after', 'CHEM120', 'MATH101H'], ['coincidence', 'CHEM120', 'MATH101H'], ['coincidence', 'MATH101H', 'CHEM120']] | [['duration', 'MATH101'], ['after', 'MATH101', 'MATH101H'], ['coincidence', 'CHEM120', 'MATH101H'], ['coincidence', 'MATH101H', 'CHEM120']] | Failed |
| normal control 7 | [['duration', 'BIO130'], ['after', 'BIO130', 'PHYS110']] | [['duration', 'BIO130']] | Failed |
| normal control 8 | [['duration', 'CHEM120'], ['coincidence', 'CHEM120', 'MATH101H'], ['exclusive', 'CHEM120', 'MATH101'], ['coincidence', 'HIST140', 'MATH101']] | [['duration', 'CHEM120'], ['coincidence', 'CHEM120', 'MATH101H'], ['exclusive', 'CHEM120', 'MATH101'], ['coincidence', 'HIST140', 'MATH101']] | Passed |
SHA-256 / 230ea6b4d26e661a7a4931e658899c90bc205a51738ffacfff2ad623dea2d94d
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(timetable, exams, periods, cons):
out = []
for e in sorted(timetable):
if exams[e] > periods[timetable[e]]:
out.append(['duration', e])
for kind, a, b in cons:
pa, pb = timetable[a], timetable[b]
if kind == 'after' and not pa > pb:
out.append([kind, a, b])
elif kind == 'exclusion' and pa == pb:
out.append([kind, a, b])
elif kind == 'coincidence' and pa != pb:
out.append([kind, a, b])
elif kind == 'exclusive' and sum(1 for e in timetable if timetable[e] == pa) > 1:
out.append([kind, a, b])
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: after direction 1', [{'A': 1, 'B': 1}, {'A': 90, 'B': 90}, [90, 120], [['after', 'A', 'B']]],
[['after', 'A', 'B']]),
('regression variant: after direction 2',
[{'MATH101H': 3, 'MATH101': 3, 'PHYS110': 3}, {'MATH101': 180, 'MATH101H': 90, 'PHYS110': 180},
[180, 90, 120, 90], [['after', 'MATH101H', 'PHYS110'], ['after', 'MATH101H', 'PHYS110']]],
[['duration', 'MATH101'], ['duration', 'PHYS110'], ['after', 'MATH101H', 'PHYS110'],
['after', 'MATH101H', 'PHYS110']]),
('partial repair guard 3',
[{'MATH101': 2, 'PHYS110': 0, 'MATH101H': 0}, {'MATH101': 120, 'MATH101H': 120, 'PHYS110': 90},
[120, 90, 180, 180],
[['coincidence', 'MATH101', 'PHYS110'], ['exclusive', 'PHYS110', 'MATH101H'],
['after', 'PHYS110', 'MATH101'], ['coincidence', 'MATH101H', 'MATH101']]],
[['coincidence', 'MATH101', 'PHYS110'], ['exclusive', 'PHYS110', 'MATH101H'],
['after', 'PHYS110', 'MATH101'], ['coincidence', 'MATH101H', 'MATH101']]),
('boundary control 4', [{'A': 1, 'B': 0}, {'A': 120, 'B': 90}, [90, 120], [['exclusive', 'A', 'B']]], []),
('normal control 5',
[{'PHYS110': 0, 'MATH101': 2, 'MATH101H': 0, 'CHEM120': 1},
{'MATH101': 90, 'MATH101H': 180, 'PHYS110': 180, 'CHEM120': 90}, [90, 120, 120, 120],
[['coincidence', 'MATH101', 'PHYS110'], ['coincidence', 'PHYS110', 'MATH101'],
['after', 'CHEM120', 'MATH101'], ['exclusive', 'CHEM120', 'MATH101']]],
[['duration', 'MATH101H'], ['duration', 'PHYS110'], ['coincidence', 'MATH101', 'PHYS110'],
['coincidence', 'PHYS110', 'MATH101'], ['after', 'CHEM120', 'MATH101']]),
('normal control 6',
[{'PHYS110': 1, 'MATH101': 0, 'CHEM120': 3, 'MATH101H': 0},
{'MATH101': 180, 'MATH101H': 90, 'PHYS110': 120, 'CHEM120': 120}, [90, 120, 120, 120],
[['after', 'MATH101', 'MATH101H'], ['after', 'CHEM120', 'MATH101H'],
['coincidence', 'CHEM120', 'MATH101H'], ['coincidence', 'MATH101H', 'CHEM120']]],
[['duration', 'MATH101'], ['after', 'MATH101', 'MATH101H'], ['coincidence', 'CHEM120', 'MATH101H'],
['coincidence', 'MATH101H', 'CHEM120']]),
('normal control 7',
[{'MATH101H': 1, 'HIST140': 3, 'PHYS110': 2, 'BIO130': 3, 'CHEM120': 1, 'MATH101': 2},
{'MATH101': 180, 'MATH101H': 180, 'PHYS110': 90, 'CHEM120': 90, 'BIO130': 120, 'HIST140': 90},
[180, 180, 180, 90], [['after', 'BIO130', 'PHYS110'], ['exclusion', 'CHEM120', 'MATH101']]],
[['duration', 'BIO130']]),
('normal control 8',
[{'CHEM120': 0, 'PHYS110': 2, 'MATH101H': 2, 'MATH101': 2, 'HIST140': 0, 'BIO130': 1},
{'MATH101': 90, 'MATH101H': 90, 'PHYS110': 90, 'CHEM120': 120, 'BIO130': 120, 'HIST140': 90},
[90, 120, 180, 120],
[['exclusion', 'BIO130', 'MATH101'], ['coincidence', 'CHEM120', 'MATH101H'],
['exclusive', 'CHEM120', 'MATH101'], ['coincidence', 'HIST140', 'MATH101']]],
[['duration', 'CHEM120'], ['coincidence', 'CHEM120', 'MATH101H'], ['exclusive', 'CHEM120', 'MATH101'],
['coincidence', 'HIST140', 'MATH101']])],
[('regression: after direction 1',
[{'BIO130': 0, 'PHYS110': 3, 'MATH101': 1, 'CHEM120': 0, 'MATH101H': 1},
{'MATH101': 180, 'MATH101H': 120, 'PHYS110': 180, 'CHEM120': 90, 'BIO130': 90}, [120, 120, 180, 90],
[['coincidence', 'CHEM120', 'BIO130'], ['after', 'CHEM120', 'BIO130'],
['exclusive', 'MATH101H', 'MATH101']]],
[['duration', 'MATH101'], ['duration', 'PHYS110'], ['after', 'CHEM120', 'BIO130'],
['exclusive', 'MATH101H', 'MATH101']]),
('regression variant: after direction 2',
[{'PHYS110': 3, 'MATH101': 3, 'MATH101H': 3}, {'MATH101': 120, 'MATH101H': 120, 'PHYS110': 90},
[120, 120, 180, 180],
[['coincidence', 'PHYS110', 'MATH101H'], ['exclusion', 'MATH101H', 'PHYS110'],
['after', 'MATH101', 'PHYS110'], ['exclusive', 'MATH101', 'MATH101H']]],
[['exclusion', 'MATH101H', 'PHYS110'], ['after', 'MATH101', 'PHYS110'],
['exclusive', 'MATH101', 'MATH101H']]),
('partial repair guard 3',
[{'MATH101': 0, 'MATH101H': 1, 'PHYS110': 3}, {'MATH101': 180, 'MATH101H': 90, 'PHYS110': 120},
[120, 90, 90, 180],
[['after', 'PHYS110', 'MATH101H'], ['exclusive', 'MATH101', 'PHYS110'],
['coincidence', 'MATH101', 'MATH101H']]],
[['duration', 'MATH101'], ['coincidence', 'MATH101', 'MATH101H']]),
('boundary control 4', [{'A': 2, 'B': 1}, {'A': 90, 'B': 90}, [90, 120, 120], [['after', 'A', 'B']]], []),
('normal control 5',
[{'MATH101': 1, 'PHYS110': 2, 'HIST140': 1, 'BIO130': 2, 'CHEM120': 1, 'MATH101H': 1},
{'MATH101': 90, 'MATH101H': 120, 'PHYS110': 90, 'CHEM120': 120, 'BIO130': 180, 'HIST140': 120},
[90, 120, 180, 120], [['exclusive', 'HIST140', 'PHYS110']]],
[['exclusive', 'HIST140', 'PHYS110']]),
('normal control 6',
[{'MATH101H': 3, 'CHEM120': 1, 'PHYS110': 0, 'MATH101': 1, 'BIO130': 0},
{'MATH101': 90, 'MATH101H': 120, 'PHYS110': 180, 'CHEM120': 180, 'BIO130': 90}, [90, 90, 120, 180],
[['after', 'MATH101H', 'PHYS110']]],
[['duration', 'CHEM120'], ['duration', 'PHYS110']]),
('normal control 7',
[{'MATH101': 3, 'BIO130': 1, 'PHYS110': 0, 'CHEM120': 2, 'MATH101H': 2, 'HIST140': 2},
{'MATH101': 90, 'MATH101H': 120, 'PHYS110': 90, 'CHEM120': 180, 'BIO130': 180, 'HIST140': 180},
[180, 90, 180, 120], [['after', 'HIST140', 'MATH101H'], ['coincidence', 'PHYS110', 'MATH101H']]],
[['duration', 'BIO130'], ['after', 'HIST140', 'MATH101H'], ['coincidence', 'PHYS110', 'MATH101H']]),
('normal control 8',
[{'MATH101H': 3, 'MATH101': 3, 'PHYS110': 3}, {'MATH101': 90, 'MATH101H': 180, 'PHYS110': 90},
[90, 180, 90, 90],
[['after', 'MATH101H', 'PHYS110'], ['coincidence', 'PHYS110', 'MATH101H'],
['coincidence', 'MATH101H', 'MATH101']]],
[['duration', 'MATH101H'], ['after', 'MATH101H', 'PHYS110']])],
[('regression: after direction 1',
[{'PHYS110': 3, 'CHEM120': 1, 'MATH101': 1, 'MATH101H': 1},
{'MATH101': 120, 'MATH101H': 120, 'PHYS110': 180, 'CHEM120': 90}, [180, 120, 120, 90],
[['after', 'MATH101', 'CHEM120'], ['exclusive', 'MATH101', 'CHEM120']]],
[['duration', 'PHYS110'], ['after', 'MATH101', 'CHEM120'], ['exclusive', 'MATH101', 'CHEM120']]),
('regression variant: after direction 2',
[{'CHEM120': 3, 'BIO130': 3, 'MATH101': 2, 'HIST140': 2, 'PHYS110': 0, 'MATH101H': 0},
{'MATH101': 180, 'MATH101H': 180, 'PHYS110': 90, 'CHEM120': 180, 'BIO130': 180, 'HIST140': 180},
[90, 180, 90, 120],
[['after', 'BIO130', 'CHEM120'], ['exclusion', 'MATH101H', 'PHYS110'],
['coincidence', 'MATH101', 'PHYS110'], ['exclusion', 'MATH101', 'PHYS110']]],
[['duration', 'BIO130'], ['duration', 'CHEM120'], ['duration', 'HIST140'], ['duration', 'MATH101'],
['duration', 'MATH101H'], ['after', 'BIO130', 'CHEM120'], ['exclusion', 'MATH101H', 'PHYS110'],
['coincidence', 'MATH101', 'PHYS110']]),
('partial repair guard 3',
[{'PHYS110': 3, 'CHEM120': 0, 'MATH101': 3, 'MATH101H': 2},
{'MATH101': 120, 'MATH101H': 90, 'PHYS110': 180, 'CHEM120': 180}, [120, 120, 90, 120],
[['coincidence', 'CHEM120', 'PHYS110'], ['coincidence', 'MATH101H', 'MATH101'],
['after', 'MATH101H', 'MATH101']]],
[['duration', 'CHEM120'], ['duration', 'PHYS110'], ['coincidence', 'CHEM120', 'PHYS110'],
['coincidence', 'MATH101H', 'MATH101'], ['after', 'MATH101H', 'MATH101']]),
('boundary control 4', [{'B': 0, 'A': 1}, {'A': 180, 'B': 180}, [120, 120], []],
[['duration', 'A'], ['duration', 'B']]),
('normal control 5',
[{'MATH101H': 3, 'MATH101': 1, 'CHEM120': 0, 'PHYS110': 0},
{'MATH101': 90, 'MATH101H': 180, 'PHYS110': 90, 'CHEM120': 90}, [180, 90, 180, 180],
[['exclusive', 'MATH101H', 'CHEM120']]],
[]),
('normal control 6',
[{'MATH101': 0, 'PHYS110': 1, 'MATH101H': 2}, {'MATH101': 90, 'MATH101H': 180, 'PHYS110': 90},
[180, 90, 120, 90], [['exclusive', 'MATH101H', 'PHYS110']]],
[['duration', 'MATH101H']]),
('normal control 7',
[{'MATH101H': 2, 'CHEM120': 1, 'BIO130': 3, 'MATH101': 3, 'PHYS110': 2},
{'MATH101': 120, 'MATH101H': 180, 'PHYS110': 120, 'CHEM120': 120, 'BIO130': 120}, [120, 120, 120, 90],
[['exclusion', 'CHEM120', 'MATH101'], ['after', 'MATH101H', 'MATH101'], ['after', 'CHEM120', 'MATH101H'],
['coincidence', 'PHYS110', 'MATH101H']]],
[['duration', 'BIO130'], ['duration', 'MATH101'], ['duration', 'MATH101H'],
['after', 'MATH101H', 'MATH101'], ['after', 'CHEM120', 'MATH101H']]),
('normal control 8',
[{'MATH101H': 0, 'MATH101': 0, 'PHYS110': 3}, {'MATH101': 180, 'MATH101H': 120, 'PHYS110': 180},
[180, 90, 120, 90],
[['coincidence', 'PHYS110', 'MATH101H'], ['exclusive', 'MATH101', 'PHYS110'],
['after', 'PHYS110', 'MATH101H']]],
[['duration', 'PHYS110'], ['coincidence', 'PHYS110', 'MATH101H'], ['exclusive', 'MATH101', 'PHYS110']])],
[('regression: after direction 1',
[{'CHEM120': 3, 'HIST140': 0, 'PHYS110': 1, 'BIO130': 3, 'MATH101': 0, 'MATH101H': 2},
{'MATH101': 120, 'MATH101H': 120, 'PHYS110': 90, 'CHEM120': 120, 'BIO130': 120, 'HIST140': 180},
[90, 90, 90, 90],
[['exclusion', 'HIST140', 'BIO130'], ['exclusion', 'MATH101', 'MATH101H'],
['exclusive', 'BIO130', 'MATH101H'], ['after', 'HIST140', 'MATH101']]],
[['duration', 'BIO130'], ['duration', 'CHEM120'], ['duration', 'HIST140'], ['duration', 'MATH101'],
['duration', 'MATH101H'], ['exclusive', 'BIO130', 'MATH101H'], ['after', 'HIST140', 'MATH101']]),
('regression variant: after direction 2',
[{'MATH101': 1, 'MATH101H': 1, 'PHYS110': 0}, {'MATH101': 90, 'MATH101H': 90, 'PHYS110': 90},
[180, 90, 120, 180],
[['after', 'MATH101', 'MATH101H'], ['exclusion', 'PHYS110', 'MATH101'],
['coincidence', 'PHYS110', 'MATH101'], ['exclusive', 'PHYS110', 'MATH101H']]],
[['after', 'MATH101', 'MATH101H'], ['coincidence', 'PHYS110', 'MATH101']]),
('partial repair guard 3',
[{'BIO130': 1, 'PHYS110': 0, 'MATH101': 0, 'MATH101H': 1, 'CHEM120': 2},
{'MATH101': 120, 'MATH101H': 180, 'PHYS110': 120, 'CHEM120': 120, 'BIO130': 180}, [90, 90, 90, 120],
[['exclusive', 'MATH101', 'BIO130'], ['after', 'PHYS110', 'MATH101H'],
['exclusion', 'MATH101', 'PHYS110'], ['after', 'PHYS110', 'BIO130']]],
[['duration', 'BIO130'], ['duration', 'CHEM120'], ['duration', 'MATH101'], ['duration', 'MATH101H'],
['duration', 'PHYS110'], ['exclusive', 'MATH101', 'BIO130'], ['after', 'PHYS110', 'MATH101H'],
['exclusion', 'MATH101', 'PHYS110'], ['after', 'PHYS110', 'BIO130']]),
('boundary control 4', [{'A': 0}, {'A': 120}, [120], []], []),
('normal control 5',
[{'HIST140': 1, 'MATH101H': 3, 'BIO130': 3, 'MATH101': 1, 'CHEM120': 3, 'PHYS110': 1},
{'MATH101': 90, 'MATH101H': 90, 'PHYS110': 90, 'CHEM120': 120, 'BIO130': 120, 'HIST140': 180},
[180, 120, 180, 90], [['exclusion', 'MATH101H', 'PHYS110']]],
[['duration', 'BIO130'], ['duration', 'CHEM120'], ['duration', 'HIST140']]),
('normal control 6',
[{'CHEM120': 1, 'MATH101H': 1, 'MATH101': 2, 'PHYS110': 3},
{'MATH101': 90, 'MATH101H': 90, 'PHYS110': 180, 'CHEM120': 180}, [120, 120, 120, 180],
[['exclusive', 'CHEM120', 'MATH101']]],
[['duration', 'CHEM120'], ['exclusive', 'CHEM120', 'MATH101']]),
('normal control 7',
[{'MATH101H': 2, 'PHYS110': 3, 'MATH101': 3}, {'MATH101': 120, 'MATH101H': 90, 'PHYS110': 180},
[90, 180, 120, 120], [['coincidence', 'PHYS110', 'MATH101'], ['after', 'MATH101H', 'MATH101']]],
[['duration', 'PHYS110'], ['after', 'MATH101H', 'MATH101']]),
('normal control 8',
[{'MATH101H': 2, 'PHYS110': 0, 'MATH101': 1}, {'MATH101': 180, 'MATH101H': 90, 'PHYS110': 180},
[120, 90, 180, 180], [['exclusive', 'MATH101H', 'PHYS110'], ['exclusive', 'MATH101', 'PHYS110']]],
[['duration', 'MATH101'], ['duration', 'PHYS110']])],
[('regression: after direction 1',
[{'PHYS110': 1, 'CHEM120': 0, 'MATH101': 3, 'MATH101H': 3, 'BIO130': 3},
{'MATH101': 120, 'MATH101H': 120, 'PHYS110': 180, 'CHEM120': 90, 'BIO130': 180}, [90, 90, 90, 180],
[['after', 'MATH101', 'MATH101H'], ['exclusion', 'CHEM120', 'BIO130']]],
[['duration', 'PHYS110'], ['after', 'MATH101', 'MATH101H']]),
('regression variant: after direction 2',
[{'MATH101': 2, 'PHYS110': 3, 'MATH101H': 3, 'CHEM120': 3},
{'MATH101': 90, 'MATH101H': 90, 'PHYS110': 90, 'CHEM120': 120}, [90, 120, 90, 90],
[['after', 'MATH101H', 'PHYS110'], ['after', 'MATH101H', 'CHEM120'],
['exclusive', 'PHYS110', 'MATH101']]],
[['duration', 'CHEM120'], ['after', 'MATH101H', 'PHYS110'], ['after', 'MATH101H', 'CHEM120'],
['exclusive', 'PHYS110', 'MATH101']]),
('partial repair guard 3',
[{'MATH101': 3, 'HIST140': 2, 'MATH101H': 0, 'PHYS110': 1, 'BIO130': 1, 'CHEM120': 0},
{'MATH101': 90, 'MATH101H': 90, 'PHYS110': 90, 'CHEM120': 180, 'BIO130': 180, 'HIST140': 180},
[180, 90, 180, 120],
[['after', 'CHEM120', 'BIO130'], ['after', 'MATH101', 'CHEM120'], ['coincidence', 'BIO130', 'MATH101H']]],
[['duration', 'BIO130'], ['after', 'CHEM120', 'BIO130'], ['coincidence', 'BIO130', 'MATH101H']]),
('boundary control 4', [{'A': 1, 'B': 1}, {'A': 90, 'B': 90}, [90, 120], [['after', 'A', 'B']]],
[['after', 'A', 'B']]),
('normal control 5',
[{'CHEM120': 0, 'MATH101H': 1, 'MATH101': 2, 'HIST140': 3, 'BIO130': 3, 'PHYS110': 1},
{'MATH101': 90, 'MATH101H': 120, 'PHYS110': 180, 'CHEM120': 90, 'BIO130': 90, 'HIST140': 180},
[180, 90, 120, 90], [['exclusive', 'HIST140', 'BIO130']]],
[['duration', 'HIST140'], ['duration', 'MATH101H'], ['duration', 'PHYS110'],
['exclusive', 'HIST140', 'BIO130']]),
('normal control 6',
[{'MATH101H': 2, 'PHYS110': 1, 'MATH101': 1}, {'MATH101': 120, 'MATH101H': 90, 'PHYS110': 90},
[180, 120, 90, 120],
[['exclusion', 'PHYS110', 'MATH101'], ['exclusion', 'MATH101H', 'MATH101'],
['exclusive', 'PHYS110', 'MATH101'], ['after', 'PHYS110', 'MATH101H']]],
[['exclusion', 'PHYS110', 'MATH101'], ['exclusive', 'PHYS110', 'MATH101'],
['after', 'PHYS110', 'MATH101H']]),
('normal control 7',
[{'MATH101': 2, 'CHEM120': 3, 'MATH101H': 3, 'PHYS110': 3},
{'MATH101': 120, 'MATH101H': 180, 'PHYS110': 180, 'CHEM120': 180}, [90, 120, 180, 90],
[['coincidence', 'MATH101H', 'CHEM120'], ['exclusion', 'PHYS110', 'MATH101']]],
[['duration', 'CHEM120'], ['duration', 'MATH101H'], ['duration', 'PHYS110']]),
('normal control 8',
[{'PHYS110': 3, 'MATH101H': 3, 'BIO130': 1, 'CHEM120': 2, 'HIST140': 0, 'MATH101': 1},
{'MATH101': 180, 'MATH101H': 90, 'PHYS110': 120, 'CHEM120': 90, 'BIO130': 180, 'HIST140': 120},
[120, 120, 120, 180],
[['after', 'MATH101H', 'BIO130'], ['exclusive', 'CHEM120', 'MATH101H'], ['after', 'BIO130', 'PHYS110']]],
[['duration', 'BIO130'], ['duration', 'MATH101'], ['after', 'BIO130', 'PHYS110']])]]
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: after direction 1 | [['after', 'A', 'B']] | [['after', 'A', 'B']] | Passed |
| regression variant: after direction 2 | [['duration', 'MATH101'], ['duration', 'PHYS110'], ['after', 'MATH101H', 'PHYS110'], ['after', 'MATH101H', 'PHYS110']] | [['duration', 'MATH101'], ['duration', 'PHYS110'], ['after', 'MATH101H', 'PHYS110'], ['after', 'MATH101H', 'PHYS110']] | Passed |
| partial repair guard 3 | [['coincidence', 'MATH101', 'PHYS110'], ['exclusive', 'PHYS110', 'MATH101H'], ['after', 'PHYS110', 'MATH101'], ['coincidence', 'MATH101H', 'MATH101']] | [['coincidence', 'MATH101', 'PHYS110'], ['exclusive', 'PHYS110', 'MATH101H'], ['after', 'PHYS110', 'MATH101'], ['coincidence', 'MATH101H', 'MATH101']] | Passed |
| boundary control 4 | [] | [] | Passed |
| normal control 5 | [['duration', 'MATH101H'], ['duration', 'PHYS110'], ['coincidence', 'MATH101', 'PHYS110'], ['coincidence', 'PHYS110', 'MATH101'], ['after', 'CHEM120', 'MATH101']] | [['duration', 'MATH101H'], ['duration', 'PHYS110'], ['coincidence', 'MATH101', 'PHYS110'], ['coincidence', 'PHYS110', 'MATH101'], ['after', 'CHEM120', 'MATH101']] | Passed |
| normal control 6 | [['duration', 'MATH101'], ['after', 'MATH101', 'MATH101H'], ['coincidence', 'CHEM120', 'MATH101H'], ['coincidence', 'MATH101H', 'CHEM120']] | [['duration', 'MATH101'], ['after', 'MATH101', 'MATH101H'], ['coincidence', 'CHEM120', 'MATH101H'], ['coincidence', 'MATH101H', 'CHEM120']] | Passed |
| normal control 7 | [['duration', 'BIO130']] | [['duration', 'BIO130']] | Passed |
| normal control 8 | [['duration', 'CHEM120'], ['coincidence', 'CHEM120', 'MATH101H'], ['exclusive', 'CHEM120', 'MATH101'], ['coincidence', 'HIST140', 'MATH101']] | [['duration', 'CHEM120'], ['coincidence', 'CHEM120', 'MATH101H'], ['exclusive', 'CHEM120', 'MATH101'], ['coincidence', 'HIST140', 'MATH101']] | Passed |
SHA-256 / 7988c670ab0806309503ead8e5cfcc3efd36b72701557a68463926fe8f55da6f
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:04.739693+00:00.
Case digest / eb09d12be5e75e80f4edd17dcbb6d88b4f304aa92c118e0088f0f3084956fada