FA-94446 / Exam timetabling constraints / Open access
Exact rest gap flagged as a conflict · case 01
Sittings separated by exactly the required rest are reported as conflicts.
ROOT CAUSE
The conflict test is inclusive.
VERIFIED REPAIR
Conflict only when the next start is before the extended end plus rest.
Unsuccessful approach: Dropping the rest term only catches overlaps.
Case contract
A student's exams [id, start, duration] and an extra-time percentage. Extended duration = ceil(duration * (100 + pct) / 100), then rounded up to a multiple of 5 minutes. In start order (ties by id) a pair conflicts if the next start is earlier than the previous extended end plus the rest minutes. Return [[id, extended end] in order, conflicting pairs].
Why this case matters
Access arrangements extend sittings; the timetable must still leave rest between a student's exams.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(exams, pct, rest):
rows = []
for eid, st, dur in sorted(exams, key=lambda x: (x[1], x[0])):
ext = -(-dur * (100 + pct) // 100)
ext = -(-ext // 5) * 5
rows.append([eid, st, st + ext])
conf = []
for a, b in zip(rows, rows[1:]):
if b[1] <= a[2] + rest:
conf.append([a[0], b[0]])
return [[[r[0], r[2]] for r in rows], conf]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: rest boundary 1', [[['A', 540, 120], ['B', 720, 90]], 50, 0], [[['A', 720], ['B', 855]], []]),
('regression variant: rest boundary 2',
[[['V0', 600, 60], ['S1', 840, 100], ['U3', 1320, 91], ['V2', 1080, 182]], 15, 30],
[[['V0', 670], ['S1', 955], ['V2', 1290], ['U3', 1425]], []]),
('partial repair guard 3',
[[['W0', 540, 182], ['S2', 810, 182], ['U3', 1050, 100], ['W1', 660, 44]], 25, 15],
[[['W0', 770], ['W1', 715], ['S2', 1040], ['U3', 1175]], [['W0', 'W1'], ['S2', 'U3']]]),
('boundary control 4', [[['A', 540, 73], ['B', 640, 60]], 10, 15], [[['A', 625], ['B', 710]], []]),
('normal control 5', [[['S1', 800, 44], ['P0', 600, 180], ['R2', 920, 60]], 50, 30],
[[['P0', 870], ['S1', 870], ['R2', 1010]], [['P0', 'S1']]]),
('normal control 6', [[['S2', 840, 180], ['S1', 690, 100], ['T0', 540, 120]], 25, 15],
[[['T0', 690], ['S1', 815], ['S2', 1065]], [['T0', 'S1']]]),
('normal control 7', [[['W2', 960, 150], ['W0', 540, 150], ['R1', 780, 72]], 25, 30],
[[['W0', 730], ['R1', 870], ['W2', 1150]], []]),
('normal control 8', [[['P1', 660, 120], ['U0', 540, 72]], 15, 30], [[['U0', 625], ['P1', 800]], []])],
[('regression: rest boundary 1', [[['A', 540, 73], ['B', 640, 60]], 10, 15], [[['A', 625], ['B', 710]], []]),
('regression variant: rest boundary 2',
[[['W3', 1110, 73], ['R1', 840, 150], ['U0', 600, 100], ['R2', 960, 100]], 33, 15],
[[['U0', 735], ['R1', 1040], ['R2', 1095], ['W3', 1210]], [['R1', 'R2']]]),
('partial repair guard 3', [[['Q1', 800, 88], ['Q0', 600, 60], ['R2', 920, 182]], 10, 30],
[[['Q0', 670], ['Q1', 900], ['R2', 1125]], [['Q1', 'R2']]]),
('boundary control 4', [[['A', 540, 91]], 10, 30], [[['A', 645]], []]),
('boundary control 5', [[['A', 540, 100], ['B', 699, 60]], 25, 30], [[['A', 665], ['B', 774]], []]),
('normal control 6', [[['S1', 690, 88], ['Q2', 780, 150], ['T0', 540, 44]], 33, 30],
[[['T0', 600], ['S1', 810], ['Q2', 980]], [['S1', 'Q2']]]),
('normal control 7', [[['R1', 630, 90], ['S0', 540, 182]], 33, 15],
[[['S0', 785], ['R1', 750]], [['S0', 'R1']]]),
('normal control 8', [[['V0', 600, 182], ['R3', 990, 90], ['S2', 900, 88], ['W1', 780, 73]], 25, 30],
[[['V0', 830], ['W1', 875], ['S2', 1010], ['R3', 1105]], [['V0', 'W1'], ['W1', 'S2'], ['S2', 'R3']]])],
[('regression: rest boundary 1',
[[['S2', 900, 73], ['P1', 780, 60], ['U3', 1050, 44], ['W0', 540, 72]], 50, 30],
[[['W0', 650], ['P1', 870], ['S2', 1010], ['U3', 1120]], []]),
('regression variant: rest boundary 2', [[['A', 540, 120], ['B', 720, 90]], 50, 0],
[[['A', 720], ['B', 855]], []]),
('partial repair guard 3', [[['Q1', 840, 120], ['S0', 600, 182]], 25, 15],
[[['S0', 830], ['Q1', 990]], [['S0', 'Q1']]]),
('boundary control 4', [[['A', 540, 88]], 25, 30], [[['A', 650]], []]),
('boundary control 5', [[['A', 540, 72]], 33, 15], [[['A', 640]], []]),
('normal control 6', [[['P1', 720, 88], ['W2', 920, 90], ['P0', 540, 91]], 25, 15],
[[['P0', 655], ['P1', 830], ['W2', 1035]], []]),
('normal control 7', [[['U2', 810, 180], ['W1', 630, 90], ['V3', 900, 180], ['S0', 540, 182]], 10, 15],
[[['S0', 745], ['W1', 730], ['U2', 1010], ['V3', 1100]], [['S0', 'W1'], ['U2', 'V3']]]),
('normal control 8', [[['W0', 540, 60], ['W1', 780, 44]], 15, 15], [[['W0', 610], ['W1', 835]], []])],
[('regression: rest boundary 1', [[['V1', 750, 150], ['W0', 600, 88]], 33, 30],
[[['W0', 720], ['V1', 950]], []]),
('regression variant: rest boundary 2',
[[['P1', 720, 73], ['R0', 600, 91], ['P2', 960, 91], ['R3', 1050, 182]], 15, 15],
[[['R0', 705], ['P1', 805], ['P2', 1065], ['R3', 1260]], [['P2', 'R3']]]),
('partial repair guard 3', [[['Q2', 870, 91], ['Q0', 600, 100], ['W1', 780, 72]], 25, 30],
[[['Q0', 725], ['W1', 870], ['Q2', 985]], [['W1', 'Q2']]]),
('boundary control 4', [[['A', 540, 120], ['B', 720, 90]], 50, 0], [[['A', 720], ['B', 855]], []]),
('boundary control 5', [[['A', 540, 73], ['B', 640, 60]], 10, 15], [[['A', 625], ['B', 710]], []]),
('normal control 6', [[['T0', 600, 88], ['W3', 1070, 44], ['Q2', 980, 150], ['U1', 780, 120]], 15, 30],
[[['T0', 705], ['U1', 920], ['Q2', 1155], ['W3', 1125]], [['Q2', 'W3']]]),
('normal control 7', [[['S3', 1080, 60], ['V1', 840, 120], ['R0', 600, 44], ['U2', 960, 90]], 15, 15],
[[['R0', 655], ['V1', 980], ['U2', 1065], ['S3', 1150]], [['V1', 'U2']]]),
('normal control 8', [[['V1', 630, 180], ['Q0', 540, 44]], 10, 30], [[['Q0', 590], ['V1', 830]], []])],
[('regression: rest boundary 1',
[[['Q2', 810, 88], ['Q1', 690, 150], ['T0', 540, 73], ['U3', 930, 88]], 15, 15],
[[['T0', 625], ['Q1', 865], ['Q2', 915], ['U3', 1035]], [['Q1', 'Q2']]]),
('regression variant: rest boundary 2', [[['Q0', 540, 120], ['U1', 720, 60]], 25, 30],
[[['Q0', 690], ['U1', 795]], []]),
('partial repair guard 3', [[['P2', 920, 180], ['Q0', 540, 150], ['S1', 740, 88]], 33, 30],
[[['Q0', 740], ['S1', 860], ['P2', 1160]], [['Q0', 'S1']]]),
('boundary control 4', [[['A', 540, 91]], 10, 30], [[['A', 645]], []]),
('boundary control 5', [[['A', 540, 100], ['B', 699, 60]], 25, 30], [[['A', 665], ['B', 774]], []]),
('normal control 6', [[['T1', 840, 72], ['V0', 600, 44]], 10, 15], [[['V0', 650], ['T1', 920]], []]),
('normal control 7', [[['Q1', 690, 150], ['P2', 810, 180], ['Q0', 540, 180]], 10, 15],
[[['Q0', 740], ['Q1', 855], ['P2', 1010]], [['Q0', 'Q1'], ['Q1', 'P2']]]),
('normal control 8', [[['S0', 540, 120], ['U2', 920, 44], ['Q3', 1070, 90], ['W1', 740, 91]], 25, 15],
[[['S0', 690], ['W1', 855], ['U2', 975], ['Q3', 1185]], []])]]
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: rest boundary 1 | [[['A', 720], ['B', 855]], [['A', 'B']]] | [[['A', 720], ['B', 855]], []] | Failed |
| regression variant: rest boundary 2 | [[['V0', 670], ['S1', 955], ['V2', 1290], ['U3', 1425]], [['V2', 'U3']]] | [[['V0', 670], ['S1', 955], ['V2', 1290], ['U3', 1425]], []] | Failed |
| partial repair guard 3 | [[['W0', 770], ['W1', 715], ['S2', 1040], ['U3', 1175]], [['W0', 'W1'], ['S2', 'U3']]] | [[['W0', 770], ['W1', 715], ['S2', 1040], ['U3', 1175]], [['W0', 'W1'], ['S2', 'U3']]] | Passed |
| boundary control 4 | [[['A', 625], ['B', 710]], [['A', 'B']]] | [[['A', 625], ['B', 710]], []] | Failed |
| normal control 5 | [[['P0', 870], ['S1', 870], ['R2', 1010]], [['P0', 'S1']]] | [[['P0', 870], ['S1', 870], ['R2', 1010]], [['P0', 'S1']]] | Passed |
| normal control 6 | [[['T0', 690], ['S1', 815], ['S2', 1065]], [['T0', 'S1']]] | [[['T0', 690], ['S1', 815], ['S2', 1065]], [['T0', 'S1']]] | Passed |
| normal control 7 | [[['W0', 730], ['R1', 870], ['W2', 1150]], []] | [[['W0', 730], ['R1', 870], ['W2', 1150]], []] | Passed |
| normal control 8 | [[['U0', 625], ['P1', 800]], []] | [[['U0', 625], ['P1', 800]], []] | Passed |
SHA-256 / 6f84bfe770103bc54ebf29e229e739e5379bc647fca7bc1bb27f9a959bea1804
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(exams, pct, rest):
rows = []
for eid, st, dur in sorted(exams, key=lambda x: (x[1], x[0])):
ext = -(-dur * (100 + pct) // 100)
ext = -(-ext // 5) * 5
rows.append([eid, st, st + ext])
conf = []
for a, b in zip(rows, rows[1:]):
if b[1] < a[2]:
conf.append([a[0], b[0]])
return [[[r[0], r[2]] for r in rows], conf]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: rest boundary 1', [[['A', 540, 120], ['B', 720, 90]], 50, 0], [[['A', 720], ['B', 855]], []]),
('regression variant: rest boundary 2',
[[['V0', 600, 60], ['S1', 840, 100], ['U3', 1320, 91], ['V2', 1080, 182]], 15, 30],
[[['V0', 670], ['S1', 955], ['V2', 1290], ['U3', 1425]], []]),
('partial repair guard 3',
[[['W0', 540, 182], ['S2', 810, 182], ['U3', 1050, 100], ['W1', 660, 44]], 25, 15],
[[['W0', 770], ['W1', 715], ['S2', 1040], ['U3', 1175]], [['W0', 'W1'], ['S2', 'U3']]]),
('boundary control 4', [[['A', 540, 73], ['B', 640, 60]], 10, 15], [[['A', 625], ['B', 710]], []]),
('normal control 5', [[['S1', 800, 44], ['P0', 600, 180], ['R2', 920, 60]], 50, 30],
[[['P0', 870], ['S1', 870], ['R2', 1010]], [['P0', 'S1']]]),
('normal control 6', [[['S2', 840, 180], ['S1', 690, 100], ['T0', 540, 120]], 25, 15],
[[['T0', 690], ['S1', 815], ['S2', 1065]], [['T0', 'S1']]]),
('normal control 7', [[['W2', 960, 150], ['W0', 540, 150], ['R1', 780, 72]], 25, 30],
[[['W0', 730], ['R1', 870], ['W2', 1150]], []]),
('normal control 8', [[['P1', 660, 120], ['U0', 540, 72]], 15, 30], [[['U0', 625], ['P1', 800]], []])],
[('regression: rest boundary 1', [[['A', 540, 73], ['B', 640, 60]], 10, 15], [[['A', 625], ['B', 710]], []]),
('regression variant: rest boundary 2',
[[['W3', 1110, 73], ['R1', 840, 150], ['U0', 600, 100], ['R2', 960, 100]], 33, 15],
[[['U0', 735], ['R1', 1040], ['R2', 1095], ['W3', 1210]], [['R1', 'R2']]]),
('partial repair guard 3', [[['Q1', 800, 88], ['Q0', 600, 60], ['R2', 920, 182]], 10, 30],
[[['Q0', 670], ['Q1', 900], ['R2', 1125]], [['Q1', 'R2']]]),
('boundary control 4', [[['A', 540, 91]], 10, 30], [[['A', 645]], []]),
('boundary control 5', [[['A', 540, 100], ['B', 699, 60]], 25, 30], [[['A', 665], ['B', 774]], []]),
('normal control 6', [[['S1', 690, 88], ['Q2', 780, 150], ['T0', 540, 44]], 33, 30],
[[['T0', 600], ['S1', 810], ['Q2', 980]], [['S1', 'Q2']]]),
('normal control 7', [[['R1', 630, 90], ['S0', 540, 182]], 33, 15],
[[['S0', 785], ['R1', 750]], [['S0', 'R1']]]),
('normal control 8', [[['V0', 600, 182], ['R3', 990, 90], ['S2', 900, 88], ['W1', 780, 73]], 25, 30],
[[['V0', 830], ['W1', 875], ['S2', 1010], ['R3', 1105]], [['V0', 'W1'], ['W1', 'S2'], ['S2', 'R3']]])],
[('regression: rest boundary 1',
[[['S2', 900, 73], ['P1', 780, 60], ['U3', 1050, 44], ['W0', 540, 72]], 50, 30],
[[['W0', 650], ['P1', 870], ['S2', 1010], ['U3', 1120]], []]),
('regression variant: rest boundary 2', [[['A', 540, 120], ['B', 720, 90]], 50, 0],
[[['A', 720], ['B', 855]], []]),
('partial repair guard 3', [[['Q1', 840, 120], ['S0', 600, 182]], 25, 15],
[[['S0', 830], ['Q1', 990]], [['S0', 'Q1']]]),
('boundary control 4', [[['A', 540, 88]], 25, 30], [[['A', 650]], []]),
('boundary control 5', [[['A', 540, 72]], 33, 15], [[['A', 640]], []]),
('normal control 6', [[['P1', 720, 88], ['W2', 920, 90], ['P0', 540, 91]], 25, 15],
[[['P0', 655], ['P1', 830], ['W2', 1035]], []]),
('normal control 7', [[['U2', 810, 180], ['W1', 630, 90], ['V3', 900, 180], ['S0', 540, 182]], 10, 15],
[[['S0', 745], ['W1', 730], ['U2', 1010], ['V3', 1100]], [['S0', 'W1'], ['U2', 'V3']]]),
('normal control 8', [[['W0', 540, 60], ['W1', 780, 44]], 15, 15], [[['W0', 610], ['W1', 835]], []])],
[('regression: rest boundary 1', [[['V1', 750, 150], ['W0', 600, 88]], 33, 30],
[[['W0', 720], ['V1', 950]], []]),
('regression variant: rest boundary 2',
[[['P1', 720, 73], ['R0', 600, 91], ['P2', 960, 91], ['R3', 1050, 182]], 15, 15],
[[['R0', 705], ['P1', 805], ['P2', 1065], ['R3', 1260]], [['P2', 'R3']]]),
('partial repair guard 3', [[['Q2', 870, 91], ['Q0', 600, 100], ['W1', 780, 72]], 25, 30],
[[['Q0', 725], ['W1', 870], ['Q2', 985]], [['W1', 'Q2']]]),
('boundary control 4', [[['A', 540, 120], ['B', 720, 90]], 50, 0], [[['A', 720], ['B', 855]], []]),
('boundary control 5', [[['A', 540, 73], ['B', 640, 60]], 10, 15], [[['A', 625], ['B', 710]], []]),
('normal control 6', [[['T0', 600, 88], ['W3', 1070, 44], ['Q2', 980, 150], ['U1', 780, 120]], 15, 30],
[[['T0', 705], ['U1', 920], ['Q2', 1155], ['W3', 1125]], [['Q2', 'W3']]]),
('normal control 7', [[['S3', 1080, 60], ['V1', 840, 120], ['R0', 600, 44], ['U2', 960, 90]], 15, 15],
[[['R0', 655], ['V1', 980], ['U2', 1065], ['S3', 1150]], [['V1', 'U2']]]),
('normal control 8', [[['V1', 630, 180], ['Q0', 540, 44]], 10, 30], [[['Q0', 590], ['V1', 830]], []])],
[('regression: rest boundary 1',
[[['Q2', 810, 88], ['Q1', 690, 150], ['T0', 540, 73], ['U3', 930, 88]], 15, 15],
[[['T0', 625], ['Q1', 865], ['Q2', 915], ['U3', 1035]], [['Q1', 'Q2']]]),
('regression variant: rest boundary 2', [[['Q0', 540, 120], ['U1', 720, 60]], 25, 30],
[[['Q0', 690], ['U1', 795]], []]),
('partial repair guard 3', [[['P2', 920, 180], ['Q0', 540, 150], ['S1', 740, 88]], 33, 30],
[[['Q0', 740], ['S1', 860], ['P2', 1160]], [['Q0', 'S1']]]),
('boundary control 4', [[['A', 540, 91]], 10, 30], [[['A', 645]], []]),
('boundary control 5', [[['A', 540, 100], ['B', 699, 60]], 25, 30], [[['A', 665], ['B', 774]], []]),
('normal control 6', [[['T1', 840, 72], ['V0', 600, 44]], 10, 15], [[['V0', 650], ['T1', 920]], []]),
('normal control 7', [[['Q1', 690, 150], ['P2', 810, 180], ['Q0', 540, 180]], 10, 15],
[[['Q0', 740], ['Q1', 855], ['P2', 1010]], [['Q0', 'Q1'], ['Q1', 'P2']]]),
('normal control 8', [[['S0', 540, 120], ['U2', 920, 44], ['Q3', 1070, 90], ['W1', 740, 91]], 25, 15],
[[['S0', 690], ['W1', 855], ['U2', 975], ['Q3', 1185]], []])]]
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: rest boundary 1 | [[['A', 720], ['B', 855]], []] | [[['A', 720], ['B', 855]], []] | Passed |
| regression variant: rest boundary 2 | [[['V0', 670], ['S1', 955], ['V2', 1290], ['U3', 1425]], []] | [[['V0', 670], ['S1', 955], ['V2', 1290], ['U3', 1425]], []] | Passed |
| partial repair guard 3 | [[['W0', 770], ['W1', 715], ['S2', 1040], ['U3', 1175]], [['W0', 'W1']]] | [[['W0', 770], ['W1', 715], ['S2', 1040], ['U3', 1175]], [['W0', 'W1'], ['S2', 'U3']]] | Failed |
| boundary control 4 | [[['A', 625], ['B', 710]], []] | [[['A', 625], ['B', 710]], []] | Passed |
| normal control 5 | [[['P0', 870], ['S1', 870], ['R2', 1010]], [['P0', 'S1']]] | [[['P0', 870], ['S1', 870], ['R2', 1010]], [['P0', 'S1']]] | Passed |
| normal control 6 | [[['T0', 690], ['S1', 815], ['S2', 1065]], []] | [[['T0', 690], ['S1', 815], ['S2', 1065]], [['T0', 'S1']]] | Failed |
| normal control 7 | [[['W0', 730], ['R1', 870], ['W2', 1150]], []] | [[['W0', 730], ['R1', 870], ['W2', 1150]], []] | Passed |
| normal control 8 | [[['U0', 625], ['P1', 800]], []] | [[['U0', 625], ['P1', 800]], []] | Passed |
SHA-256 / 746bf8d8ae2bc8728020df7bb61196599edffd55ebdc72e8d5aafbad4b7b728b
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(exams, pct, rest):
rows = []
for eid, st, dur in sorted(exams, key=lambda x: (x[1], x[0])):
ext = -(-dur * (100 + pct) // 100)
ext = -(-ext // 5) * 5
rows.append([eid, st, st + ext])
conf = []
for a, b in zip(rows, rows[1:]):
if b[1] < a[2] + rest:
conf.append([a[0], b[0]])
return [[[r[0], r[2]] for r in rows], conf]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: rest boundary 1', [[['A', 540, 120], ['B', 720, 90]], 50, 0], [[['A', 720], ['B', 855]], []]),
('regression variant: rest boundary 2',
[[['V0', 600, 60], ['S1', 840, 100], ['U3', 1320, 91], ['V2', 1080, 182]], 15, 30],
[[['V0', 670], ['S1', 955], ['V2', 1290], ['U3', 1425]], []]),
('partial repair guard 3',
[[['W0', 540, 182], ['S2', 810, 182], ['U3', 1050, 100], ['W1', 660, 44]], 25, 15],
[[['W0', 770], ['W1', 715], ['S2', 1040], ['U3', 1175]], [['W0', 'W1'], ['S2', 'U3']]]),
('boundary control 4', [[['A', 540, 73], ['B', 640, 60]], 10, 15], [[['A', 625], ['B', 710]], []]),
('normal control 5', [[['S1', 800, 44], ['P0', 600, 180], ['R2', 920, 60]], 50, 30],
[[['P0', 870], ['S1', 870], ['R2', 1010]], [['P0', 'S1']]]),
('normal control 6', [[['S2', 840, 180], ['S1', 690, 100], ['T0', 540, 120]], 25, 15],
[[['T0', 690], ['S1', 815], ['S2', 1065]], [['T0', 'S1']]]),
('normal control 7', [[['W2', 960, 150], ['W0', 540, 150], ['R1', 780, 72]], 25, 30],
[[['W0', 730], ['R1', 870], ['W2', 1150]], []]),
('normal control 8', [[['P1', 660, 120], ['U0', 540, 72]], 15, 30], [[['U0', 625], ['P1', 800]], []])],
[('regression: rest boundary 1', [[['A', 540, 73], ['B', 640, 60]], 10, 15], [[['A', 625], ['B', 710]], []]),
('regression variant: rest boundary 2',
[[['W3', 1110, 73], ['R1', 840, 150], ['U0', 600, 100], ['R2', 960, 100]], 33, 15],
[[['U0', 735], ['R1', 1040], ['R2', 1095], ['W3', 1210]], [['R1', 'R2']]]),
('partial repair guard 3', [[['Q1', 800, 88], ['Q0', 600, 60], ['R2', 920, 182]], 10, 30],
[[['Q0', 670], ['Q1', 900], ['R2', 1125]], [['Q1', 'R2']]]),
('boundary control 4', [[['A', 540, 91]], 10, 30], [[['A', 645]], []]),
('boundary control 5', [[['A', 540, 100], ['B', 699, 60]], 25, 30], [[['A', 665], ['B', 774]], []]),
('normal control 6', [[['S1', 690, 88], ['Q2', 780, 150], ['T0', 540, 44]], 33, 30],
[[['T0', 600], ['S1', 810], ['Q2', 980]], [['S1', 'Q2']]]),
('normal control 7', [[['R1', 630, 90], ['S0', 540, 182]], 33, 15],
[[['S0', 785], ['R1', 750]], [['S0', 'R1']]]),
('normal control 8', [[['V0', 600, 182], ['R3', 990, 90], ['S2', 900, 88], ['W1', 780, 73]], 25, 30],
[[['V0', 830], ['W1', 875], ['S2', 1010], ['R3', 1105]], [['V0', 'W1'], ['W1', 'S2'], ['S2', 'R3']]])],
[('regression: rest boundary 1',
[[['S2', 900, 73], ['P1', 780, 60], ['U3', 1050, 44], ['W0', 540, 72]], 50, 30],
[[['W0', 650], ['P1', 870], ['S2', 1010], ['U3', 1120]], []]),
('regression variant: rest boundary 2', [[['A', 540, 120], ['B', 720, 90]], 50, 0],
[[['A', 720], ['B', 855]], []]),
('partial repair guard 3', [[['Q1', 840, 120], ['S0', 600, 182]], 25, 15],
[[['S0', 830], ['Q1', 990]], [['S0', 'Q1']]]),
('boundary control 4', [[['A', 540, 88]], 25, 30], [[['A', 650]], []]),
('boundary control 5', [[['A', 540, 72]], 33, 15], [[['A', 640]], []]),
('normal control 6', [[['P1', 720, 88], ['W2', 920, 90], ['P0', 540, 91]], 25, 15],
[[['P0', 655], ['P1', 830], ['W2', 1035]], []]),
('normal control 7', [[['U2', 810, 180], ['W1', 630, 90], ['V3', 900, 180], ['S0', 540, 182]], 10, 15],
[[['S0', 745], ['W1', 730], ['U2', 1010], ['V3', 1100]], [['S0', 'W1'], ['U2', 'V3']]]),
('normal control 8', [[['W0', 540, 60], ['W1', 780, 44]], 15, 15], [[['W0', 610], ['W1', 835]], []])],
[('regression: rest boundary 1', [[['V1', 750, 150], ['W0', 600, 88]], 33, 30],
[[['W0', 720], ['V1', 950]], []]),
('regression variant: rest boundary 2',
[[['P1', 720, 73], ['R0', 600, 91], ['P2', 960, 91], ['R3', 1050, 182]], 15, 15],
[[['R0', 705], ['P1', 805], ['P2', 1065], ['R3', 1260]], [['P2', 'R3']]]),
('partial repair guard 3', [[['Q2', 870, 91], ['Q0', 600, 100], ['W1', 780, 72]], 25, 30],
[[['Q0', 725], ['W1', 870], ['Q2', 985]], [['W1', 'Q2']]]),
('boundary control 4', [[['A', 540, 120], ['B', 720, 90]], 50, 0], [[['A', 720], ['B', 855]], []]),
('boundary control 5', [[['A', 540, 73], ['B', 640, 60]], 10, 15], [[['A', 625], ['B', 710]], []]),
('normal control 6', [[['T0', 600, 88], ['W3', 1070, 44], ['Q2', 980, 150], ['U1', 780, 120]], 15, 30],
[[['T0', 705], ['U1', 920], ['Q2', 1155], ['W3', 1125]], [['Q2', 'W3']]]),
('normal control 7', [[['S3', 1080, 60], ['V1', 840, 120], ['R0', 600, 44], ['U2', 960, 90]], 15, 15],
[[['R0', 655], ['V1', 980], ['U2', 1065], ['S3', 1150]], [['V1', 'U2']]]),
('normal control 8', [[['V1', 630, 180], ['Q0', 540, 44]], 10, 30], [[['Q0', 590], ['V1', 830]], []])],
[('regression: rest boundary 1',
[[['Q2', 810, 88], ['Q1', 690, 150], ['T0', 540, 73], ['U3', 930, 88]], 15, 15],
[[['T0', 625], ['Q1', 865], ['Q2', 915], ['U3', 1035]], [['Q1', 'Q2']]]),
('regression variant: rest boundary 2', [[['Q0', 540, 120], ['U1', 720, 60]], 25, 30],
[[['Q0', 690], ['U1', 795]], []]),
('partial repair guard 3', [[['P2', 920, 180], ['Q0', 540, 150], ['S1', 740, 88]], 33, 30],
[[['Q0', 740], ['S1', 860], ['P2', 1160]], [['Q0', 'S1']]]),
('boundary control 4', [[['A', 540, 91]], 10, 30], [[['A', 645]], []]),
('boundary control 5', [[['A', 540, 100], ['B', 699, 60]], 25, 30], [[['A', 665], ['B', 774]], []]),
('normal control 6', [[['T1', 840, 72], ['V0', 600, 44]], 10, 15], [[['V0', 650], ['T1', 920]], []]),
('normal control 7', [[['Q1', 690, 150], ['P2', 810, 180], ['Q0', 540, 180]], 10, 15],
[[['Q0', 740], ['Q1', 855], ['P2', 1010]], [['Q0', 'Q1'], ['Q1', 'P2']]]),
('normal control 8', [[['S0', 540, 120], ['U2', 920, 44], ['Q3', 1070, 90], ['W1', 740, 91]], 25, 15],
[[['S0', 690], ['W1', 855], ['U2', 975], ['Q3', 1185]], []])]]
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: rest boundary 1 | [[['A', 720], ['B', 855]], []] | [[['A', 720], ['B', 855]], []] | Passed |
| regression variant: rest boundary 2 | [[['V0', 670], ['S1', 955], ['V2', 1290], ['U3', 1425]], []] | [[['V0', 670], ['S1', 955], ['V2', 1290], ['U3', 1425]], []] | Passed |
| partial repair guard 3 | [[['W0', 770], ['W1', 715], ['S2', 1040], ['U3', 1175]], [['W0', 'W1'], ['S2', 'U3']]] | [[['W0', 770], ['W1', 715], ['S2', 1040], ['U3', 1175]], [['W0', 'W1'], ['S2', 'U3']]] | Passed |
| boundary control 4 | [[['A', 625], ['B', 710]], []] | [[['A', 625], ['B', 710]], []] | Passed |
| normal control 5 | [[['P0', 870], ['S1', 870], ['R2', 1010]], [['P0', 'S1']]] | [[['P0', 870], ['S1', 870], ['R2', 1010]], [['P0', 'S1']]] | Passed |
| normal control 6 | [[['T0', 690], ['S1', 815], ['S2', 1065]], [['T0', 'S1']]] | [[['T0', 690], ['S1', 815], ['S2', 1065]], [['T0', 'S1']]] | Passed |
| normal control 7 | [[['W0', 730], ['R1', 870], ['W2', 1150]], []] | [[['W0', 730], ['R1', 870], ['W2', 1150]], []] | Passed |
| normal control 8 | [[['U0', 625], ['P1', 800]], []] | [[['U0', 625], ['P1', 800]], []] | Passed |
SHA-256 / b2a9c80f580c79bb53431bcf5080458cfc50b51cd83879648ceeaaecffd21a96
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.540070+00:00.
Case digest / 87555c7e9628c28ce851e5e9d3280436397a7ea88ee86b02a99be08b856fbe08