FA-94601 / Exam timetabling constraints / Open access
Teaching commitment blocks the whole day · case 01
Invigilators teaching one period cannot be assigned any duty that day.
ROOT CAUSE
Busy periods are widened to their day.
VERIFIED REPAIR
Only the exact teaching period conflicts.
Unsuccessful approach: Blocking the following period too still rejects free periods.
Case contract
duties [invigilator, exam, period]; teach invigilator -> busy periods; subj invigilator -> subject code; exam subject is the part of the exam id before "-". Findings: busy (duty in a busy period), own_subject, double (same invigilator already on duty that period), daily_max (reported once, on the first duty that exceeds maxday on a day = period // spd). Return sorted [invigilator, exam, finding] rows.
Why this case matters
Invigilation rosters must respect teaching commitments, conflict-of-interest rules and daily limits.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(duties, teach, subj, maxday, spd):
out = []
seen = {}
per_day = {}
for inv, ex, p in duties:
if p // spd in [q // spd for q in teach.get(inv, [])]:
out.append([inv, ex, 'busy'])
if ex.split('-')[0] == subj.get(inv):
out.append([inv, ex, 'own_subject'])
if (inv, p) in seen:
out.append([inv, ex, 'double'])
seen[(inv, p)] = ex
d = (inv, p // spd)
per_day[d] = per_day.get(d, 0) + 1
if per_day[d] == maxday + 1:
out.append([inv, ex, 'daily_max'])
return sorted(out)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: busy period granularity 1',
[[['bob', 'CHEM-110', 0], ['cy', 'BIO-201', 2], ['cy', 'BIO-201', 2], ['ann', 'BIO-201', 4],
['ann', 'MATH-101', 3]],
{'ann': [3], 'bob': [], 'cy': []}, {'ann': 'MATH', 'bob': 'CHEM', 'cy': 'BIO'}, 2, 3],
[['ann', 'MATH-101', 'busy'], ['ann', 'MATH-101', 'own_subject'], ['bob', 'CHEM-110', 'own_subject'],
['cy', 'BIO-201', 'double'], ['cy', 'BIO-201', 'own_subject'], ['cy', 'BIO-201', 'own_subject']]),
('regression variant: busy period granularity 2',
[[['ann', 'CHEM-110', 0], ['cy', 'MATH-101', 5]], {'ann': [5], 'bob': [4, 5], 'cy': [4]},
{'ann': 'BIOL', 'bob': 'BIOL', 'cy': 'MATH'}, 1, 2],
[['cy', 'MATH-101', 'own_subject']]),
('partial repair guard 3',
[[['bob', 'BIOL-300', 3], ['cy', 'CHEM-110', 3], ['cy', 'CHEM-110', 3], ['ann', 'MATH-101', 0],
['bob', 'BIOL-300', 1], ['cy', 'MATH-101', 3]],
{'bob': [], 'cy': [0, 2]}, {'ann': 'MATH', 'bob': 'CHEM', 'cy': 'BIO'}, 2, 3],
[['ann', 'MATH-101', 'own_subject'], ['cy', 'CHEM-110', 'double'], ['cy', 'MATH-101', 'daily_max'],
['cy', 'MATH-101', 'double']]),
('boundary control 4', [[['ann', 'MATH-101', 2], ['ann', 'CHEM-110', 3]], {}, {}, 1, 3], []),
('normal control 5',
[[['bob', 'BIO-201', 0], ['ann', 'CHEM-110', 3], ['ann', 'CHEM-110', 0], ['ann', 'MATH-101', 0],
['bob', 'MATH-101', 2]],
{'ann': [3], 'bob': [1], 'cy': [4]}, {'ann': 'CHEM', 'bob': 'CHEM', 'cy': 'BIO'}, 1, 2],
[['ann', 'CHEM-110', 'busy'], ['ann', 'CHEM-110', 'own_subject'], ['ann', 'CHEM-110', 'own_subject'],
['ann', 'MATH-101', 'daily_max'], ['ann', 'MATH-101', 'double']]),
('normal control 6',
[[['bob', 'BIOL-300', 4], ['bob', 'CHEM-110', 1], ['ann', 'CHEM-110', 2], ['ann', 'BIO-201', 5]],
{'ann': [], 'bob': [], 'cy': []}, {'ann': 'BIO', 'bob': 'BIOL', 'cy': 'CHEM'}, 1, 2],
[['ann', 'BIO-201', 'own_subject'], ['bob', 'BIOL-300', 'own_subject']]),
('normal control 7',
[[['cy', 'BIOL-300', 5], ['ann', 'BIOL-300', 1], ['ann', 'MATH-101', 3], ['cy', 'MATH-101', 5],
['cy', 'BIO-201', 4]],
{'ann': [], 'bob': [3], 'cy': []}, {'ann': 'CHEM', 'bob': 'BIOL', 'cy': 'BIOL'}, 2, 2],
[['cy', 'BIO-201', 'daily_max'], ['cy', 'BIOL-300', 'own_subject'], ['cy', 'MATH-101', 'double']]),
('normal control 8',
[[['cy', 'BIO-201', 3], ['ann', 'MATH-101', 3], ['ann', 'MATH-101', 2]], {'ann': [5], 'bob': []},
{'ann': 'MATH', 'bob': 'MATH', 'cy': 'BIO'}, 2, 3],
[['ann', 'MATH-101', 'own_subject'], ['ann', 'MATH-101', 'own_subject'],
['cy', 'BIO-201', 'own_subject']])],
[('regression: busy period granularity 1',
[[['cy', 'CHEM-110', 1], ['ann', 'MATH-101', 4]], {'ann': [5], 'cy': [4]},
{'ann': 'BIO', 'bob': 'CHEM', 'cy': 'CHEM'}, 1, 2],
[['cy', 'CHEM-110', 'own_subject']]),
('regression variant: busy period granularity 2',
[[['cy', 'MATH-101', 5], ['ann', 'MATH-101', 1], ['cy', 'MATH-101', 4], ['ann', 'BIO-201', 2],
['bob', 'MATH-101', 0]],
{'ann': [1, 5], 'bob': [0], 'cy': [3]}, {'ann': 'MATH', 'bob': 'CHEM', 'cy': 'BIO'}, 1, 3],
[['ann', 'BIO-201', 'daily_max'], ['ann', 'MATH-101', 'busy'], ['ann', 'MATH-101', 'own_subject'],
['bob', 'MATH-101', 'busy'], ['cy', 'MATH-101', 'daily_max']]),
('partial repair guard 3',
[[['ann', 'MATH-101', 4], ['cy', 'BIOL-300', 2], ['bob', 'CHEM-110', 4], ['cy', 'CHEM-110', 4],
['bob', 'BIOL-300', 4], ['cy', 'CHEM-110', 4], ['ann', 'MATH-101', 0]],
{'ann': [2, 3], 'bob': [1, 3]}, {'ann': 'CHEM', 'bob': 'MATH', 'cy': 'BIOL'}, 1, 2],
[['bob', 'BIOL-300', 'daily_max'], ['bob', 'BIOL-300', 'double'], ['cy', 'BIOL-300', 'own_subject'],
['cy', 'CHEM-110', 'daily_max'], ['cy', 'CHEM-110', 'double']]),
('boundary control 4', [[['ann', 'BIOL-300', 0]], {}, {'ann': 'BIO'}, 2, 3], []),
('normal control 5',
[[['cy', 'BIO-201', 3], ['ann', 'MATH-101', 3], ['ann', 'MATH-101', 2]], {'ann': [5], 'bob': []},
{'ann': 'MATH', 'bob': 'MATH', 'cy': 'BIO'}, 2, 3],
[['ann', 'MATH-101', 'own_subject'], ['ann', 'MATH-101', 'own_subject'],
['cy', 'BIO-201', 'own_subject']]),
('normal control 6',
[[['bob', 'CHEM-110', 1], ['bob', 'BIOL-300', 2], ['cy', 'BIO-201', 0], ['cy', 'MATH-101', 0],
['ann', 'MATH-101', 0], ['cy', 'CHEM-110', 2], ['cy', 'BIO-201', 2]],
{'bob': [0, 3], 'cy': []}, {'ann': 'BIO', 'bob': 'BIOL', 'cy': 'CHEM'}, 2, 3],
[['bob', 'BIOL-300', 'own_subject'], ['cy', 'BIO-201', 'double'], ['cy', 'CHEM-110', 'daily_max'],
['cy', 'CHEM-110', 'own_subject'], ['cy', 'MATH-101', 'double']]),
('normal control 7',
[[['bob', 'MATH-101', 2], ['bob', 'BIOL-300', 4], ['ann', 'BIO-201', 4]],
{'ann': [2], 'bob': [3], 'cy': [0]}, {'ann': 'MATH', 'bob': 'CHEM', 'cy': 'BIO'}, 1, 2],
[]),
('normal control 8',
[[['bob', 'BIO-201', 3], ['cy', 'BIO-201', 5], ['cy', 'MATH-101', 3], ['cy', 'BIOL-300', 1],
['cy', 'CHEM-110', 5], ['cy', 'MATH-101', 2]],
{'ann': [3, 5], 'bob': [], 'cy': [4]}, {'ann': 'BIOL', 'bob': 'MATH', 'cy': 'BIOL'}, 2, 3],
[['cy', 'BIOL-300', 'own_subject'], ['cy', 'CHEM-110', 'daily_max'], ['cy', 'CHEM-110', 'double']])],
[('regression: busy period granularity 1',
[[['bob', 'BIO-201', 0], ['ann', 'MATH-101', 3], ['ann', 'CHEM-110', 2]], {'ann': [1, 3], 'bob': []},
{'ann': 'BIOL', 'bob': 'BIOL', 'cy': 'BIO'}, 2, 3],
[['ann', 'MATH-101', 'busy']]),
('regression variant: busy period granularity 2',
[[['ann', 'MATH-101', 1], ['bob', 'BIOL-300', 0], ['ann', 'MATH-101', 2], ['ann', 'MATH-101', 3],
['bob', 'BIOL-300', 4], ['bob', 'MATH-101', 4], ['ann', 'CHEM-110', 0]],
{'ann': [], 'bob': [2, 5], 'cy': [1, 5]}, {'ann': 'CHEM', 'bob': 'CHEM', 'cy': 'BIOL'}, 2, 3],
[['ann', 'CHEM-110', 'daily_max'], ['ann', 'CHEM-110', 'own_subject'], ['bob', 'MATH-101', 'double']]),
('partial repair guard 3',
[[['bob', 'BIOL-300', 0], ['cy', 'MATH-101', 5], ['ann', 'BIOL-300', 2]],
{'ann': [0], 'bob': [0], 'cy': [2, 4]}, {'ann': 'BIO', 'bob': 'BIO', 'cy': 'CHEM'}, 1, 3],
[['bob', 'BIOL-300', 'busy']]),
('boundary control 4', [[['ann', 'MATH-101', 0], ['bob', 'CHEM-110', 0]], {}, {}, 2, 3], []),
('normal control 5',
[[['bob', 'MATH-101', 4], ['cy', 'BIOL-300', 4], ['ann', 'BIO-201', 3]], {'ann': [2], 'cy': [0, 3]},
{'ann': 'CHEM', 'bob': 'CHEM', 'cy': 'CHEM'}, 1, 2],
[]),
('normal control 6',
[[['ann', 'BIO-201', 0], ['bob', 'CHEM-110', 0], ['cy', 'CHEM-110', 2]], {'ann': [], 'bob': [0, 1]},
{'ann': 'BIO', 'bob': 'MATH', 'cy': 'BIOL'}, 2, 2],
[['ann', 'BIO-201', 'own_subject'], ['bob', 'CHEM-110', 'busy']]),
('normal control 7',
[[['ann', 'BIOL-300', 1], ['cy', 'BIOL-300', 5], ['bob', 'BIO-201', 3], ['cy', 'CHEM-110', 5],
['cy', 'BIOL-300', 4], ['bob', 'MATH-101', 4]],
{'bob': [1], 'cy': [2]}, {'ann': 'MATH', 'bob': 'CHEM', 'cy': 'CHEM'}, 2, 3],
[['cy', 'BIOL-300', 'daily_max'], ['cy', 'CHEM-110', 'double'], ['cy', 'CHEM-110', 'own_subject']]),
('normal control 8',
[[['cy', 'CHEM-110', 5], ['ann', 'MATH-101', 5], ['cy', 'BIO-201', 4], ['ann', 'BIO-201', 4]],
{'ann': [], 'cy': []}, {'ann': 'CHEM', 'bob': 'MATH', 'cy': 'BIO'}, 2, 3],
[['cy', 'BIO-201', 'own_subject']])],
[('regression: busy period granularity 1',
[[['bob', 'BIO-201', 3], ['cy', 'CHEM-110', 5], ['ann', 'BIOL-300', 1], ['ann', 'BIO-201', 2],
['cy', 'CHEM-110', 3], ['bob', 'CHEM-110', 4], ['cy', 'CHEM-110', 0]],
{'ann': [1, 5], 'bob': [3], 'cy': [3]}, {'ann': 'CHEM', 'bob': 'MATH', 'cy': 'MATH'}, 1, 3],
[['ann', 'BIO-201', 'daily_max'], ['ann', 'BIOL-300', 'busy'], ['bob', 'BIO-201', 'busy'],
['bob', 'CHEM-110', 'daily_max'], ['cy', 'CHEM-110', 'busy'], ['cy', 'CHEM-110', 'daily_max']]),
('regression variant: busy period granularity 2',
[[['ann', 'MATH-101', 4], ['ann', 'MATH-101', 1], ['bob', 'BIO-201', 4], ['bob', 'BIOL-300', 5],
['cy', 'MATH-101', 1]],
{'ann': [0], 'bob': [], 'cy': [2]}, {'ann': 'BIO', 'bob': 'MATH', 'cy': 'BIO'}, 1, 2],
[['bob', 'BIOL-300', 'daily_max']]),
('partial repair guard 3',
[[['ann', 'BIOL-300', 3], ['bob', 'BIO-201', 5]], {'bob': [1, 4], 'cy': [3, 4]},
{'ann': 'CHEM', 'bob': 'BIOL', 'cy': 'MATH'}, 2, 3],
[]),
('boundary control 4',
[[['ann', 'MATH-101', 0], ['ann', 'CHEM-110', 1], ['ann', 'BIO-201', 2]], {}, {}, 2, 3],
[['ann', 'BIO-201', 'daily_max']]),
('normal control 5',
[[['bob', 'CHEM-110', 4], ['ann', 'BIOL-300', 5], ['cy', 'BIO-201', 5], ['bob', 'BIO-201', 5]],
{'ann': [], 'bob': [5], 'cy': []}, {'ann': 'BIO', 'bob': 'MATH', 'cy': 'BIO'}, 2, 3],
[['bob', 'BIO-201', 'busy'], ['cy', 'BIO-201', 'own_subject']]),
('normal control 6',
[[['ann', 'CHEM-110', 4], ['cy', 'BIOL-300', 3]], {'ann': [1], 'bob': [1, 3], 'cy': []},
{'ann': 'CHEM', 'bob': 'BIOL', 'cy': 'BIO'}, 1, 3],
[['ann', 'CHEM-110', 'own_subject']]),
('normal control 7',
[[['cy', 'BIOL-300', 1], ['bob', 'BIOL-300', 3], ['bob', 'BIO-201', 0], ['cy', 'CHEM-110', 2],
['ann', 'BIOL-300', 1]],
{'ann': [0, 5], 'bob': [4], 'cy': []}, {'ann': 'BIOL', 'bob': 'CHEM', 'cy': 'BIOL'}, 2, 3],
[['ann', 'BIOL-300', 'own_subject'], ['cy', 'BIOL-300', 'own_subject']]),
('normal control 8',
[[['bob', 'BIOL-300', 5], ['cy', 'BIO-201', 3], ['ann', 'MATH-101', 4], ['cy', 'BIO-201', 4],
['cy', 'BIO-201', 0]],
{'ann': [], 'bob': [2, 5], 'cy': [4, 5]}, {'ann': 'BIOL', 'bob': 'BIOL', 'cy': 'BIO'}, 2, 3],
[['bob', 'BIOL-300', 'busy'], ['bob', 'BIOL-300', 'own_subject'], ['cy', 'BIO-201', 'busy'],
['cy', 'BIO-201', 'own_subject'], ['cy', 'BIO-201', 'own_subject'], ['cy', 'BIO-201', 'own_subject']])],
[('regression: busy period granularity 1',
[[['cy', 'MATH-101', 0], ['cy', 'CHEM-110', 2], ['bob', 'BIO-201', 3], ['ann', 'CHEM-110', 3],
['bob', 'BIO-201', 4], ['cy', 'BIO-201', 5]],
{'ann': [3], 'bob': [1], 'cy': [0, 4]}, {'ann': 'MATH', 'bob': 'BIOL', 'cy': 'MATH'}, 1, 3],
[['ann', 'CHEM-110', 'busy'], ['bob', 'BIO-201', 'daily_max'], ['cy', 'CHEM-110', 'daily_max'],
['cy', 'MATH-101', 'busy'], ['cy', 'MATH-101', 'own_subject']]),
('regression variant: busy period granularity 2',
[[['cy', 'BIOL-300', 4], ['ann', 'BIOL-300', 3], ['bob', 'BIO-201', 5], ['bob', 'MATH-101', 1],
['bob', 'BIOL-300', 4], ['bob', 'CHEM-110', 1]],
{'ann': [1, 5], 'bob': [5], 'cy': [2, 3]}, {'ann': 'CHEM', 'bob': 'BIOL', 'cy': 'MATH'}, 1, 2],
[['bob', 'BIO-201', 'busy'], ['bob', 'BIOL-300', 'daily_max'], ['bob', 'BIOL-300', 'own_subject'],
['bob', 'CHEM-110', 'daily_max'], ['bob', 'CHEM-110', 'double']]),
('partial repair guard 3',
[[['bob', 'CHEM-110', 5], ['ann', 'CHEM-110', 2], ['ann', 'CHEM-110', 1], ['bob', 'MATH-101', 5],
['cy', 'CHEM-110', 2], ['cy', 'CHEM-110', 3]],
{'ann': [0, 1], 'bob': [1], 'cy': []}, {'ann': 'BIOL', 'bob': 'BIO', 'cy': 'CHEM'}, 2, 2],
[['ann', 'CHEM-110', 'busy'], ['bob', 'MATH-101', 'double'], ['cy', 'CHEM-110', 'own_subject'],
['cy', 'CHEM-110', 'own_subject']]),
('boundary control 4', [[['ann', 'BIO-201', 0]], {}, {'ann': 'BIOL'}, 2, 3], []),
('normal control 5',
[[['bob', 'MATH-101', 2], ['bob', 'BIOL-300', 4], ['ann', 'BIO-201', 4]],
{'ann': [2], 'bob': [3], 'cy': [0]}, {'ann': 'MATH', 'bob': 'CHEM', 'cy': 'BIO'}, 1, 2],
[]),
('normal control 6',
[[['cy', 'MATH-101', 2], ['ann', 'BIO-201', 3]], {'ann': [3, 4], 'bob': [3], 'cy': [3, 5]},
{'ann': 'CHEM', 'bob': 'BIO', 'cy': 'MATH'}, 1, 3],
[['ann', 'BIO-201', 'busy'], ['cy', 'MATH-101', 'own_subject']]),
('normal control 7',
[[['cy', 'CHEM-110', 0], ['cy', 'BIO-201', 5]], {'ann': [], 'cy': []},
{'ann': 'BIOL', 'bob': 'BIOL', 'cy': 'CHEM'}, 2, 3],
[['cy', 'CHEM-110', 'own_subject']]),
('normal control 8',
[[['ann', 'CHEM-110', 2], ['bob', 'BIOL-300', 3], ['bob', 'CHEM-110', 4], ['bob', 'CHEM-110', 5],
['bob', 'MATH-101', 0], ['bob', 'BIO-201', 1]],
{'ann': [3, 5], 'bob': [0, 5], 'cy': [0, 3]}, {'ann': 'BIOL', 'bob': 'BIOL', 'cy': 'MATH'}, 1, 3],
[['bob', 'BIO-201', 'daily_max'], ['bob', 'BIOL-300', 'own_subject'], ['bob', 'CHEM-110', 'busy'],
['bob', 'CHEM-110', 'daily_max'], ['bob', 'MATH-101', 'busy']])]]
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: busy period granularity 1 | [['ann', 'BIO-201', 'busy'], ['ann', 'MATH-101', 'busy'], ['ann', 'MATH-101', 'own_subject'], ['bob', 'CHEM-110', 'own_subject'], ['cy', 'BIO-201', 'double'], ['cy', 'BIO-201', 'own_subject'], ['cy', 'BIO-201', 'own_subject']] | [['ann', 'MATH-101', 'busy'], ['ann', 'MATH-101', 'own_subject'], ['bob', 'CHEM-110', 'own_subject'], ['cy', 'BIO-201', 'double'], ['cy', 'BIO-201', 'own_subject'], ['cy', 'BIO-201', 'own_subject']] | Failed |
| regression variant: busy period granularity 2 | [['cy', 'MATH-101', 'busy'], ['cy', 'MATH-101', 'own_subject']] | [['cy', 'MATH-101', 'own_subject']] | Failed |
| partial repair guard 3 | [['ann', 'MATH-101', 'own_subject'], ['cy', 'CHEM-110', 'double'], ['cy', 'MATH-101', 'daily_max'], ['cy', 'MATH-101', 'double']] | [['ann', 'MATH-101', 'own_subject'], ['cy', 'CHEM-110', 'double'], ['cy', 'MATH-101', 'daily_max'], ['cy', 'MATH-101', 'double']] | Passed |
| boundary control 4 | [] | [] | Passed |
| normal control 5 | [['ann', 'CHEM-110', 'busy'], ['ann', 'CHEM-110', 'own_subject'], ['ann', 'CHEM-110', 'own_subject'], ['ann', 'MATH-101', 'daily_max'], ['ann', 'MATH-101', 'double'], ['bob', 'BIO-201', 'busy']] | [['ann', 'CHEM-110', 'busy'], ['ann', 'CHEM-110', 'own_subject'], ['ann', 'CHEM-110', 'own_subject'], ['ann', 'MATH-101', 'daily_max'], ['ann', 'MATH-101', 'double']] | Failed |
| normal control 6 | [['ann', 'BIO-201', 'own_subject'], ['bob', 'BIOL-300', 'own_subject']] | [['ann', 'BIO-201', 'own_subject'], ['bob', 'BIOL-300', 'own_subject']] | Passed |
| normal control 7 | [['cy', 'BIO-201', 'daily_max'], ['cy', 'BIOL-300', 'own_subject'], ['cy', 'MATH-101', 'double']] | [['cy', 'BIO-201', 'daily_max'], ['cy', 'BIOL-300', 'own_subject'], ['cy', 'MATH-101', 'double']] | Passed |
| normal control 8 | [['ann', 'MATH-101', 'busy'], ['ann', 'MATH-101', 'own_subject'], ['ann', 'MATH-101', 'own_subject'], ['cy', 'BIO-201', 'own_subject']] | [['ann', 'MATH-101', 'own_subject'], ['ann', 'MATH-101', 'own_subject'], ['cy', 'BIO-201', 'own_subject']] | Failed |
SHA-256 / 855287d86bf6a141a85e252bef71548c251f46b6395d3cde7883102cbe16e73c
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(duties, teach, subj, maxday, spd):
out = []
seen = {}
per_day = {}
for inv, ex, p in duties:
if p in teach.get(inv, []) or p - 1 in teach.get(inv, []):
out.append([inv, ex, 'busy'])
if ex.split('-')[0] == subj.get(inv):
out.append([inv, ex, 'own_subject'])
if (inv, p) in seen:
out.append([inv, ex, 'double'])
seen[(inv, p)] = ex
d = (inv, p // spd)
per_day[d] = per_day.get(d, 0) + 1
if per_day[d] == maxday + 1:
out.append([inv, ex, 'daily_max'])
return sorted(out)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: busy period granularity 1',
[[['bob', 'CHEM-110', 0], ['cy', 'BIO-201', 2], ['cy', 'BIO-201', 2], ['ann', 'BIO-201', 4],
['ann', 'MATH-101', 3]],
{'ann': [3], 'bob': [], 'cy': []}, {'ann': 'MATH', 'bob': 'CHEM', 'cy': 'BIO'}, 2, 3],
[['ann', 'MATH-101', 'busy'], ['ann', 'MATH-101', 'own_subject'], ['bob', 'CHEM-110', 'own_subject'],
['cy', 'BIO-201', 'double'], ['cy', 'BIO-201', 'own_subject'], ['cy', 'BIO-201', 'own_subject']]),
('regression variant: busy period granularity 2',
[[['ann', 'CHEM-110', 0], ['cy', 'MATH-101', 5]], {'ann': [5], 'bob': [4, 5], 'cy': [4]},
{'ann': 'BIOL', 'bob': 'BIOL', 'cy': 'MATH'}, 1, 2],
[['cy', 'MATH-101', 'own_subject']]),
('partial repair guard 3',
[[['bob', 'BIOL-300', 3], ['cy', 'CHEM-110', 3], ['cy', 'CHEM-110', 3], ['ann', 'MATH-101', 0],
['bob', 'BIOL-300', 1], ['cy', 'MATH-101', 3]],
{'bob': [], 'cy': [0, 2]}, {'ann': 'MATH', 'bob': 'CHEM', 'cy': 'BIO'}, 2, 3],
[['ann', 'MATH-101', 'own_subject'], ['cy', 'CHEM-110', 'double'], ['cy', 'MATH-101', 'daily_max'],
['cy', 'MATH-101', 'double']]),
('boundary control 4', [[['ann', 'MATH-101', 2], ['ann', 'CHEM-110', 3]], {}, {}, 1, 3], []),
('normal control 5',
[[['bob', 'BIO-201', 0], ['ann', 'CHEM-110', 3], ['ann', 'CHEM-110', 0], ['ann', 'MATH-101', 0],
['bob', 'MATH-101', 2]],
{'ann': [3], 'bob': [1], 'cy': [4]}, {'ann': 'CHEM', 'bob': 'CHEM', 'cy': 'BIO'}, 1, 2],
[['ann', 'CHEM-110', 'busy'], ['ann', 'CHEM-110', 'own_subject'], ['ann', 'CHEM-110', 'own_subject'],
['ann', 'MATH-101', 'daily_max'], ['ann', 'MATH-101', 'double']]),
('normal control 6',
[[['bob', 'BIOL-300', 4], ['bob', 'CHEM-110', 1], ['ann', 'CHEM-110', 2], ['ann', 'BIO-201', 5]],
{'ann': [], 'bob': [], 'cy': []}, {'ann': 'BIO', 'bob': 'BIOL', 'cy': 'CHEM'}, 1, 2],
[['ann', 'BIO-201', 'own_subject'], ['bob', 'BIOL-300', 'own_subject']]),
('normal control 7',
[[['cy', 'BIOL-300', 5], ['ann', 'BIOL-300', 1], ['ann', 'MATH-101', 3], ['cy', 'MATH-101', 5],
['cy', 'BIO-201', 4]],
{'ann': [], 'bob': [3], 'cy': []}, {'ann': 'CHEM', 'bob': 'BIOL', 'cy': 'BIOL'}, 2, 2],
[['cy', 'BIO-201', 'daily_max'], ['cy', 'BIOL-300', 'own_subject'], ['cy', 'MATH-101', 'double']]),
('normal control 8',
[[['cy', 'BIO-201', 3], ['ann', 'MATH-101', 3], ['ann', 'MATH-101', 2]], {'ann': [5], 'bob': []},
{'ann': 'MATH', 'bob': 'MATH', 'cy': 'BIO'}, 2, 3],
[['ann', 'MATH-101', 'own_subject'], ['ann', 'MATH-101', 'own_subject'],
['cy', 'BIO-201', 'own_subject']])],
[('regression: busy period granularity 1',
[[['cy', 'CHEM-110', 1], ['ann', 'MATH-101', 4]], {'ann': [5], 'cy': [4]},
{'ann': 'BIO', 'bob': 'CHEM', 'cy': 'CHEM'}, 1, 2],
[['cy', 'CHEM-110', 'own_subject']]),
('regression variant: busy period granularity 2',
[[['cy', 'MATH-101', 5], ['ann', 'MATH-101', 1], ['cy', 'MATH-101', 4], ['ann', 'BIO-201', 2],
['bob', 'MATH-101', 0]],
{'ann': [1, 5], 'bob': [0], 'cy': [3]}, {'ann': 'MATH', 'bob': 'CHEM', 'cy': 'BIO'}, 1, 3],
[['ann', 'BIO-201', 'daily_max'], ['ann', 'MATH-101', 'busy'], ['ann', 'MATH-101', 'own_subject'],
['bob', 'MATH-101', 'busy'], ['cy', 'MATH-101', 'daily_max']]),
('partial repair guard 3',
[[['ann', 'MATH-101', 4], ['cy', 'BIOL-300', 2], ['bob', 'CHEM-110', 4], ['cy', 'CHEM-110', 4],
['bob', 'BIOL-300', 4], ['cy', 'CHEM-110', 4], ['ann', 'MATH-101', 0]],
{'ann': [2, 3], 'bob': [1, 3]}, {'ann': 'CHEM', 'bob': 'MATH', 'cy': 'BIOL'}, 1, 2],
[['bob', 'BIOL-300', 'daily_max'], ['bob', 'BIOL-300', 'double'], ['cy', 'BIOL-300', 'own_subject'],
['cy', 'CHEM-110', 'daily_max'], ['cy', 'CHEM-110', 'double']]),
('boundary control 4', [[['ann', 'BIOL-300', 0]], {}, {'ann': 'BIO'}, 2, 3], []),
('normal control 5',
[[['cy', 'BIO-201', 3], ['ann', 'MATH-101', 3], ['ann', 'MATH-101', 2]], {'ann': [5], 'bob': []},
{'ann': 'MATH', 'bob': 'MATH', 'cy': 'BIO'}, 2, 3],
[['ann', 'MATH-101', 'own_subject'], ['ann', 'MATH-101', 'own_subject'],
['cy', 'BIO-201', 'own_subject']]),
('normal control 6',
[[['bob', 'CHEM-110', 1], ['bob', 'BIOL-300', 2], ['cy', 'BIO-201', 0], ['cy', 'MATH-101', 0],
['ann', 'MATH-101', 0], ['cy', 'CHEM-110', 2], ['cy', 'BIO-201', 2]],
{'bob': [0, 3], 'cy': []}, {'ann': 'BIO', 'bob': 'BIOL', 'cy': 'CHEM'}, 2, 3],
[['bob', 'BIOL-300', 'own_subject'], ['cy', 'BIO-201', 'double'], ['cy', 'CHEM-110', 'daily_max'],
['cy', 'CHEM-110', 'own_subject'], ['cy', 'MATH-101', 'double']]),
('normal control 7',
[[['bob', 'MATH-101', 2], ['bob', 'BIOL-300', 4], ['ann', 'BIO-201', 4]],
{'ann': [2], 'bob': [3], 'cy': [0]}, {'ann': 'MATH', 'bob': 'CHEM', 'cy': 'BIO'}, 1, 2],
[]),
('normal control 8',
[[['bob', 'BIO-201', 3], ['cy', 'BIO-201', 5], ['cy', 'MATH-101', 3], ['cy', 'BIOL-300', 1],
['cy', 'CHEM-110', 5], ['cy', 'MATH-101', 2]],
{'ann': [3, 5], 'bob': [], 'cy': [4]}, {'ann': 'BIOL', 'bob': 'MATH', 'cy': 'BIOL'}, 2, 3],
[['cy', 'BIOL-300', 'own_subject'], ['cy', 'CHEM-110', 'daily_max'], ['cy', 'CHEM-110', 'double']])],
[('regression: busy period granularity 1',
[[['bob', 'BIO-201', 0], ['ann', 'MATH-101', 3], ['ann', 'CHEM-110', 2]], {'ann': [1, 3], 'bob': []},
{'ann': 'BIOL', 'bob': 'BIOL', 'cy': 'BIO'}, 2, 3],
[['ann', 'MATH-101', 'busy']]),
('regression variant: busy period granularity 2',
[[['ann', 'MATH-101', 1], ['bob', 'BIOL-300', 0], ['ann', 'MATH-101', 2], ['ann', 'MATH-101', 3],
['bob', 'BIOL-300', 4], ['bob', 'MATH-101', 4], ['ann', 'CHEM-110', 0]],
{'ann': [], 'bob': [2, 5], 'cy': [1, 5]}, {'ann': 'CHEM', 'bob': 'CHEM', 'cy': 'BIOL'}, 2, 3],
[['ann', 'CHEM-110', 'daily_max'], ['ann', 'CHEM-110', 'own_subject'], ['bob', 'MATH-101', 'double']]),
('partial repair guard 3',
[[['bob', 'BIOL-300', 0], ['cy', 'MATH-101', 5], ['ann', 'BIOL-300', 2]],
{'ann': [0], 'bob': [0], 'cy': [2, 4]}, {'ann': 'BIO', 'bob': 'BIO', 'cy': 'CHEM'}, 1, 3],
[['bob', 'BIOL-300', 'busy']]),
('boundary control 4', [[['ann', 'MATH-101', 0], ['bob', 'CHEM-110', 0]], {}, {}, 2, 3], []),
('normal control 5',
[[['bob', 'MATH-101', 4], ['cy', 'BIOL-300', 4], ['ann', 'BIO-201', 3]], {'ann': [2], 'cy': [0, 3]},
{'ann': 'CHEM', 'bob': 'CHEM', 'cy': 'CHEM'}, 1, 2],
[]),
('normal control 6',
[[['ann', 'BIO-201', 0], ['bob', 'CHEM-110', 0], ['cy', 'CHEM-110', 2]], {'ann': [], 'bob': [0, 1]},
{'ann': 'BIO', 'bob': 'MATH', 'cy': 'BIOL'}, 2, 2],
[['ann', 'BIO-201', 'own_subject'], ['bob', 'CHEM-110', 'busy']]),
('normal control 7',
[[['ann', 'BIOL-300', 1], ['cy', 'BIOL-300', 5], ['bob', 'BIO-201', 3], ['cy', 'CHEM-110', 5],
['cy', 'BIOL-300', 4], ['bob', 'MATH-101', 4]],
{'bob': [1], 'cy': [2]}, {'ann': 'MATH', 'bob': 'CHEM', 'cy': 'CHEM'}, 2, 3],
[['cy', 'BIOL-300', 'daily_max'], ['cy', 'CHEM-110', 'double'], ['cy', 'CHEM-110', 'own_subject']]),
('normal control 8',
[[['cy', 'CHEM-110', 5], ['ann', 'MATH-101', 5], ['cy', 'BIO-201', 4], ['ann', 'BIO-201', 4]],
{'ann': [], 'cy': []}, {'ann': 'CHEM', 'bob': 'MATH', 'cy': 'BIO'}, 2, 3],
[['cy', 'BIO-201', 'own_subject']])],
[('regression: busy period granularity 1',
[[['bob', 'BIO-201', 3], ['cy', 'CHEM-110', 5], ['ann', 'BIOL-300', 1], ['ann', 'BIO-201', 2],
['cy', 'CHEM-110', 3], ['bob', 'CHEM-110', 4], ['cy', 'CHEM-110', 0]],
{'ann': [1, 5], 'bob': [3], 'cy': [3]}, {'ann': 'CHEM', 'bob': 'MATH', 'cy': 'MATH'}, 1, 3],
[['ann', 'BIO-201', 'daily_max'], ['ann', 'BIOL-300', 'busy'], ['bob', 'BIO-201', 'busy'],
['bob', 'CHEM-110', 'daily_max'], ['cy', 'CHEM-110', 'busy'], ['cy', 'CHEM-110', 'daily_max']]),
('regression variant: busy period granularity 2',
[[['ann', 'MATH-101', 4], ['ann', 'MATH-101', 1], ['bob', 'BIO-201', 4], ['bob', 'BIOL-300', 5],
['cy', 'MATH-101', 1]],
{'ann': [0], 'bob': [], 'cy': [2]}, {'ann': 'BIO', 'bob': 'MATH', 'cy': 'BIO'}, 1, 2],
[['bob', 'BIOL-300', 'daily_max']]),
('partial repair guard 3',
[[['ann', 'BIOL-300', 3], ['bob', 'BIO-201', 5]], {'bob': [1, 4], 'cy': [3, 4]},
{'ann': 'CHEM', 'bob': 'BIOL', 'cy': 'MATH'}, 2, 3],
[]),
('boundary control 4',
[[['ann', 'MATH-101', 0], ['ann', 'CHEM-110', 1], ['ann', 'BIO-201', 2]], {}, {}, 2, 3],
[['ann', 'BIO-201', 'daily_max']]),
('normal control 5',
[[['bob', 'CHEM-110', 4], ['ann', 'BIOL-300', 5], ['cy', 'BIO-201', 5], ['bob', 'BIO-201', 5]],
{'ann': [], 'bob': [5], 'cy': []}, {'ann': 'BIO', 'bob': 'MATH', 'cy': 'BIO'}, 2, 3],
[['bob', 'BIO-201', 'busy'], ['cy', 'BIO-201', 'own_subject']]),
('normal control 6',
[[['ann', 'CHEM-110', 4], ['cy', 'BIOL-300', 3]], {'ann': [1], 'bob': [1, 3], 'cy': []},
{'ann': 'CHEM', 'bob': 'BIOL', 'cy': 'BIO'}, 1, 3],
[['ann', 'CHEM-110', 'own_subject']]),
('normal control 7',
[[['cy', 'BIOL-300', 1], ['bob', 'BIOL-300', 3], ['bob', 'BIO-201', 0], ['cy', 'CHEM-110', 2],
['ann', 'BIOL-300', 1]],
{'ann': [0, 5], 'bob': [4], 'cy': []}, {'ann': 'BIOL', 'bob': 'CHEM', 'cy': 'BIOL'}, 2, 3],
[['ann', 'BIOL-300', 'own_subject'], ['cy', 'BIOL-300', 'own_subject']]),
('normal control 8',
[[['bob', 'BIOL-300', 5], ['cy', 'BIO-201', 3], ['ann', 'MATH-101', 4], ['cy', 'BIO-201', 4],
['cy', 'BIO-201', 0]],
{'ann': [], 'bob': [2, 5], 'cy': [4, 5]}, {'ann': 'BIOL', 'bob': 'BIOL', 'cy': 'BIO'}, 2, 3],
[['bob', 'BIOL-300', 'busy'], ['bob', 'BIOL-300', 'own_subject'], ['cy', 'BIO-201', 'busy'],
['cy', 'BIO-201', 'own_subject'], ['cy', 'BIO-201', 'own_subject'], ['cy', 'BIO-201', 'own_subject']])],
[('regression: busy period granularity 1',
[[['cy', 'MATH-101', 0], ['cy', 'CHEM-110', 2], ['bob', 'BIO-201', 3], ['ann', 'CHEM-110', 3],
['bob', 'BIO-201', 4], ['cy', 'BIO-201', 5]],
{'ann': [3], 'bob': [1], 'cy': [0, 4]}, {'ann': 'MATH', 'bob': 'BIOL', 'cy': 'MATH'}, 1, 3],
[['ann', 'CHEM-110', 'busy'], ['bob', 'BIO-201', 'daily_max'], ['cy', 'CHEM-110', 'daily_max'],
['cy', 'MATH-101', 'busy'], ['cy', 'MATH-101', 'own_subject']]),
('regression variant: busy period granularity 2',
[[['cy', 'BIOL-300', 4], ['ann', 'BIOL-300', 3], ['bob', 'BIO-201', 5], ['bob', 'MATH-101', 1],
['bob', 'BIOL-300', 4], ['bob', 'CHEM-110', 1]],
{'ann': [1, 5], 'bob': [5], 'cy': [2, 3]}, {'ann': 'CHEM', 'bob': 'BIOL', 'cy': 'MATH'}, 1, 2],
[['bob', 'BIO-201', 'busy'], ['bob', 'BIOL-300', 'daily_max'], ['bob', 'BIOL-300', 'own_subject'],
['bob', 'CHEM-110', 'daily_max'], ['bob', 'CHEM-110', 'double']]),
('partial repair guard 3',
[[['bob', 'CHEM-110', 5], ['ann', 'CHEM-110', 2], ['ann', 'CHEM-110', 1], ['bob', 'MATH-101', 5],
['cy', 'CHEM-110', 2], ['cy', 'CHEM-110', 3]],
{'ann': [0, 1], 'bob': [1], 'cy': []}, {'ann': 'BIOL', 'bob': 'BIO', 'cy': 'CHEM'}, 2, 2],
[['ann', 'CHEM-110', 'busy'], ['bob', 'MATH-101', 'double'], ['cy', 'CHEM-110', 'own_subject'],
['cy', 'CHEM-110', 'own_subject']]),
('boundary control 4', [[['ann', 'BIO-201', 0]], {}, {'ann': 'BIOL'}, 2, 3], []),
('normal control 5',
[[['bob', 'MATH-101', 2], ['bob', 'BIOL-300', 4], ['ann', 'BIO-201', 4]],
{'ann': [2], 'bob': [3], 'cy': [0]}, {'ann': 'MATH', 'bob': 'CHEM', 'cy': 'BIO'}, 1, 2],
[]),
('normal control 6',
[[['cy', 'MATH-101', 2], ['ann', 'BIO-201', 3]], {'ann': [3, 4], 'bob': [3], 'cy': [3, 5]},
{'ann': 'CHEM', 'bob': 'BIO', 'cy': 'MATH'}, 1, 3],
[['ann', 'BIO-201', 'busy'], ['cy', 'MATH-101', 'own_subject']]),
('normal control 7',
[[['cy', 'CHEM-110', 0], ['cy', 'BIO-201', 5]], {'ann': [], 'cy': []},
{'ann': 'BIOL', 'bob': 'BIOL', 'cy': 'CHEM'}, 2, 3],
[['cy', 'CHEM-110', 'own_subject']]),
('normal control 8',
[[['ann', 'CHEM-110', 2], ['bob', 'BIOL-300', 3], ['bob', 'CHEM-110', 4], ['bob', 'CHEM-110', 5],
['bob', 'MATH-101', 0], ['bob', 'BIO-201', 1]],
{'ann': [3, 5], 'bob': [0, 5], 'cy': [0, 3]}, {'ann': 'BIOL', 'bob': 'BIOL', 'cy': 'MATH'}, 1, 3],
[['bob', 'BIO-201', 'daily_max'], ['bob', 'BIOL-300', 'own_subject'], ['bob', 'CHEM-110', 'busy'],
['bob', 'CHEM-110', 'daily_max'], ['bob', 'MATH-101', 'busy']])]]
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: busy period granularity 1 | [['ann', 'BIO-201', 'busy'], ['ann', 'MATH-101', 'busy'], ['ann', 'MATH-101', 'own_subject'], ['bob', 'CHEM-110', 'own_subject'], ['cy', 'BIO-201', 'double'], ['cy', 'BIO-201', 'own_subject'], ['cy', 'BIO-201', 'own_subject']] | [['ann', 'MATH-101', 'busy'], ['ann', 'MATH-101', 'own_subject'], ['bob', 'CHEM-110', 'own_subject'], ['cy', 'BIO-201', 'double'], ['cy', 'BIO-201', 'own_subject'], ['cy', 'BIO-201', 'own_subject']] | Failed |
| regression variant: busy period granularity 2 | [['cy', 'MATH-101', 'busy'], ['cy', 'MATH-101', 'own_subject']] | [['cy', 'MATH-101', 'own_subject']] | Failed |
| partial repair guard 3 | [['ann', 'MATH-101', 'own_subject'], ['cy', 'CHEM-110', 'busy'], ['cy', 'CHEM-110', 'busy'], ['cy', 'CHEM-110', 'double'], ['cy', 'MATH-101', 'busy'], ['cy', 'MATH-101', 'daily_max'], ['cy', 'MATH-101', 'double']] | [['ann', 'MATH-101', 'own_subject'], ['cy', 'CHEM-110', 'double'], ['cy', 'MATH-101', 'daily_max'], ['cy', 'MATH-101', 'double']] | Failed |
| boundary control 4 | [] | [] | Passed |
| normal control 5 | [['ann', 'CHEM-110', 'busy'], ['ann', 'CHEM-110', 'own_subject'], ['ann', 'CHEM-110', 'own_subject'], ['ann', 'MATH-101', 'daily_max'], ['ann', 'MATH-101', 'double'], ['bob', 'MATH-101', 'busy']] | [['ann', 'CHEM-110', 'busy'], ['ann', 'CHEM-110', 'own_subject'], ['ann', 'CHEM-110', 'own_subject'], ['ann', 'MATH-101', 'daily_max'], ['ann', 'MATH-101', 'double']] | Failed |
| normal control 6 | [['ann', 'BIO-201', 'own_subject'], ['bob', 'BIOL-300', 'own_subject']] | [['ann', 'BIO-201', 'own_subject'], ['bob', 'BIOL-300', 'own_subject']] | Passed |
| normal control 7 | [['cy', 'BIO-201', 'daily_max'], ['cy', 'BIOL-300', 'own_subject'], ['cy', 'MATH-101', 'double']] | [['cy', 'BIO-201', 'daily_max'], ['cy', 'BIOL-300', 'own_subject'], ['cy', 'MATH-101', 'double']] | Passed |
| normal control 8 | [['ann', 'MATH-101', 'own_subject'], ['ann', 'MATH-101', 'own_subject'], ['cy', 'BIO-201', 'own_subject']] | [['ann', 'MATH-101', 'own_subject'], ['ann', 'MATH-101', 'own_subject'], ['cy', 'BIO-201', 'own_subject']] | Passed |
SHA-256 / edd5728abc17a07162da5189373fcba3e8dd4ece4569cb5f3483fe28b9e6f3bb
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(duties, teach, subj, maxday, spd):
out = []
seen = {}
per_day = {}
for inv, ex, p in duties:
if p in teach.get(inv, []):
out.append([inv, ex, 'busy'])
if ex.split('-')[0] == subj.get(inv):
out.append([inv, ex, 'own_subject'])
if (inv, p) in seen:
out.append([inv, ex, 'double'])
seen[(inv, p)] = ex
d = (inv, p // spd)
per_day[d] = per_day.get(d, 0) + 1
if per_day[d] == maxday + 1:
out.append([inv, ex, 'daily_max'])
return sorted(out)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: busy period granularity 1',
[[['bob', 'CHEM-110', 0], ['cy', 'BIO-201', 2], ['cy', 'BIO-201', 2], ['ann', 'BIO-201', 4],
['ann', 'MATH-101', 3]],
{'ann': [3], 'bob': [], 'cy': []}, {'ann': 'MATH', 'bob': 'CHEM', 'cy': 'BIO'}, 2, 3],
[['ann', 'MATH-101', 'busy'], ['ann', 'MATH-101', 'own_subject'], ['bob', 'CHEM-110', 'own_subject'],
['cy', 'BIO-201', 'double'], ['cy', 'BIO-201', 'own_subject'], ['cy', 'BIO-201', 'own_subject']]),
('regression variant: busy period granularity 2',
[[['ann', 'CHEM-110', 0], ['cy', 'MATH-101', 5]], {'ann': [5], 'bob': [4, 5], 'cy': [4]},
{'ann': 'BIOL', 'bob': 'BIOL', 'cy': 'MATH'}, 1, 2],
[['cy', 'MATH-101', 'own_subject']]),
('partial repair guard 3',
[[['bob', 'BIOL-300', 3], ['cy', 'CHEM-110', 3], ['cy', 'CHEM-110', 3], ['ann', 'MATH-101', 0],
['bob', 'BIOL-300', 1], ['cy', 'MATH-101', 3]],
{'bob': [], 'cy': [0, 2]}, {'ann': 'MATH', 'bob': 'CHEM', 'cy': 'BIO'}, 2, 3],
[['ann', 'MATH-101', 'own_subject'], ['cy', 'CHEM-110', 'double'], ['cy', 'MATH-101', 'daily_max'],
['cy', 'MATH-101', 'double']]),
('boundary control 4', [[['ann', 'MATH-101', 2], ['ann', 'CHEM-110', 3]], {}, {}, 1, 3], []),
('normal control 5',
[[['bob', 'BIO-201', 0], ['ann', 'CHEM-110', 3], ['ann', 'CHEM-110', 0], ['ann', 'MATH-101', 0],
['bob', 'MATH-101', 2]],
{'ann': [3], 'bob': [1], 'cy': [4]}, {'ann': 'CHEM', 'bob': 'CHEM', 'cy': 'BIO'}, 1, 2],
[['ann', 'CHEM-110', 'busy'], ['ann', 'CHEM-110', 'own_subject'], ['ann', 'CHEM-110', 'own_subject'],
['ann', 'MATH-101', 'daily_max'], ['ann', 'MATH-101', 'double']]),
('normal control 6',
[[['bob', 'BIOL-300', 4], ['bob', 'CHEM-110', 1], ['ann', 'CHEM-110', 2], ['ann', 'BIO-201', 5]],
{'ann': [], 'bob': [], 'cy': []}, {'ann': 'BIO', 'bob': 'BIOL', 'cy': 'CHEM'}, 1, 2],
[['ann', 'BIO-201', 'own_subject'], ['bob', 'BIOL-300', 'own_subject']]),
('normal control 7',
[[['cy', 'BIOL-300', 5], ['ann', 'BIOL-300', 1], ['ann', 'MATH-101', 3], ['cy', 'MATH-101', 5],
['cy', 'BIO-201', 4]],
{'ann': [], 'bob': [3], 'cy': []}, {'ann': 'CHEM', 'bob': 'BIOL', 'cy': 'BIOL'}, 2, 2],
[['cy', 'BIO-201', 'daily_max'], ['cy', 'BIOL-300', 'own_subject'], ['cy', 'MATH-101', 'double']]),
('normal control 8',
[[['cy', 'BIO-201', 3], ['ann', 'MATH-101', 3], ['ann', 'MATH-101', 2]], {'ann': [5], 'bob': []},
{'ann': 'MATH', 'bob': 'MATH', 'cy': 'BIO'}, 2, 3],
[['ann', 'MATH-101', 'own_subject'], ['ann', 'MATH-101', 'own_subject'],
['cy', 'BIO-201', 'own_subject']])],
[('regression: busy period granularity 1',
[[['cy', 'CHEM-110', 1], ['ann', 'MATH-101', 4]], {'ann': [5], 'cy': [4]},
{'ann': 'BIO', 'bob': 'CHEM', 'cy': 'CHEM'}, 1, 2],
[['cy', 'CHEM-110', 'own_subject']]),
('regression variant: busy period granularity 2',
[[['cy', 'MATH-101', 5], ['ann', 'MATH-101', 1], ['cy', 'MATH-101', 4], ['ann', 'BIO-201', 2],
['bob', 'MATH-101', 0]],
{'ann': [1, 5], 'bob': [0], 'cy': [3]}, {'ann': 'MATH', 'bob': 'CHEM', 'cy': 'BIO'}, 1, 3],
[['ann', 'BIO-201', 'daily_max'], ['ann', 'MATH-101', 'busy'], ['ann', 'MATH-101', 'own_subject'],
['bob', 'MATH-101', 'busy'], ['cy', 'MATH-101', 'daily_max']]),
('partial repair guard 3',
[[['ann', 'MATH-101', 4], ['cy', 'BIOL-300', 2], ['bob', 'CHEM-110', 4], ['cy', 'CHEM-110', 4],
['bob', 'BIOL-300', 4], ['cy', 'CHEM-110', 4], ['ann', 'MATH-101', 0]],
{'ann': [2, 3], 'bob': [1, 3]}, {'ann': 'CHEM', 'bob': 'MATH', 'cy': 'BIOL'}, 1, 2],
[['bob', 'BIOL-300', 'daily_max'], ['bob', 'BIOL-300', 'double'], ['cy', 'BIOL-300', 'own_subject'],
['cy', 'CHEM-110', 'daily_max'], ['cy', 'CHEM-110', 'double']]),
('boundary control 4', [[['ann', 'BIOL-300', 0]], {}, {'ann': 'BIO'}, 2, 3], []),
('normal control 5',
[[['cy', 'BIO-201', 3], ['ann', 'MATH-101', 3], ['ann', 'MATH-101', 2]], {'ann': [5], 'bob': []},
{'ann': 'MATH', 'bob': 'MATH', 'cy': 'BIO'}, 2, 3],
[['ann', 'MATH-101', 'own_subject'], ['ann', 'MATH-101', 'own_subject'],
['cy', 'BIO-201', 'own_subject']]),
('normal control 6',
[[['bob', 'CHEM-110', 1], ['bob', 'BIOL-300', 2], ['cy', 'BIO-201', 0], ['cy', 'MATH-101', 0],
['ann', 'MATH-101', 0], ['cy', 'CHEM-110', 2], ['cy', 'BIO-201', 2]],
{'bob': [0, 3], 'cy': []}, {'ann': 'BIO', 'bob': 'BIOL', 'cy': 'CHEM'}, 2, 3],
[['bob', 'BIOL-300', 'own_subject'], ['cy', 'BIO-201', 'double'], ['cy', 'CHEM-110', 'daily_max'],
['cy', 'CHEM-110', 'own_subject'], ['cy', 'MATH-101', 'double']]),
('normal control 7',
[[['bob', 'MATH-101', 2], ['bob', 'BIOL-300', 4], ['ann', 'BIO-201', 4]],
{'ann': [2], 'bob': [3], 'cy': [0]}, {'ann': 'MATH', 'bob': 'CHEM', 'cy': 'BIO'}, 1, 2],
[]),
('normal control 8',
[[['bob', 'BIO-201', 3], ['cy', 'BIO-201', 5], ['cy', 'MATH-101', 3], ['cy', 'BIOL-300', 1],
['cy', 'CHEM-110', 5], ['cy', 'MATH-101', 2]],
{'ann': [3, 5], 'bob': [], 'cy': [4]}, {'ann': 'BIOL', 'bob': 'MATH', 'cy': 'BIOL'}, 2, 3],
[['cy', 'BIOL-300', 'own_subject'], ['cy', 'CHEM-110', 'daily_max'], ['cy', 'CHEM-110', 'double']])],
[('regression: busy period granularity 1',
[[['bob', 'BIO-201', 0], ['ann', 'MATH-101', 3], ['ann', 'CHEM-110', 2]], {'ann': [1, 3], 'bob': []},
{'ann': 'BIOL', 'bob': 'BIOL', 'cy': 'BIO'}, 2, 3],
[['ann', 'MATH-101', 'busy']]),
('regression variant: busy period granularity 2',
[[['ann', 'MATH-101', 1], ['bob', 'BIOL-300', 0], ['ann', 'MATH-101', 2], ['ann', 'MATH-101', 3],
['bob', 'BIOL-300', 4], ['bob', 'MATH-101', 4], ['ann', 'CHEM-110', 0]],
{'ann': [], 'bob': [2, 5], 'cy': [1, 5]}, {'ann': 'CHEM', 'bob': 'CHEM', 'cy': 'BIOL'}, 2, 3],
[['ann', 'CHEM-110', 'daily_max'], ['ann', 'CHEM-110', 'own_subject'], ['bob', 'MATH-101', 'double']]),
('partial repair guard 3',
[[['bob', 'BIOL-300', 0], ['cy', 'MATH-101', 5], ['ann', 'BIOL-300', 2]],
{'ann': [0], 'bob': [0], 'cy': [2, 4]}, {'ann': 'BIO', 'bob': 'BIO', 'cy': 'CHEM'}, 1, 3],
[['bob', 'BIOL-300', 'busy']]),
('boundary control 4', [[['ann', 'MATH-101', 0], ['bob', 'CHEM-110', 0]], {}, {}, 2, 3], []),
('normal control 5',
[[['bob', 'MATH-101', 4], ['cy', 'BIOL-300', 4], ['ann', 'BIO-201', 3]], {'ann': [2], 'cy': [0, 3]},
{'ann': 'CHEM', 'bob': 'CHEM', 'cy': 'CHEM'}, 1, 2],
[]),
('normal control 6',
[[['ann', 'BIO-201', 0], ['bob', 'CHEM-110', 0], ['cy', 'CHEM-110', 2]], {'ann': [], 'bob': [0, 1]},
{'ann': 'BIO', 'bob': 'MATH', 'cy': 'BIOL'}, 2, 2],
[['ann', 'BIO-201', 'own_subject'], ['bob', 'CHEM-110', 'busy']]),
('normal control 7',
[[['ann', 'BIOL-300', 1], ['cy', 'BIOL-300', 5], ['bob', 'BIO-201', 3], ['cy', 'CHEM-110', 5],
['cy', 'BIOL-300', 4], ['bob', 'MATH-101', 4]],
{'bob': [1], 'cy': [2]}, {'ann': 'MATH', 'bob': 'CHEM', 'cy': 'CHEM'}, 2, 3],
[['cy', 'BIOL-300', 'daily_max'], ['cy', 'CHEM-110', 'double'], ['cy', 'CHEM-110', 'own_subject']]),
('normal control 8',
[[['cy', 'CHEM-110', 5], ['ann', 'MATH-101', 5], ['cy', 'BIO-201', 4], ['ann', 'BIO-201', 4]],
{'ann': [], 'cy': []}, {'ann': 'CHEM', 'bob': 'MATH', 'cy': 'BIO'}, 2, 3],
[['cy', 'BIO-201', 'own_subject']])],
[('regression: busy period granularity 1',
[[['bob', 'BIO-201', 3], ['cy', 'CHEM-110', 5], ['ann', 'BIOL-300', 1], ['ann', 'BIO-201', 2],
['cy', 'CHEM-110', 3], ['bob', 'CHEM-110', 4], ['cy', 'CHEM-110', 0]],
{'ann': [1, 5], 'bob': [3], 'cy': [3]}, {'ann': 'CHEM', 'bob': 'MATH', 'cy': 'MATH'}, 1, 3],
[['ann', 'BIO-201', 'daily_max'], ['ann', 'BIOL-300', 'busy'], ['bob', 'BIO-201', 'busy'],
['bob', 'CHEM-110', 'daily_max'], ['cy', 'CHEM-110', 'busy'], ['cy', 'CHEM-110', 'daily_max']]),
('regression variant: busy period granularity 2',
[[['ann', 'MATH-101', 4], ['ann', 'MATH-101', 1], ['bob', 'BIO-201', 4], ['bob', 'BIOL-300', 5],
['cy', 'MATH-101', 1]],
{'ann': [0], 'bob': [], 'cy': [2]}, {'ann': 'BIO', 'bob': 'MATH', 'cy': 'BIO'}, 1, 2],
[['bob', 'BIOL-300', 'daily_max']]),
('partial repair guard 3',
[[['ann', 'BIOL-300', 3], ['bob', 'BIO-201', 5]], {'bob': [1, 4], 'cy': [3, 4]},
{'ann': 'CHEM', 'bob': 'BIOL', 'cy': 'MATH'}, 2, 3],
[]),
('boundary control 4',
[[['ann', 'MATH-101', 0], ['ann', 'CHEM-110', 1], ['ann', 'BIO-201', 2]], {}, {}, 2, 3],
[['ann', 'BIO-201', 'daily_max']]),
('normal control 5',
[[['bob', 'CHEM-110', 4], ['ann', 'BIOL-300', 5], ['cy', 'BIO-201', 5], ['bob', 'BIO-201', 5]],
{'ann': [], 'bob': [5], 'cy': []}, {'ann': 'BIO', 'bob': 'MATH', 'cy': 'BIO'}, 2, 3],
[['bob', 'BIO-201', 'busy'], ['cy', 'BIO-201', 'own_subject']]),
('normal control 6',
[[['ann', 'CHEM-110', 4], ['cy', 'BIOL-300', 3]], {'ann': [1], 'bob': [1, 3], 'cy': []},
{'ann': 'CHEM', 'bob': 'BIOL', 'cy': 'BIO'}, 1, 3],
[['ann', 'CHEM-110', 'own_subject']]),
('normal control 7',
[[['cy', 'BIOL-300', 1], ['bob', 'BIOL-300', 3], ['bob', 'BIO-201', 0], ['cy', 'CHEM-110', 2],
['ann', 'BIOL-300', 1]],
{'ann': [0, 5], 'bob': [4], 'cy': []}, {'ann': 'BIOL', 'bob': 'CHEM', 'cy': 'BIOL'}, 2, 3],
[['ann', 'BIOL-300', 'own_subject'], ['cy', 'BIOL-300', 'own_subject']]),
('normal control 8',
[[['bob', 'BIOL-300', 5], ['cy', 'BIO-201', 3], ['ann', 'MATH-101', 4], ['cy', 'BIO-201', 4],
['cy', 'BIO-201', 0]],
{'ann': [], 'bob': [2, 5], 'cy': [4, 5]}, {'ann': 'BIOL', 'bob': 'BIOL', 'cy': 'BIO'}, 2, 3],
[['bob', 'BIOL-300', 'busy'], ['bob', 'BIOL-300', 'own_subject'], ['cy', 'BIO-201', 'busy'],
['cy', 'BIO-201', 'own_subject'], ['cy', 'BIO-201', 'own_subject'], ['cy', 'BIO-201', 'own_subject']])],
[('regression: busy period granularity 1',
[[['cy', 'MATH-101', 0], ['cy', 'CHEM-110', 2], ['bob', 'BIO-201', 3], ['ann', 'CHEM-110', 3],
['bob', 'BIO-201', 4], ['cy', 'BIO-201', 5]],
{'ann': [3], 'bob': [1], 'cy': [0, 4]}, {'ann': 'MATH', 'bob': 'BIOL', 'cy': 'MATH'}, 1, 3],
[['ann', 'CHEM-110', 'busy'], ['bob', 'BIO-201', 'daily_max'], ['cy', 'CHEM-110', 'daily_max'],
['cy', 'MATH-101', 'busy'], ['cy', 'MATH-101', 'own_subject']]),
('regression variant: busy period granularity 2',
[[['cy', 'BIOL-300', 4], ['ann', 'BIOL-300', 3], ['bob', 'BIO-201', 5], ['bob', 'MATH-101', 1],
['bob', 'BIOL-300', 4], ['bob', 'CHEM-110', 1]],
{'ann': [1, 5], 'bob': [5], 'cy': [2, 3]}, {'ann': 'CHEM', 'bob': 'BIOL', 'cy': 'MATH'}, 1, 2],
[['bob', 'BIO-201', 'busy'], ['bob', 'BIOL-300', 'daily_max'], ['bob', 'BIOL-300', 'own_subject'],
['bob', 'CHEM-110', 'daily_max'], ['bob', 'CHEM-110', 'double']]),
('partial repair guard 3',
[[['bob', 'CHEM-110', 5], ['ann', 'CHEM-110', 2], ['ann', 'CHEM-110', 1], ['bob', 'MATH-101', 5],
['cy', 'CHEM-110', 2], ['cy', 'CHEM-110', 3]],
{'ann': [0, 1], 'bob': [1], 'cy': []}, {'ann': 'BIOL', 'bob': 'BIO', 'cy': 'CHEM'}, 2, 2],
[['ann', 'CHEM-110', 'busy'], ['bob', 'MATH-101', 'double'], ['cy', 'CHEM-110', 'own_subject'],
['cy', 'CHEM-110', 'own_subject']]),
('boundary control 4', [[['ann', 'BIO-201', 0]], {}, {'ann': 'BIOL'}, 2, 3], []),
('normal control 5',
[[['bob', 'MATH-101', 2], ['bob', 'BIOL-300', 4], ['ann', 'BIO-201', 4]],
{'ann': [2], 'bob': [3], 'cy': [0]}, {'ann': 'MATH', 'bob': 'CHEM', 'cy': 'BIO'}, 1, 2],
[]),
('normal control 6',
[[['cy', 'MATH-101', 2], ['ann', 'BIO-201', 3]], {'ann': [3, 4], 'bob': [3], 'cy': [3, 5]},
{'ann': 'CHEM', 'bob': 'BIO', 'cy': 'MATH'}, 1, 3],
[['ann', 'BIO-201', 'busy'], ['cy', 'MATH-101', 'own_subject']]),
('normal control 7',
[[['cy', 'CHEM-110', 0], ['cy', 'BIO-201', 5]], {'ann': [], 'cy': []},
{'ann': 'BIOL', 'bob': 'BIOL', 'cy': 'CHEM'}, 2, 3],
[['cy', 'CHEM-110', 'own_subject']]),
('normal control 8',
[[['ann', 'CHEM-110', 2], ['bob', 'BIOL-300', 3], ['bob', 'CHEM-110', 4], ['bob', 'CHEM-110', 5],
['bob', 'MATH-101', 0], ['bob', 'BIO-201', 1]],
{'ann': [3, 5], 'bob': [0, 5], 'cy': [0, 3]}, {'ann': 'BIOL', 'bob': 'BIOL', 'cy': 'MATH'}, 1, 3],
[['bob', 'BIO-201', 'daily_max'], ['bob', 'BIOL-300', 'own_subject'], ['bob', 'CHEM-110', 'busy'],
['bob', 'CHEM-110', 'daily_max'], ['bob', 'MATH-101', 'busy']])]]
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: busy period granularity 1 | [['ann', 'MATH-101', 'busy'], ['ann', 'MATH-101', 'own_subject'], ['bob', 'CHEM-110', 'own_subject'], ['cy', 'BIO-201', 'double'], ['cy', 'BIO-201', 'own_subject'], ['cy', 'BIO-201', 'own_subject']] | [['ann', 'MATH-101', 'busy'], ['ann', 'MATH-101', 'own_subject'], ['bob', 'CHEM-110', 'own_subject'], ['cy', 'BIO-201', 'double'], ['cy', 'BIO-201', 'own_subject'], ['cy', 'BIO-201', 'own_subject']] | Passed |
| regression variant: busy period granularity 2 | [['cy', 'MATH-101', 'own_subject']] | [['cy', 'MATH-101', 'own_subject']] | Passed |
| partial repair guard 3 | [['ann', 'MATH-101', 'own_subject'], ['cy', 'CHEM-110', 'double'], ['cy', 'MATH-101', 'daily_max'], ['cy', 'MATH-101', 'double']] | [['ann', 'MATH-101', 'own_subject'], ['cy', 'CHEM-110', 'double'], ['cy', 'MATH-101', 'daily_max'], ['cy', 'MATH-101', 'double']] | Passed |
| boundary control 4 | [] | [] | Passed |
| normal control 5 | [['ann', 'CHEM-110', 'busy'], ['ann', 'CHEM-110', 'own_subject'], ['ann', 'CHEM-110', 'own_subject'], ['ann', 'MATH-101', 'daily_max'], ['ann', 'MATH-101', 'double']] | [['ann', 'CHEM-110', 'busy'], ['ann', 'CHEM-110', 'own_subject'], ['ann', 'CHEM-110', 'own_subject'], ['ann', 'MATH-101', 'daily_max'], ['ann', 'MATH-101', 'double']] | Passed |
| normal control 6 | [['ann', 'BIO-201', 'own_subject'], ['bob', 'BIOL-300', 'own_subject']] | [['ann', 'BIO-201', 'own_subject'], ['bob', 'BIOL-300', 'own_subject']] | Passed |
| normal control 7 | [['cy', 'BIO-201', 'daily_max'], ['cy', 'BIOL-300', 'own_subject'], ['cy', 'MATH-101', 'double']] | [['cy', 'BIO-201', 'daily_max'], ['cy', 'BIOL-300', 'own_subject'], ['cy', 'MATH-101', 'double']] | Passed |
| normal control 8 | [['ann', 'MATH-101', 'own_subject'], ['ann', 'MATH-101', 'own_subject'], ['cy', 'BIO-201', 'own_subject']] | [['ann', 'MATH-101', 'own_subject'], ['ann', 'MATH-101', 'own_subject'], ['cy', 'BIO-201', 'own_subject']] | Passed |
SHA-256 / bbae805c7b8f8e1af7254e59b7a28b668908130a958984a00281c72635a8daef
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:05.898804+00:00.
Case digest / c0dd89f1135c180692eba1e24b1a8e8272e87a5459aa2b4650ee8a2bcbdb16f4