FA-94651 / Exam timetabling constraints / Open access
Period penalty charged once per room of a split exam · case 01
Splitting an exam across rooms multiplies its period penalty.
ROOT CAUSE
The period penalty is charged per assignment row.
VERIFIED REPAIR
Charge the period penalty once per exam and period.
Unsuccessful approach: Keying by room as well still charges once per room.
Case contract
Assignment rows [exam, room, period] (a split exam has one row per room; rows may repeat). Each exam pays its period penalty once per distinct period it occupies and each room penalty once per distinct (exam, room). Return [period penalty, room penalty, total].
Why this case matters
Period and room preferences are soft costs that must not be multiplied by exam splitting.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(assign, ppen, rpen):
seen_exam = set()
seen_room = set()
pp = rp = 0
for ex, r, p in assign:
pp += ppen[p]
if (ex, r) not in seen_room:
seen_room.add((ex, r))
rp += rpen[r]
return [pp, rp, pp + rp]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: split period charge 1', [[['A', 'R1', 1], ['A', 'R2', 1]], [0, 5, 0, 0], {'R1': 0, 'R2': 3}],
[5, 3, 8]),
('regression variant: split period charge 2',
[[['CHEM120', 'R2', 3], ['PHYS110', 'R1', 0], ['PHYS110', 'R2', 1], ['PHYS110', 'R1', 0]], [1, 5, 1, 10],
{'R1': 0, 'R2': 3, 'R3': 2}],
[16, 6, 22]),
('partial repair guard 3',
[[['CHEM120', 'R3', 1], ['PHYS110', 'R3', 2], ['CHEM120', 'R3', 2], ['CHEM120', 'R2', 2],
['MATH101H', 'R2', 0], ['PHYS110', 'R3', 1], ['MATH101', 'R2', 3]],
[1, 1, 10, 10], {'R1': 0, 'R2': 1, 'R3': 7}],
[33, 17, 50]),
('boundary control 4', [[['A', 'R2', 0], ['B', 'R2', 0]], [2, 5, 0, 0], {'R1': 0, 'R2': 3}], [4, 6, 10]),
('normal control 5',
[[['MATH101', 'R2', 2], ['PHYS110', 'R3', 2], ['MATH101', 'R1', 1], ['PHYS110', 'R1', 1],
['PHYS110', 'R3', 2]],
[1, 0, 5, 10], {'R1': 0, 'R2': 3, 'R3': 7}],
[10, 10, 20]),
('normal control 6',
[[['MATH101', 'R2', 0], ['MATH101H', 'R3', 0], ['MATH101', 'R1', 1], ['CHEM120', 'R2', 0],
['MATH101', 'R1', 1], ['CHEM120', 'R1', 1], ['MATH101', 'R1', 1]],
[5, 10, 1, 1], {'R1': 0, 'R2': 1, 'R3': 7}],
[35, 9, 44]),
('normal control 7',
[[['MATH101', 'R3', 1], ['CHEM120', 'R3', 1], ['MATH101H', 'R2', 2]], [5, 1, 10, 1],
{'R1': 0, 'R2': 1, 'R3': 2}],
[12, 5, 17]),
('normal control 8',
[[['MATH101', 'R3', 1], ['CHEM120', 'R1', 3], ['MATH101', 'R2', 0], ['PHYS110', 'R2', 0],
['MATH101', 'R2', 0], ['PHYS110', 'R2', 3], ['MATH101', 'R2', 0]],
[10, 1, 0, 1], {'R1': 0, 'R2': 1, 'R3': 2}],
[23, 4, 27])],
[('regression: split period charge 1', [[['A', 'R2', 1], ['A', 'R2', 1]], [0, 5, 0, 0], {'R1': 0, 'R2': 3}],
[5, 3, 8]),
('regression variant: split period charge 2',
[[['MATH101', 'R3', 3], ['CHEM120', 'R3', 2], ['PHYS110', 'R1', 0], ['PHYS110', 'R1', 0]], [10, 10, 1, 10],
{'R1': 0, 'R2': 3, 'R3': 7}],
[21, 14, 35]),
('partial repair guard 3',
[[['MATH101H', 'R2', 2], ['MATH101H', 'R3', 1], ['CHEM120', 'R1', 3], ['MATH101H', 'R1', 1],
['MATH101H', 'R2', 2]],
[10, 10, 1, 10], {'R1': 0, 'R2': 1, 'R3': 7}],
[21, 8, 29]),
('boundary control 4', [[['A', 'R1', 1], ['A', 'R2', 1]], [0, 5, 0, 0], {'R1': 0, 'R2': 3}], [5, 3, 8]),
('boundary control 5', [[['A', 'R2', 0], ['B', 'R2', 0]], [2, 5, 0, 0], {'R1': 0, 'R2': 3}], [4, 6, 10]),
('normal control 6',
[[['MATH101H', 'R3', 1], ['MATH101', 'R1', 2], ['MATH101H', 'R2', 2], ['MATH101H', 'R1', 0]], [1, 1, 0, 1],
{'R1': 0, 'R2': 1, 'R3': 2}],
[2, 3, 5]),
('normal control 7',
[[['MATH101', 'R1', 1], ['MATH101', 'R3', 1], ['CHEM120', 'R1', 2], ['PHYS110', 'R1', 3],
['CHEM120', 'R2', 0], ['CHEM120', 'R1', 0]],
[10, 5, 10, 10], {'R1': 0, 'R2': 3, 'R3': 2}],
[35, 5, 40]),
('normal control 8',
[[['CHEM120', 'R1', 3], ['MATH101H', 'R1', 1], ['CHEM120', 'R2', 0]], [0, 1, 0, 10],
{'R1': 0, 'R2': 1, 'R3': 2}],
[11, 1, 12])],
[('regression: split period charge 1',
[[['MATH101H', 'R3', 1], ['MATH101', 'R1', 3], ['PHYS110', 'R1', 0], ['MATH101', 'R1', 0],
['MATH101H', 'R1', 2], ['PHYS110', 'R1', 1], ['MATH101', 'R1', 3], ['MATH101H', 'R1', 2]],
[1, 0, 5, 10], {'R1': 0, 'R2': 1, 'R3': 2}],
[17, 2, 19]),
('regression variant: split period charge 2',
[[['MATH101H', 'R1', 0], ['CHEM120', 'R1', 3], ['PHYS110', 'R2', 3], ['MATH101H', 'R2', 0],
['MATH101', 'R2', 2]],
[1, 0, 10, 10], {'R1': 0, 'R2': 3, 'R3': 7}],
[31, 9, 40]),
('partial repair guard 3',
[[['CHEM120', 'R3', 3], ['MATH101', 'R2', 0], ['PHYS110', 'R2', 1], ['CHEM120', 'R2', 3],
['PHYS110', 'R3', 0], ['CHEM120', 'R2', 3], ['MATH101H', 'R1', 3]],
[1, 10, 10, 5], {'R1': 0, 'R2': 3, 'R3': 2}],
[22, 13, 35]),
('boundary control 4', [[['A', 'R1', 1], ['A', 'R2', 1]], [0, 5, 0, 0], {'R1': 0, 'R2': 3}], [5, 3, 8]),
('boundary control 5', [[['A', 'R2', 0], ['B', 'R2', 0]], [2, 5, 0, 0], {'R1': 0, 'R2': 3}], [4, 6, 10]),
('normal control 6',
[[['MATH101H', 'R3', 0], ['CHEM120', 'R1', 3], ['MATH101', 'R3', 3], ['MATH101H', 'R2', 3],
['MATH101', 'R2', 1], ['PHYS110', 'R2', 0], ['PHYS110', 'R3', 0]],
[1, 1, 10, 0], {'R1': 0, 'R2': 3, 'R3': 2}],
[3, 15, 18]),
('normal control 7',
[[['MATH101H', 'R3', 2], ['CHEM120', 'R2', 2], ['MATH101H', 'R3', 0], ['CHEM120', 'R3', 2],
['MATH101', 'R1', 3], ['MATH101', 'R2', 1], ['CHEM120', 'R3', 2]],
[10, 1, 1, 10], {'R1': 0, 'R2': 1, 'R3': 2}],
[23, 6, 29]),
('normal control 8',
[[['MATH101', 'R2', 2], ['CHEM120', 'R2', 0], ['CHEM120', 'R2', 1], ['MATH101H', 'R1', 3],
['PHYS110', 'R1', 0], ['MATH101H', 'R3', 1], ['MATH101H', 'R1', 3]],
[0, 10, 1, 0], {'R1': 0, 'R2': 3, 'R3': 2}],
[21, 8, 29])],
[('regression: split period charge 1',
[[['CHEM120', 'R2', 0], ['MATH101H', 'R1', 3], ['PHYS110', 'R2', 3], ['PHYS110', 'R2', 3],
['PHYS110', 'R2', 3]],
[1, 1, 0, 1], {'R1': 0, 'R2': 1, 'R3': 2}],
[3, 2, 5]),
('regression variant: split period charge 2',
[[['MATH101', 'R1', 3], ['MATH101', 'R3', 0], ['MATH101', 'R1', 1], ['MATH101H', 'R3', 1],
['CHEM120', 'R1', 3], ['CHEM120', 'R2', 1], ['MATH101', 'R2', 3], ['MATH101', 'R3', 0]],
[10, 10, 0, 0], {'R1': 0, 'R2': 3, 'R3': 2}],
[40, 10, 50]),
('partial repair guard 3',
[[['MATH101H', 'R3', 1], ['MATH101H', 'R1', 1]], [0, 5, 5, 5], {'R1': 0, 'R2': 3, 'R3': 2}], [5, 2, 7]),
('boundary control 4', [[['A', 'R1', 1], ['A', 'R2', 1]], [0, 5, 0, 0], {'R1': 0, 'R2': 3}], [5, 3, 8]),
('boundary control 5', [[['A', 'R2', 0], ['B', 'R2', 0]], [2, 5, 0, 0], {'R1': 0, 'R2': 3}], [4, 6, 10]),
('normal control 6',
[[['PHYS110', 'R3', 3], ['MATH101', 'R3', 0]], [5, 0, 1, 5], {'R1': 0, 'R2': 1, 'R3': 7}], [10, 14, 24]),
('normal control 7',
[[['PHYS110', 'R1', 0], ['MATH101H', 'R1', 0]], [0, 5, 0, 10], {'R1': 0, 'R2': 3, 'R3': 2}], [0, 0, 0]),
('normal control 8',
[[['MATH101', 'R1', 0], ['CHEM120', 'R1', 1], ['PHYS110', 'R2', 0], ['MATH101', 'R1', 0],
['PHYS110', 'R2', 0]],
[10, 5, 1, 0], {'R1': 0, 'R2': 3, 'R3': 7}],
[25, 3, 28])],
[('regression: split period charge 1',
[[['CHEM120', 'R1', 2], ['MATH101', 'R2', 3], ['PHYS110', 'R2', 1], ['CHEM120', 'R1', 2]], [10, 5, 5, 1],
{'R1': 0, 'R2': 3, 'R3': 7}],
[11, 6, 17]),
('regression variant: split period charge 2',
[[['MATH101H', 'R2', 3], ['CHEM120', 'R3', 3], ['CHEM120', 'R3', 2], ['MATH101', 'R1', 0],
['MATH101', 'R2', 3], ['MATH101H', 'R2', 3]],
[0, 1, 0, 5], {'R1': 0, 'R2': 3, 'R3': 7}],
[15, 13, 28]),
('partial repair guard 3',
[[['MATH101', 'R2', 1], ['MATH101H', 'R1', 2], ['MATH101H', 'R1', 1], ['MATH101H', 'R2', 0],
['MATH101H', 'R2', 2], ['MATH101', 'R2', 3], ['CHEM120', 'R1', 0], ['MATH101', 'R2', 1]],
[1, 1, 1, 0], {'R1': 0, 'R2': 3, 'R3': 2}],
[5, 6, 11]),
('boundary control 4', [[['A', 'R1', 1], ['A', 'R2', 1]], [0, 5, 0, 0], {'R1': 0, 'R2': 3}], [5, 3, 8]),
('boundary control 5', [[['A', 'R2', 0], ['B', 'R2', 0]], [2, 5, 0, 0], {'R1': 0, 'R2': 3}], [4, 6, 10]),
('normal control 6',
[[['MATH101H', 'R1', 1], ['MATH101', 'R2', 3], ['MATH101', 'R2', 2], ['MATH101', 'R1', 0],
['MATH101H', 'R1', 1], ['MATH101', 'R1', 3], ['MATH101H', 'R2', 0]],
[5, 1, 10, 0], {'R1': 0, 'R2': 1, 'R3': 7}],
[21, 2, 23]),
('normal control 7',
[[['MATH101H', 'R3', 3], ['CHEM120', 'R3', 2]], [0, 1, 0, 5], {'R1': 0, 'R2': 3, 'R3': 7}], [5, 14, 19]),
('normal control 8',
[[['CHEM120', 'R1', 2], ['MATH101H', 'R3', 0], ['CHEM120', 'R2', 1], ['MATH101', 'R2', 0],
['MATH101', 'R3', 2]],
[1, 5, 10, 1], {'R1': 0, 'R2': 3, 'R3': 2}],
[27, 10, 37])]]
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: split period charge 1 | [10, 3, 13] | [5, 3, 8] | Failed |
| regression variant: split period charge 2 | [17, 6, 23] | [16, 6, 22] | Failed |
| partial repair guard 3 | [43, 17, 60] | [33, 17, 50] | Failed |
| boundary control 4 | [4, 6, 10] | [4, 6, 10] | Passed |
| normal control 5 | [15, 10, 25] | [10, 10, 20] | Failed |
| normal control 6 | [55, 9, 64] | [35, 9, 44] | Failed |
| normal control 7 | [12, 5, 17] | [12, 5, 17] | Passed |
| normal control 8 | [43, 4, 47] | [23, 4, 27] | Failed |
SHA-256 / d9be034027e647c60eac000761d578bc0c512451bc703c7e3d0843ac636e0ad6
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(assign, ppen, rpen):
seen_exam = set()
seen_room = set()
pp = rp = 0
for ex, r, p in assign:
if (ex, r, p) not in seen_exam:
seen_exam.add((ex, r, p))
pp += ppen[p]
if (ex, r) not in seen_room:
seen_room.add((ex, r))
rp += rpen[r]
return [pp, rp, pp + rp]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: split period charge 1', [[['A', 'R1', 1], ['A', 'R2', 1]], [0, 5, 0, 0], {'R1': 0, 'R2': 3}],
[5, 3, 8]),
('regression variant: split period charge 2',
[[['CHEM120', 'R2', 3], ['PHYS110', 'R1', 0], ['PHYS110', 'R2', 1], ['PHYS110', 'R1', 0]], [1, 5, 1, 10],
{'R1': 0, 'R2': 3, 'R3': 2}],
[16, 6, 22]),
('partial repair guard 3',
[[['CHEM120', 'R3', 1], ['PHYS110', 'R3', 2], ['CHEM120', 'R3', 2], ['CHEM120', 'R2', 2],
['MATH101H', 'R2', 0], ['PHYS110', 'R3', 1], ['MATH101', 'R2', 3]],
[1, 1, 10, 10], {'R1': 0, 'R2': 1, 'R3': 7}],
[33, 17, 50]),
('boundary control 4', [[['A', 'R2', 0], ['B', 'R2', 0]], [2, 5, 0, 0], {'R1': 0, 'R2': 3}], [4, 6, 10]),
('normal control 5',
[[['MATH101', 'R2', 2], ['PHYS110', 'R3', 2], ['MATH101', 'R1', 1], ['PHYS110', 'R1', 1],
['PHYS110', 'R3', 2]],
[1, 0, 5, 10], {'R1': 0, 'R2': 3, 'R3': 7}],
[10, 10, 20]),
('normal control 6',
[[['MATH101', 'R2', 0], ['MATH101H', 'R3', 0], ['MATH101', 'R1', 1], ['CHEM120', 'R2', 0],
['MATH101', 'R1', 1], ['CHEM120', 'R1', 1], ['MATH101', 'R1', 1]],
[5, 10, 1, 1], {'R1': 0, 'R2': 1, 'R3': 7}],
[35, 9, 44]),
('normal control 7',
[[['MATH101', 'R3', 1], ['CHEM120', 'R3', 1], ['MATH101H', 'R2', 2]], [5, 1, 10, 1],
{'R1': 0, 'R2': 1, 'R3': 2}],
[12, 5, 17]),
('normal control 8',
[[['MATH101', 'R3', 1], ['CHEM120', 'R1', 3], ['MATH101', 'R2', 0], ['PHYS110', 'R2', 0],
['MATH101', 'R2', 0], ['PHYS110', 'R2', 3], ['MATH101', 'R2', 0]],
[10, 1, 0, 1], {'R1': 0, 'R2': 1, 'R3': 2}],
[23, 4, 27])],
[('regression: split period charge 1', [[['A', 'R2', 1], ['A', 'R2', 1]], [0, 5, 0, 0], {'R1': 0, 'R2': 3}],
[5, 3, 8]),
('regression variant: split period charge 2',
[[['MATH101', 'R3', 3], ['CHEM120', 'R3', 2], ['PHYS110', 'R1', 0], ['PHYS110', 'R1', 0]], [10, 10, 1, 10],
{'R1': 0, 'R2': 3, 'R3': 7}],
[21, 14, 35]),
('partial repair guard 3',
[[['MATH101H', 'R2', 2], ['MATH101H', 'R3', 1], ['CHEM120', 'R1', 3], ['MATH101H', 'R1', 1],
['MATH101H', 'R2', 2]],
[10, 10, 1, 10], {'R1': 0, 'R2': 1, 'R3': 7}],
[21, 8, 29]),
('boundary control 4', [[['A', 'R1', 1], ['A', 'R2', 1]], [0, 5, 0, 0], {'R1': 0, 'R2': 3}], [5, 3, 8]),
('boundary control 5', [[['A', 'R2', 0], ['B', 'R2', 0]], [2, 5, 0, 0], {'R1': 0, 'R2': 3}], [4, 6, 10]),
('normal control 6',
[[['MATH101H', 'R3', 1], ['MATH101', 'R1', 2], ['MATH101H', 'R2', 2], ['MATH101H', 'R1', 0]], [1, 1, 0, 1],
{'R1': 0, 'R2': 1, 'R3': 2}],
[2, 3, 5]),
('normal control 7',
[[['MATH101', 'R1', 1], ['MATH101', 'R3', 1], ['CHEM120', 'R1', 2], ['PHYS110', 'R1', 3],
['CHEM120', 'R2', 0], ['CHEM120', 'R1', 0]],
[10, 5, 10, 10], {'R1': 0, 'R2': 3, 'R3': 2}],
[35, 5, 40]),
('normal control 8',
[[['CHEM120', 'R1', 3], ['MATH101H', 'R1', 1], ['CHEM120', 'R2', 0]], [0, 1, 0, 10],
{'R1': 0, 'R2': 1, 'R3': 2}],
[11, 1, 12])],
[('regression: split period charge 1',
[[['MATH101H', 'R3', 1], ['MATH101', 'R1', 3], ['PHYS110', 'R1', 0], ['MATH101', 'R1', 0],
['MATH101H', 'R1', 2], ['PHYS110', 'R1', 1], ['MATH101', 'R1', 3], ['MATH101H', 'R1', 2]],
[1, 0, 5, 10], {'R1': 0, 'R2': 1, 'R3': 2}],
[17, 2, 19]),
('regression variant: split period charge 2',
[[['MATH101H', 'R1', 0], ['CHEM120', 'R1', 3], ['PHYS110', 'R2', 3], ['MATH101H', 'R2', 0],
['MATH101', 'R2', 2]],
[1, 0, 10, 10], {'R1': 0, 'R2': 3, 'R3': 7}],
[31, 9, 40]),
('partial repair guard 3',
[[['CHEM120', 'R3', 3], ['MATH101', 'R2', 0], ['PHYS110', 'R2', 1], ['CHEM120', 'R2', 3],
['PHYS110', 'R3', 0], ['CHEM120', 'R2', 3], ['MATH101H', 'R1', 3]],
[1, 10, 10, 5], {'R1': 0, 'R2': 3, 'R3': 2}],
[22, 13, 35]),
('boundary control 4', [[['A', 'R1', 1], ['A', 'R2', 1]], [0, 5, 0, 0], {'R1': 0, 'R2': 3}], [5, 3, 8]),
('boundary control 5', [[['A', 'R2', 0], ['B', 'R2', 0]], [2, 5, 0, 0], {'R1': 0, 'R2': 3}], [4, 6, 10]),
('normal control 6',
[[['MATH101H', 'R3', 0], ['CHEM120', 'R1', 3], ['MATH101', 'R3', 3], ['MATH101H', 'R2', 3],
['MATH101', 'R2', 1], ['PHYS110', 'R2', 0], ['PHYS110', 'R3', 0]],
[1, 1, 10, 0], {'R1': 0, 'R2': 3, 'R3': 2}],
[3, 15, 18]),
('normal control 7',
[[['MATH101H', 'R3', 2], ['CHEM120', 'R2', 2], ['MATH101H', 'R3', 0], ['CHEM120', 'R3', 2],
['MATH101', 'R1', 3], ['MATH101', 'R2', 1], ['CHEM120', 'R3', 2]],
[10, 1, 1, 10], {'R1': 0, 'R2': 1, 'R3': 2}],
[23, 6, 29]),
('normal control 8',
[[['MATH101', 'R2', 2], ['CHEM120', 'R2', 0], ['CHEM120', 'R2', 1], ['MATH101H', 'R1', 3],
['PHYS110', 'R1', 0], ['MATH101H', 'R3', 1], ['MATH101H', 'R1', 3]],
[0, 10, 1, 0], {'R1': 0, 'R2': 3, 'R3': 2}],
[21, 8, 29])],
[('regression: split period charge 1',
[[['CHEM120', 'R2', 0], ['MATH101H', 'R1', 3], ['PHYS110', 'R2', 3], ['PHYS110', 'R2', 3],
['PHYS110', 'R2', 3]],
[1, 1, 0, 1], {'R1': 0, 'R2': 1, 'R3': 2}],
[3, 2, 5]),
('regression variant: split period charge 2',
[[['MATH101', 'R1', 3], ['MATH101', 'R3', 0], ['MATH101', 'R1', 1], ['MATH101H', 'R3', 1],
['CHEM120', 'R1', 3], ['CHEM120', 'R2', 1], ['MATH101', 'R2', 3], ['MATH101', 'R3', 0]],
[10, 10, 0, 0], {'R1': 0, 'R2': 3, 'R3': 2}],
[40, 10, 50]),
('partial repair guard 3',
[[['MATH101H', 'R3', 1], ['MATH101H', 'R1', 1]], [0, 5, 5, 5], {'R1': 0, 'R2': 3, 'R3': 2}], [5, 2, 7]),
('boundary control 4', [[['A', 'R1', 1], ['A', 'R2', 1]], [0, 5, 0, 0], {'R1': 0, 'R2': 3}], [5, 3, 8]),
('boundary control 5', [[['A', 'R2', 0], ['B', 'R2', 0]], [2, 5, 0, 0], {'R1': 0, 'R2': 3}], [4, 6, 10]),
('normal control 6',
[[['PHYS110', 'R3', 3], ['MATH101', 'R3', 0]], [5, 0, 1, 5], {'R1': 0, 'R2': 1, 'R3': 7}], [10, 14, 24]),
('normal control 7',
[[['PHYS110', 'R1', 0], ['MATH101H', 'R1', 0]], [0, 5, 0, 10], {'R1': 0, 'R2': 3, 'R3': 2}], [0, 0, 0]),
('normal control 8',
[[['MATH101', 'R1', 0], ['CHEM120', 'R1', 1], ['PHYS110', 'R2', 0], ['MATH101', 'R1', 0],
['PHYS110', 'R2', 0]],
[10, 5, 1, 0], {'R1': 0, 'R2': 3, 'R3': 7}],
[25, 3, 28])],
[('regression: split period charge 1',
[[['CHEM120', 'R1', 2], ['MATH101', 'R2', 3], ['PHYS110', 'R2', 1], ['CHEM120', 'R1', 2]], [10, 5, 5, 1],
{'R1': 0, 'R2': 3, 'R3': 7}],
[11, 6, 17]),
('regression variant: split period charge 2',
[[['MATH101H', 'R2', 3], ['CHEM120', 'R3', 3], ['CHEM120', 'R3', 2], ['MATH101', 'R1', 0],
['MATH101', 'R2', 3], ['MATH101H', 'R2', 3]],
[0, 1, 0, 5], {'R1': 0, 'R2': 3, 'R3': 7}],
[15, 13, 28]),
('partial repair guard 3',
[[['MATH101', 'R2', 1], ['MATH101H', 'R1', 2], ['MATH101H', 'R1', 1], ['MATH101H', 'R2', 0],
['MATH101H', 'R2', 2], ['MATH101', 'R2', 3], ['CHEM120', 'R1', 0], ['MATH101', 'R2', 1]],
[1, 1, 1, 0], {'R1': 0, 'R2': 3, 'R3': 2}],
[5, 6, 11]),
('boundary control 4', [[['A', 'R1', 1], ['A', 'R2', 1]], [0, 5, 0, 0], {'R1': 0, 'R2': 3}], [5, 3, 8]),
('boundary control 5', [[['A', 'R2', 0], ['B', 'R2', 0]], [2, 5, 0, 0], {'R1': 0, 'R2': 3}], [4, 6, 10]),
('normal control 6',
[[['MATH101H', 'R1', 1], ['MATH101', 'R2', 3], ['MATH101', 'R2', 2], ['MATH101', 'R1', 0],
['MATH101H', 'R1', 1], ['MATH101', 'R1', 3], ['MATH101H', 'R2', 0]],
[5, 1, 10, 0], {'R1': 0, 'R2': 1, 'R3': 7}],
[21, 2, 23]),
('normal control 7',
[[['MATH101H', 'R3', 3], ['CHEM120', 'R3', 2]], [0, 1, 0, 5], {'R1': 0, 'R2': 3, 'R3': 7}], [5, 14, 19]),
('normal control 8',
[[['CHEM120', 'R1', 2], ['MATH101H', 'R3', 0], ['CHEM120', 'R2', 1], ['MATH101', 'R2', 0],
['MATH101', 'R3', 2]],
[1, 5, 10, 1], {'R1': 0, 'R2': 3, 'R3': 2}],
[27, 10, 37])]]
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: split period charge 1 | [10, 3, 13] | [5, 3, 8] | Failed |
| regression variant: split period charge 2 | [16, 6, 22] | [16, 6, 22] | Passed |
| partial repair guard 3 | [43, 17, 60] | [33, 17, 50] | Failed |
| boundary control 4 | [4, 6, 10] | [4, 6, 10] | Passed |
| normal control 5 | [10, 10, 20] | [10, 10, 20] | Passed |
| normal control 6 | [35, 9, 44] | [35, 9, 44] | Passed |
| normal control 7 | [12, 5, 17] | [12, 5, 17] | Passed |
| normal control 8 | [23, 4, 27] | [23, 4, 27] | Passed |
SHA-256 / 905a7bf41b11feacdfc1c2c227f64469ea54397ccab9c246fb6fb76f1d51ef8f
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(assign, ppen, rpen):
seen_exam = set()
seen_room = set()
pp = rp = 0
for ex, r, p in assign:
if (ex, p) not in seen_exam:
seen_exam.add((ex, p))
pp += ppen[p]
if (ex, r) not in seen_room:
seen_room.add((ex, r))
rp += rpen[r]
return [pp, rp, pp + rp]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: split period charge 1', [[['A', 'R1', 1], ['A', 'R2', 1]], [0, 5, 0, 0], {'R1': 0, 'R2': 3}],
[5, 3, 8]),
('regression variant: split period charge 2',
[[['CHEM120', 'R2', 3], ['PHYS110', 'R1', 0], ['PHYS110', 'R2', 1], ['PHYS110', 'R1', 0]], [1, 5, 1, 10],
{'R1': 0, 'R2': 3, 'R3': 2}],
[16, 6, 22]),
('partial repair guard 3',
[[['CHEM120', 'R3', 1], ['PHYS110', 'R3', 2], ['CHEM120', 'R3', 2], ['CHEM120', 'R2', 2],
['MATH101H', 'R2', 0], ['PHYS110', 'R3', 1], ['MATH101', 'R2', 3]],
[1, 1, 10, 10], {'R1': 0, 'R2': 1, 'R3': 7}],
[33, 17, 50]),
('boundary control 4', [[['A', 'R2', 0], ['B', 'R2', 0]], [2, 5, 0, 0], {'R1': 0, 'R2': 3}], [4, 6, 10]),
('normal control 5',
[[['MATH101', 'R2', 2], ['PHYS110', 'R3', 2], ['MATH101', 'R1', 1], ['PHYS110', 'R1', 1],
['PHYS110', 'R3', 2]],
[1, 0, 5, 10], {'R1': 0, 'R2': 3, 'R3': 7}],
[10, 10, 20]),
('normal control 6',
[[['MATH101', 'R2', 0], ['MATH101H', 'R3', 0], ['MATH101', 'R1', 1], ['CHEM120', 'R2', 0],
['MATH101', 'R1', 1], ['CHEM120', 'R1', 1], ['MATH101', 'R1', 1]],
[5, 10, 1, 1], {'R1': 0, 'R2': 1, 'R3': 7}],
[35, 9, 44]),
('normal control 7',
[[['MATH101', 'R3', 1], ['CHEM120', 'R3', 1], ['MATH101H', 'R2', 2]], [5, 1, 10, 1],
{'R1': 0, 'R2': 1, 'R3': 2}],
[12, 5, 17]),
('normal control 8',
[[['MATH101', 'R3', 1], ['CHEM120', 'R1', 3], ['MATH101', 'R2', 0], ['PHYS110', 'R2', 0],
['MATH101', 'R2', 0], ['PHYS110', 'R2', 3], ['MATH101', 'R2', 0]],
[10, 1, 0, 1], {'R1': 0, 'R2': 1, 'R3': 2}],
[23, 4, 27])],
[('regression: split period charge 1', [[['A', 'R2', 1], ['A', 'R2', 1]], [0, 5, 0, 0], {'R1': 0, 'R2': 3}],
[5, 3, 8]),
('regression variant: split period charge 2',
[[['MATH101', 'R3', 3], ['CHEM120', 'R3', 2], ['PHYS110', 'R1', 0], ['PHYS110', 'R1', 0]], [10, 10, 1, 10],
{'R1': 0, 'R2': 3, 'R3': 7}],
[21, 14, 35]),
('partial repair guard 3',
[[['MATH101H', 'R2', 2], ['MATH101H', 'R3', 1], ['CHEM120', 'R1', 3], ['MATH101H', 'R1', 1],
['MATH101H', 'R2', 2]],
[10, 10, 1, 10], {'R1': 0, 'R2': 1, 'R3': 7}],
[21, 8, 29]),
('boundary control 4', [[['A', 'R1', 1], ['A', 'R2', 1]], [0, 5, 0, 0], {'R1': 0, 'R2': 3}], [5, 3, 8]),
('boundary control 5', [[['A', 'R2', 0], ['B', 'R2', 0]], [2, 5, 0, 0], {'R1': 0, 'R2': 3}], [4, 6, 10]),
('normal control 6',
[[['MATH101H', 'R3', 1], ['MATH101', 'R1', 2], ['MATH101H', 'R2', 2], ['MATH101H', 'R1', 0]], [1, 1, 0, 1],
{'R1': 0, 'R2': 1, 'R3': 2}],
[2, 3, 5]),
('normal control 7',
[[['MATH101', 'R1', 1], ['MATH101', 'R3', 1], ['CHEM120', 'R1', 2], ['PHYS110', 'R1', 3],
['CHEM120', 'R2', 0], ['CHEM120', 'R1', 0]],
[10, 5, 10, 10], {'R1': 0, 'R2': 3, 'R3': 2}],
[35, 5, 40]),
('normal control 8',
[[['CHEM120', 'R1', 3], ['MATH101H', 'R1', 1], ['CHEM120', 'R2', 0]], [0, 1, 0, 10],
{'R1': 0, 'R2': 1, 'R3': 2}],
[11, 1, 12])],
[('regression: split period charge 1',
[[['MATH101H', 'R3', 1], ['MATH101', 'R1', 3], ['PHYS110', 'R1', 0], ['MATH101', 'R1', 0],
['MATH101H', 'R1', 2], ['PHYS110', 'R1', 1], ['MATH101', 'R1', 3], ['MATH101H', 'R1', 2]],
[1, 0, 5, 10], {'R1': 0, 'R2': 1, 'R3': 2}],
[17, 2, 19]),
('regression variant: split period charge 2',
[[['MATH101H', 'R1', 0], ['CHEM120', 'R1', 3], ['PHYS110', 'R2', 3], ['MATH101H', 'R2', 0],
['MATH101', 'R2', 2]],
[1, 0, 10, 10], {'R1': 0, 'R2': 3, 'R3': 7}],
[31, 9, 40]),
('partial repair guard 3',
[[['CHEM120', 'R3', 3], ['MATH101', 'R2', 0], ['PHYS110', 'R2', 1], ['CHEM120', 'R2', 3],
['PHYS110', 'R3', 0], ['CHEM120', 'R2', 3], ['MATH101H', 'R1', 3]],
[1, 10, 10, 5], {'R1': 0, 'R2': 3, 'R3': 2}],
[22, 13, 35]),
('boundary control 4', [[['A', 'R1', 1], ['A', 'R2', 1]], [0, 5, 0, 0], {'R1': 0, 'R2': 3}], [5, 3, 8]),
('boundary control 5', [[['A', 'R2', 0], ['B', 'R2', 0]], [2, 5, 0, 0], {'R1': 0, 'R2': 3}], [4, 6, 10]),
('normal control 6',
[[['MATH101H', 'R3', 0], ['CHEM120', 'R1', 3], ['MATH101', 'R3', 3], ['MATH101H', 'R2', 3],
['MATH101', 'R2', 1], ['PHYS110', 'R2', 0], ['PHYS110', 'R3', 0]],
[1, 1, 10, 0], {'R1': 0, 'R2': 3, 'R3': 2}],
[3, 15, 18]),
('normal control 7',
[[['MATH101H', 'R3', 2], ['CHEM120', 'R2', 2], ['MATH101H', 'R3', 0], ['CHEM120', 'R3', 2],
['MATH101', 'R1', 3], ['MATH101', 'R2', 1], ['CHEM120', 'R3', 2]],
[10, 1, 1, 10], {'R1': 0, 'R2': 1, 'R3': 2}],
[23, 6, 29]),
('normal control 8',
[[['MATH101', 'R2', 2], ['CHEM120', 'R2', 0], ['CHEM120', 'R2', 1], ['MATH101H', 'R1', 3],
['PHYS110', 'R1', 0], ['MATH101H', 'R3', 1], ['MATH101H', 'R1', 3]],
[0, 10, 1, 0], {'R1': 0, 'R2': 3, 'R3': 2}],
[21, 8, 29])],
[('regression: split period charge 1',
[[['CHEM120', 'R2', 0], ['MATH101H', 'R1', 3], ['PHYS110', 'R2', 3], ['PHYS110', 'R2', 3],
['PHYS110', 'R2', 3]],
[1, 1, 0, 1], {'R1': 0, 'R2': 1, 'R3': 2}],
[3, 2, 5]),
('regression variant: split period charge 2',
[[['MATH101', 'R1', 3], ['MATH101', 'R3', 0], ['MATH101', 'R1', 1], ['MATH101H', 'R3', 1],
['CHEM120', 'R1', 3], ['CHEM120', 'R2', 1], ['MATH101', 'R2', 3], ['MATH101', 'R3', 0]],
[10, 10, 0, 0], {'R1': 0, 'R2': 3, 'R3': 2}],
[40, 10, 50]),
('partial repair guard 3',
[[['MATH101H', 'R3', 1], ['MATH101H', 'R1', 1]], [0, 5, 5, 5], {'R1': 0, 'R2': 3, 'R3': 2}], [5, 2, 7]),
('boundary control 4', [[['A', 'R1', 1], ['A', 'R2', 1]], [0, 5, 0, 0], {'R1': 0, 'R2': 3}], [5, 3, 8]),
('boundary control 5', [[['A', 'R2', 0], ['B', 'R2', 0]], [2, 5, 0, 0], {'R1': 0, 'R2': 3}], [4, 6, 10]),
('normal control 6',
[[['PHYS110', 'R3', 3], ['MATH101', 'R3', 0]], [5, 0, 1, 5], {'R1': 0, 'R2': 1, 'R3': 7}], [10, 14, 24]),
('normal control 7',
[[['PHYS110', 'R1', 0], ['MATH101H', 'R1', 0]], [0, 5, 0, 10], {'R1': 0, 'R2': 3, 'R3': 2}], [0, 0, 0]),
('normal control 8',
[[['MATH101', 'R1', 0], ['CHEM120', 'R1', 1], ['PHYS110', 'R2', 0], ['MATH101', 'R1', 0],
['PHYS110', 'R2', 0]],
[10, 5, 1, 0], {'R1': 0, 'R2': 3, 'R3': 7}],
[25, 3, 28])],
[('regression: split period charge 1',
[[['CHEM120', 'R1', 2], ['MATH101', 'R2', 3], ['PHYS110', 'R2', 1], ['CHEM120', 'R1', 2]], [10, 5, 5, 1],
{'R1': 0, 'R2': 3, 'R3': 7}],
[11, 6, 17]),
('regression variant: split period charge 2',
[[['MATH101H', 'R2', 3], ['CHEM120', 'R3', 3], ['CHEM120', 'R3', 2], ['MATH101', 'R1', 0],
['MATH101', 'R2', 3], ['MATH101H', 'R2', 3]],
[0, 1, 0, 5], {'R1': 0, 'R2': 3, 'R3': 7}],
[15, 13, 28]),
('partial repair guard 3',
[[['MATH101', 'R2', 1], ['MATH101H', 'R1', 2], ['MATH101H', 'R1', 1], ['MATH101H', 'R2', 0],
['MATH101H', 'R2', 2], ['MATH101', 'R2', 3], ['CHEM120', 'R1', 0], ['MATH101', 'R2', 1]],
[1, 1, 1, 0], {'R1': 0, 'R2': 3, 'R3': 2}],
[5, 6, 11]),
('boundary control 4', [[['A', 'R1', 1], ['A', 'R2', 1]], [0, 5, 0, 0], {'R1': 0, 'R2': 3}], [5, 3, 8]),
('boundary control 5', [[['A', 'R2', 0], ['B', 'R2', 0]], [2, 5, 0, 0], {'R1': 0, 'R2': 3}], [4, 6, 10]),
('normal control 6',
[[['MATH101H', 'R1', 1], ['MATH101', 'R2', 3], ['MATH101', 'R2', 2], ['MATH101', 'R1', 0],
['MATH101H', 'R1', 1], ['MATH101', 'R1', 3], ['MATH101H', 'R2', 0]],
[5, 1, 10, 0], {'R1': 0, 'R2': 1, 'R3': 7}],
[21, 2, 23]),
('normal control 7',
[[['MATH101H', 'R3', 3], ['CHEM120', 'R3', 2]], [0, 1, 0, 5], {'R1': 0, 'R2': 3, 'R3': 7}], [5, 14, 19]),
('normal control 8',
[[['CHEM120', 'R1', 2], ['MATH101H', 'R3', 0], ['CHEM120', 'R2', 1], ['MATH101', 'R2', 0],
['MATH101', 'R3', 2]],
[1, 5, 10, 1], {'R1': 0, 'R2': 3, 'R3': 2}],
[27, 10, 37])]]
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: split period charge 1 | [5, 3, 8] | [5, 3, 8] | Passed |
| regression variant: split period charge 2 | [16, 6, 22] | [16, 6, 22] | Passed |
| partial repair guard 3 | [33, 17, 50] | [33, 17, 50] | Passed |
| boundary control 4 | [4, 6, 10] | [4, 6, 10] | Passed |
| normal control 5 | [10, 10, 20] | [10, 10, 20] | Passed |
| normal control 6 | [35, 9, 44] | [35, 9, 44] | Passed |
| normal control 7 | [12, 5, 17] | [12, 5, 17] | Passed |
| normal control 8 | [23, 4, 27] | [23, 4, 27] | Passed |
SHA-256 / f79dc6f7b9e66fe7d925a2ff23fd7e5189218f8da83dcc76a81a8df09f061498
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:06.475732+00:00.
Case digest / 180a6d1972d03e7eb185a01867f1eb8232220555a6d2b83e9df2474f8e8a5dda