FAILURE MAP
← Case archive

FA-94721 / Exam timetabling constraints / Open access

Day-slot restriction applies only to the named slot · case 01

A Friday-afternoon restriction still allows a Friday-evening exam.

Verified by executionVariant 1 · 8 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The slot rule matches only equality.

VERIFIED REPAIR

A day-slot rule covers the named slot and later slots.

Unsuccessful approach: A strict comparison excludes the named slot itself.

Case contract

sits [student, exam, period]; periods index -> [weekday 0=Mon..6=Sun, slot am/pm/eve]; avoid student -> rules "day" (whole day) or "day-slot" (that slot and later slots that day). Each sitting matching any rule is reported once as [student, exam, period]; return rows sorted.

Why this case matters

Religious-observance and other unavailability constraints are student-specific hard constraints.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(sits, periods, avoid):
    names = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']
    order = ['am', 'pm', 'eve']
    out = []
    for st, ex, p in sits:
        wd, slot = periods[p]
        for rule in avoid.get(st, []):
            parts = rule.split('-')
            if parts[0] != names[wd]:
                continue
            if len(parts) == 1 or order.index(slot) == order.index(parts[1]):
                out.append([st, ex, p])
                break
    return sorted(out)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: slot onward 1', [[['s1', 'A', 0]], [[4, 'eve']], {'s1': ['fri-pm']}], [['s1', 'A', 0]]),
  ('regression variant: slot onward 2',
   [[['s3', 'ECON150', 5], ['s1', 'PHYS110', 5], ['s3', 'BIO130', 4]],
    [[5, 'pm'], [0, 'eve'], [1, 'pm'], [2, 'pm'], [6, 'eve'], [0, 'pm']],
    {'s1': ['fri'], 's2': ['sat', 'sun-am'], 's3': ['sun-am', 'fri']}],
   [['s3', 'BIO130', 4]]),
  ('partial repair guard 3',
   [[['s3', 'MATH101H', 4]], [[6, 'am'], [5, 'eve'], [0, 'am'], [5, 'pm'], [6, 'am'], [6, 'am']],
    {'s1': ['sat', 'sun-am', 'fri-eve'], 's2': ['fri-pm', 'sun-am'], 's3': ['sun-am', 'fri', 'fri-eve']}],
   [['s3', 'MATH101H', 4]]),
  ('boundary control 4', [[['s1', 'A', 0]], [[4, 'eve']], {'s1': ['fri-eve', 'fri-pm']}], [['s1', 'A', 0]]),
  ('normal control 5',
   [[['s2', 'MATH101', 3], ['s1', 'BIO130', 2], ['s2', 'BIO130', 3]],
    [[1, 'pm'], [6, 'am'], [2, 'pm'], [2, 'pm'], [3, 'eve'], [3, 'eve']],
    {'s1': ['fri', 'sat'], 's3': ['sun-am', 'fri']}],
   []),
  ('normal control 6',
   [[['s1', 'CHEM120', 3], ['s1', 'BIO130', 4], ['s2', 'ECON150', 4], ['s1', 'HIST140', 0],
     ['s1', 'CHEM120', 1]],
    [[6, 'pm'], [3, 'pm'], [5, 'pm'], [0, 'eve'], [6, 'am'], [1, 'am']],
    {'s1': ['mon-eve', 'fri', 'sun-am'], 's2': ['sat', 'fri-pm', 'fri']}],
   [['s1', 'BIO130', 4], ['s1', 'CHEM120', 3], ['s1', 'HIST140', 0]]),
  ('normal control 7',
   [[['s1', 'ECON150', 3], ['s1', 'CHEM120', 1], ['s2', 'PHYS110', 2], ['s3', 'MATH101', 1],
     ['s3', 'PHYS110', 1], ['s3', 'ECON150', 1]],
    [[3, 'am'], [1, 'eve'], [1, 'pm'], [3, 'pm'], [1, 'am'], [4, 'am']],
    {'s1': ['sat', 'sun-am', 'fri-eve'], 's2': ['fri-eve'], 's3': ['sat', 'fri-eve', 'fri']}],
   []),
  ('normal control 8',
   [[['s3', 'BIO130', 1]], [[2, 'pm'], [0, 'am'], [2, 'am'], [6, 'eve'], [3, 'pm'], [3, 'eve']],
    {'s1': ['sun-am', 'fri-pm', 'sat'], 's3': ['fri-pm']}],
   [])],
 [('regression: slot onward 1',
   [[['s2', 'PHYS110', 4], ['s3', 'BIO130', 3], ['s1', 'CHEM120', 1], ['s1', 'HIST140', 5],
     ['s3', 'HIST140', 3], ['s3', 'HIST140', 5]],
    [[5, 'eve'], [3, 'eve'], [1, 'eve'], [6, 'eve'], [0, 'am'], [5, 'am']],
    {'s1': ['mon-eve', 'sat'], 's2': ['fri-pm'], 's3': ['mon-eve', 'sun-am']}],
   [['s1', 'HIST140', 5], ['s3', 'BIO130', 3], ['s3', 'HIST140', 3]]),
  ('regression variant: slot onward 2',
   [[['s1', 'PHYS110', 5], ['s3', 'PHYS110', 0], ['s3', 'ECON150', 0], ['s3', 'MATH101', 5],
     ['s2', 'BIO130', 3], ['s1', 'HIST140', 4]],
    [[3, 'am'], [5, 'am'], [1, 'pm'], [0, 'pm'], [5, 'eve'], [6, 'eve']],
    {'s1': ['fri-eve', 'sun-am', 'sat'], 's2': ['fri', 'sat'], 's3': ['sat', 'fri-pm', 'sun-am']}],
   [['s1', 'HIST140', 4], ['s1', 'PHYS110', 5], ['s3', 'MATH101', 5]]),
  ('partial repair guard 3',
   [[['s2', 'BIO130', 5], ['s3', 'MATH101', 3]],
    [[5, 'pm'], [5, 'eve'], [3, 'pm'], [4, 'eve'], [1, 'eve'], [2, 'am']],
    {'s2': ['fri', 'fri-eve', 'mon-eve'], 's3': ['fri-eve']}],
   [['s3', 'MATH101', 3]]),
  ('boundary control 4', [[['s1', 'A', 0]], [[4, 'am']], {'s1': ['fri-pm']}], []),
  ('normal control 5',
   [[['s1', 'HIST140', 4], ['s2', 'BIO130', 5], ['s2', 'ECON150', 5], ['s3', 'BIO130', 2],
     ['s2', 'BIO130', 4], ['s2', 'ECON150', 3]],
    [[3, 'pm'], [5, 'pm'], [1, 'pm'], [4, 'am'], [2, 'eve'], [3, 'am']],
    {'s1': ['sat'], 's3': ['fri', 'fri-eve', 'sun-am']}],
   []),
  ('normal control 6',
   [[['s3', 'MATH101', 3], ['s3', 'CHEM120', 0], ['s1', 'PHYS110', 5], ['s1', 'BIO130', 1]],
    [[3, 'eve'], [0, 'am'], [4, 'eve'], [1, 'am'], [5, 'am'], [4, 'pm']],
    {'s1': ['sun-am', 'fri-pm'], 's2': ['mon-eve', 'sun-am'], 's3': ['sun-am', 'mon-eve']}],
   [['s1', 'PHYS110', 5]]),
  ('normal control 7',
   [[['s3', 'HIST140', 2], ['s1', 'CHEM120', 3], ['s3', 'MATH101', 0], ['s2', 'PHYS110', 5]],
    [[5, 'eve'], [1, 'am'], [0, 'pm'], [5, 'pm'], [1, 'am'], [5, 'pm']],
    {'s2': ['fri-eve', 'fri', 'sat'], 's3': ['fri', 'sat']}],
   [['s2', 'PHYS110', 5], ['s3', 'MATH101', 0]]),
  ('normal control 8',
   [[['s2', 'HIST140', 4]], [[4, 'eve'], [1, 'am'], [3, 'pm'], [2, 'eve'], [1, 'am'], [6, 'am']],
    {'s1': ['sun-am', 'sat'], 's3': ['fri-pm', 'fri']}],
   [])],
 [('regression: slot onward 1',
   [[['s3', 'PHYS110', 5], ['s2', 'MATH101', 5], ['s3', 'MATH101H', 2]],
    [[1, 'am'], [2, 'eve'], [0, 'eve'], [2, 'eve'], [4, 'eve'], [6, 'eve']],
    {'s1': ['fri', 'fri-eve', 'sun-am'], 's2': ['fri-pm'], 's3': ['sun-am', 'fri']}],
   [['s3', 'PHYS110', 5]]),
  ('regression variant: slot onward 2',
   [[['s1', 'BIO130', 4], ['s3', 'MATH101H', 3], ['s2', 'CHEM120', 5], ['s1', 'MATH101', 3],
     ['s3', 'MATH101', 4]],
    [[5, 'eve'], [6, 'am'], [2, 'eve'], [4, 'eve'], [2, 'eve'], [5, 'am']],
    {'s1': ['sat', 'fri-pm'], 's2': ['sat', 'fri-pm', 'fri'], 's3': ['sat', 'sun-am']}],
   [['s1', 'MATH101', 3], ['s2', 'CHEM120', 5]]),
  ('partial repair guard 3',
   [[['s2', 'MATH101', 0], ['s1', 'PHYS110', 1]],
    [[0, 'eve'], [0, 'pm'], [2, 'pm'], [5, 'pm'], [5, 'pm'], [1, 'am']],
    {'s1': ['sun-am'], 's2': ['sun-am', 'mon-eve'], 's3': ['sun-am', 'sat']}],
   [['s2', 'MATH101', 0]]),
  ('boundary control 4', [[['s1', 'A', 0]], [[0, 'am']], {'s1': ['sun']}], []),
  ('normal control 5',
   [[['s1', 'ECON150', 5], ['s1', 'HIST140', 3], ['s3', 'HIST140', 3], ['s2', 'PHYS110', 5],
     ['s3', 'BIO130', 4], ['s3', 'BIO130', 4]],
    [[0, 'pm'], [5, 'eve'], [4, 'pm'], [1, 'pm'], [2, 'eve'], [0, 'pm']],
    {'s1': ['mon-eve'], 's2': ['fri-eve', 'sun-am'], 's3': ['mon-eve']}],
   []),
  ('normal control 6',
   [[['s3', 'MATH101', 1], ['s1', 'HIST140', 1], ['s3', 'ECON150', 5]],
    [[6, 'am'], [4, 'pm'], [6, 'eve'], [6, 'am'], [3, 'am'], [5, 'pm']],
    {'s1': ['sun-am', 'fri-eve', 'sat'], 's2': ['sun-am'], 's3': ['fri-eve']}],
   []),
  ('normal control 7',
   [[['s3', 'PHYS110', 2], ['s1', 'MATH101H', 5]],
    [[2, 'pm'], [2, 'pm'], [1, 'am'], [3, 'pm'], [2, 'am'], [5, 'eve']],
    {'s1': ['mon-eve'], 's2': ['fri-eve', 'sat'], 's3': ['fri-pm', 'sat']}],
   []),
  ('normal control 8',
   [[['s1', 'ECON150', 4], ['s2', 'CHEM120', 4], ['s1', 'BIO130', 0], ['s2', 'ECON150', 4],
     ['s3', 'CHEM120', 3], ['s3', 'MATH101H', 0]],
    [[0, 'pm'], [1, 'pm'], [5, 'pm'], [1, 'eve'], [0, 'pm'], [5, 'eve']],
    {'s1': ['fri-eve'], 's2': ['fri'], 's3': ['sun-am']}],
   [])],
 [('regression: slot onward 1',
   [[['s1', 'HIST140', 4]], [[4, 'eve'], [3, 'am'], [5, 'eve'], [6, 'pm'], [6, 'eve'], [6, 'pm']],
    {'s1': ['fri-pm', 'fri-eve', 'sun-am'], 's2': ['mon-eve', 'fri'], 's3': ['fri', 'fri-eve']}],
   [['s1', 'HIST140', 4]]),
  ('regression variant: slot onward 2',
   [[['s1', 'CHEM120', 4], ['s2', 'ECON150', 4], ['s3', 'CHEM120', 4], ['s3', 'MATH101H', 0],
     ['s2', 'PHYS110', 2]],
    [[3, 'pm'], [2, 'pm'], [3, 'pm'], [1, 'pm'], [6, 'eve'], [4, 'eve']],
    {'s3': ['sun-am', 'sat', 'fri-eve']}],
   [['s3', 'CHEM120', 4]]),
  ('partial repair guard 3',
   [[['s2', 'BIO130', 4], ['s1', 'ECON150', 1], ['s2', 'BIO130', 1], ['s2', 'ECON150', 1]],
    [[6, 'eve'], [5, 'eve'], [1, 'pm'], [5, 'eve'], [6, 'am'], [3, 'eve']],
    {'s1': ['fri-eve', 'sun-am', 'sat'], 's2': ['fri', 'fri-eve', 'sun-am'], 's3': ['sat']}],
   [['s1', 'ECON150', 1], ['s2', 'BIO130', 4]]),
  ('boundary control 4', [[['s1', 'A', 0]], [[5, 'am']], {'s1': ['sat', 'fri-pm']}], [['s1', 'A', 0]]),
  ('normal control 5',
   [[['s3', 'ECON150', 5], ['s1', 'PHYS110', 5], ['s3', 'BIO130', 4]],
    [[5, 'pm'], [0, 'eve'], [1, 'pm'], [2, 'pm'], [6, 'eve'], [0, 'pm']],
    {'s1': ['fri'], 's2': ['sat', 'sun-am'], 's3': ['sun-am', 'fri']}],
   [['s3', 'BIO130', 4]]),
  ('normal control 6',
   [[['s1', 'CHEM120', 5], ['s2', 'CHEM120', 3], ['s2', 'MATH101H', 1], ['s2', 'MATH101', 0],
     ['s3', 'MATH101', 3]],
    [[0, 'eve'], [1, 'am'], [5, 'am'], [4, 'pm'], [4, 'eve'], [1, 'eve']],
    {'s1': ['fri-pm', 'fri-eve'], 's2': ['fri-pm']}],
   [['s2', 'CHEM120', 3]]),
  ('normal control 7',
   [[['s2', 'PHYS110', 1], ['s2', 'ECON150', 2], ['s2', 'BIO130', 0], ['s3', 'CHEM120', 2]],
    [[1, 'eve'], [0, 'eve'], [5, 'eve'], [3, 'am'], [1, 'am'], [2, 'am']],
    {'s1': ['fri-pm'], 's2': ['mon-eve'], 's3': ['sat', 'fri-eve', 'fri']}],
   [['s2', 'PHYS110', 1], ['s3', 'CHEM120', 2]]),
  ('normal control 8',
   [[['s2', 'BIO130', 1], ['s1', 'ECON150', 0], ['s2', 'BIO130', 0], ['s2', 'CHEM120', 0]],
    [[0, 'eve'], [5, 'am'], [0, 'pm'], [3, 'eve'], [1, 'eve'], [6, 'pm']],
    {'s1': ['sun-am', 'mon-eve'], 's2': ['fri-pm', 'sun-am'], 's3': ['sat', 'fri-eve']}],
   [['s1', 'ECON150', 0]])],
 [('regression: slot onward 1',
   [[['s3', 'BIO130', 4], ['s3', 'MATH101', 1], ['s3', 'ECON150', 4], ['s2', 'CHEM120', 0]],
    [[6, 'pm'], [5, 'pm'], [1, 'eve'], [4, 'eve'], [3, 'am'], [3, 'pm']],
    {'s2': ['sun-am'], 's3': ['fri-eve', 'fri']}],
   [['s2', 'CHEM120', 0]]),
  ('regression variant: slot onward 2',
   [[['s3', 'ECON150', 2], ['s3', 'HIST140', 5], ['s1', 'PHYS110', 4]],
    [[2, 'am'], [2, 'pm'], [6, 'eve'], [1, 'eve'], [2, 'pm'], [2, 'pm']],
    {'s1': ['sat', 'fri', 'mon-eve'], 's2': ['sat'], 's3': ['sun-am', 'fri']}],
   [['s3', 'ECON150', 2]]),
  ('partial repair guard 3',
   [[['s2', 'ECON150', 3], ['s2', 'CHEM120', 4]],
    [[2, 'pm'], [2, 'pm'], [2, 'eve'], [0, 'eve'], [6, 'am'], [1, 'eve']],
    {'s2': ['sun-am', 'fri'], 's3': ['fri-eve', 'fri-pm', 'fri']}],
   [['s2', 'CHEM120', 4]]),
  ('boundary control 4', [[['s1', 'A', 0]], [[4, 'eve']], {'s1': ['fri-pm']}], [['s1', 'A', 0]]),
  ('normal control 5',
   [[['s1', 'MATH101H', 3], ['s1', 'ECON150', 2], ['s1', 'HIST140', 2], ['s2', 'MATH101', 3],
     ['s2', 'ECON150', 1]],
    [[2, 'am'], [5, 'eve'], [3, 'am'], [1, 'eve'], [0, 'eve'], [2, 'am']],
    {'s1': ['mon-eve', 'fri-eve'], 's2': ['fri-pm', 'fri-eve', 'mon-eve'], 's3': ['fri', 'sat', 'fri-pm']}],
   []),
  ('normal control 6',
   [[['s1', 'MATH101H', 4], ['s3', 'BIO130', 1], ['s3', 'BIO130', 2], ['s3', 'BIO130', 3],
     ['s1', 'ECON150', 4], ['s1', 'PHYS110', 3]],
    [[0, 'am'], [1, 'eve'], [3, 'eve'], [6, 'pm'], [5, 'eve'], [2, 'eve']], {'s2': ['sat']}],
   []),
  ('normal control 7',
   [[['s3', 'MATH101', 5], ['s2', 'MATH101H', 4]],
    [[3, 'eve'], [2, 'eve'], [2, 'am'], [1, 'pm'], [0, 'eve'], [2, 'pm']],
    {'s1': ['fri-pm', 'mon-eve', 'sun-am'], 's3': ['fri']}],
   []),
  ('normal control 8',
   [[['s2', 'HIST140', 3], ['s3', 'CHEM120', 1], ['s3', 'HIST140', 0], ['s2', 'ECON150', 3]],
    [[3, 'pm'], [6, 'pm'], [3, 'pm'], [0, 'pm'], [1, 'eve'], [1, 'pm']],
    {'s1': ['mon-eve', 'fri-eve', 'fri-pm'], 's2': ['mon-eve', 'sun-am'], 's3': ['fri-eve']}],
   [])]]
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 fixtureActualExpectedOutcome
regression: slot onward 1[][['s1', 'A', 0]]Failed
regression variant: slot onward 2[][['s3', 'BIO130', 4]]Failed
partial repair guard 3[['s3', 'MATH101H', 4]][['s3', 'MATH101H', 4]]Passed
boundary control 4[['s1', 'A', 0]][['s1', 'A', 0]]Passed
normal control 5[][]Passed
normal control 6[['s1', 'BIO130', 4], ['s1', 'CHEM120', 3]][['s1', 'BIO130', 4], ['s1', 'CHEM120', 3], ['s1', 'HIST140', 0]]Failed
normal control 7[][]Passed
normal control 8[][]Passed

SHA-256 / 2bf802598d9de19ed91cc207c5f91d765fe70ef19df8958a9cc6b12b48bc9d53

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(sits, periods, avoid):
    names = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']
    order = ['am', 'pm', 'eve']
    out = []
    for st, ex, p in sits:
        wd, slot = periods[p]
        for rule in avoid.get(st, []):
            parts = rule.split('-')
            if parts[0] != names[wd]:
                continue
            if len(parts) == 1 or order.index(slot) > order.index(parts[1]):
                out.append([st, ex, p])
                break
    return sorted(out)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: slot onward 1', [[['s1', 'A', 0]], [[4, 'eve']], {'s1': ['fri-pm']}], [['s1', 'A', 0]]),
  ('regression variant: slot onward 2',
   [[['s3', 'ECON150', 5], ['s1', 'PHYS110', 5], ['s3', 'BIO130', 4]],
    [[5, 'pm'], [0, 'eve'], [1, 'pm'], [2, 'pm'], [6, 'eve'], [0, 'pm']],
    {'s1': ['fri'], 's2': ['sat', 'sun-am'], 's3': ['sun-am', 'fri']}],
   [['s3', 'BIO130', 4]]),
  ('partial repair guard 3',
   [[['s3', 'MATH101H', 4]], [[6, 'am'], [5, 'eve'], [0, 'am'], [5, 'pm'], [6, 'am'], [6, 'am']],
    {'s1': ['sat', 'sun-am', 'fri-eve'], 's2': ['fri-pm', 'sun-am'], 's3': ['sun-am', 'fri', 'fri-eve']}],
   [['s3', 'MATH101H', 4]]),
  ('boundary control 4', [[['s1', 'A', 0]], [[4, 'eve']], {'s1': ['fri-eve', 'fri-pm']}], [['s1', 'A', 0]]),
  ('normal control 5',
   [[['s2', 'MATH101', 3], ['s1', 'BIO130', 2], ['s2', 'BIO130', 3]],
    [[1, 'pm'], [6, 'am'], [2, 'pm'], [2, 'pm'], [3, 'eve'], [3, 'eve']],
    {'s1': ['fri', 'sat'], 's3': ['sun-am', 'fri']}],
   []),
  ('normal control 6',
   [[['s1', 'CHEM120', 3], ['s1', 'BIO130', 4], ['s2', 'ECON150', 4], ['s1', 'HIST140', 0],
     ['s1', 'CHEM120', 1]],
    [[6, 'pm'], [3, 'pm'], [5, 'pm'], [0, 'eve'], [6, 'am'], [1, 'am']],
    {'s1': ['mon-eve', 'fri', 'sun-am'], 's2': ['sat', 'fri-pm', 'fri']}],
   [['s1', 'BIO130', 4], ['s1', 'CHEM120', 3], ['s1', 'HIST140', 0]]),
  ('normal control 7',
   [[['s1', 'ECON150', 3], ['s1', 'CHEM120', 1], ['s2', 'PHYS110', 2], ['s3', 'MATH101', 1],
     ['s3', 'PHYS110', 1], ['s3', 'ECON150', 1]],
    [[3, 'am'], [1, 'eve'], [1, 'pm'], [3, 'pm'], [1, 'am'], [4, 'am']],
    {'s1': ['sat', 'sun-am', 'fri-eve'], 's2': ['fri-eve'], 's3': ['sat', 'fri-eve', 'fri']}],
   []),
  ('normal control 8',
   [[['s3', 'BIO130', 1]], [[2, 'pm'], [0, 'am'], [2, 'am'], [6, 'eve'], [3, 'pm'], [3, 'eve']],
    {'s1': ['sun-am', 'fri-pm', 'sat'], 's3': ['fri-pm']}],
   [])],
 [('regression: slot onward 1',
   [[['s2', 'PHYS110', 4], ['s3', 'BIO130', 3], ['s1', 'CHEM120', 1], ['s1', 'HIST140', 5],
     ['s3', 'HIST140', 3], ['s3', 'HIST140', 5]],
    [[5, 'eve'], [3, 'eve'], [1, 'eve'], [6, 'eve'], [0, 'am'], [5, 'am']],
    {'s1': ['mon-eve', 'sat'], 's2': ['fri-pm'], 's3': ['mon-eve', 'sun-am']}],
   [['s1', 'HIST140', 5], ['s3', 'BIO130', 3], ['s3', 'HIST140', 3]]),
  ('regression variant: slot onward 2',
   [[['s1', 'PHYS110', 5], ['s3', 'PHYS110', 0], ['s3', 'ECON150', 0], ['s3', 'MATH101', 5],
     ['s2', 'BIO130', 3], ['s1', 'HIST140', 4]],
    [[3, 'am'], [5, 'am'], [1, 'pm'], [0, 'pm'], [5, 'eve'], [6, 'eve']],
    {'s1': ['fri-eve', 'sun-am', 'sat'], 's2': ['fri', 'sat'], 's3': ['sat', 'fri-pm', 'sun-am']}],
   [['s1', 'HIST140', 4], ['s1', 'PHYS110', 5], ['s3', 'MATH101', 5]]),
  ('partial repair guard 3',
   [[['s2', 'BIO130', 5], ['s3', 'MATH101', 3]],
    [[5, 'pm'], [5, 'eve'], [3, 'pm'], [4, 'eve'], [1, 'eve'], [2, 'am']],
    {'s2': ['fri', 'fri-eve', 'mon-eve'], 's3': ['fri-eve']}],
   [['s3', 'MATH101', 3]]),
  ('boundary control 4', [[['s1', 'A', 0]], [[4, 'am']], {'s1': ['fri-pm']}], []),
  ('normal control 5',
   [[['s1', 'HIST140', 4], ['s2', 'BIO130', 5], ['s2', 'ECON150', 5], ['s3', 'BIO130', 2],
     ['s2', 'BIO130', 4], ['s2', 'ECON150', 3]],
    [[3, 'pm'], [5, 'pm'], [1, 'pm'], [4, 'am'], [2, 'eve'], [3, 'am']],
    {'s1': ['sat'], 's3': ['fri', 'fri-eve', 'sun-am']}],
   []),
  ('normal control 6',
   [[['s3', 'MATH101', 3], ['s3', 'CHEM120', 0], ['s1', 'PHYS110', 5], ['s1', 'BIO130', 1]],
    [[3, 'eve'], [0, 'am'], [4, 'eve'], [1, 'am'], [5, 'am'], [4, 'pm']],
    {'s1': ['sun-am', 'fri-pm'], 's2': ['mon-eve', 'sun-am'], 's3': ['sun-am', 'mon-eve']}],
   [['s1', 'PHYS110', 5]]),
  ('normal control 7',
   [[['s3', 'HIST140', 2], ['s1', 'CHEM120', 3], ['s3', 'MATH101', 0], ['s2', 'PHYS110', 5]],
    [[5, 'eve'], [1, 'am'], [0, 'pm'], [5, 'pm'], [1, 'am'], [5, 'pm']],
    {'s2': ['fri-eve', 'fri', 'sat'], 's3': ['fri', 'sat']}],
   [['s2', 'PHYS110', 5], ['s3', 'MATH101', 0]]),
  ('normal control 8',
   [[['s2', 'HIST140', 4]], [[4, 'eve'], [1, 'am'], [3, 'pm'], [2, 'eve'], [1, 'am'], [6, 'am']],
    {'s1': ['sun-am', 'sat'], 's3': ['fri-pm', 'fri']}],
   [])],
 [('regression: slot onward 1',
   [[['s3', 'PHYS110', 5], ['s2', 'MATH101', 5], ['s3', 'MATH101H', 2]],
    [[1, 'am'], [2, 'eve'], [0, 'eve'], [2, 'eve'], [4, 'eve'], [6, 'eve']],
    {'s1': ['fri', 'fri-eve', 'sun-am'], 's2': ['fri-pm'], 's3': ['sun-am', 'fri']}],
   [['s3', 'PHYS110', 5]]),
  ('regression variant: slot onward 2',
   [[['s1', 'BIO130', 4], ['s3', 'MATH101H', 3], ['s2', 'CHEM120', 5], ['s1', 'MATH101', 3],
     ['s3', 'MATH101', 4]],
    [[5, 'eve'], [6, 'am'], [2, 'eve'], [4, 'eve'], [2, 'eve'], [5, 'am']],
    {'s1': ['sat', 'fri-pm'], 's2': ['sat', 'fri-pm', 'fri'], 's3': ['sat', 'sun-am']}],
   [['s1', 'MATH101', 3], ['s2', 'CHEM120', 5]]),
  ('partial repair guard 3',
   [[['s2', 'MATH101', 0], ['s1', 'PHYS110', 1]],
    [[0, 'eve'], [0, 'pm'], [2, 'pm'], [5, 'pm'], [5, 'pm'], [1, 'am']],
    {'s1': ['sun-am'], 's2': ['sun-am', 'mon-eve'], 's3': ['sun-am', 'sat']}],
   [['s2', 'MATH101', 0]]),
  ('boundary control 4', [[['s1', 'A', 0]], [[0, 'am']], {'s1': ['sun']}], []),
  ('normal control 5',
   [[['s1', 'ECON150', 5], ['s1', 'HIST140', 3], ['s3', 'HIST140', 3], ['s2', 'PHYS110', 5],
     ['s3', 'BIO130', 4], ['s3', 'BIO130', 4]],
    [[0, 'pm'], [5, 'eve'], [4, 'pm'], [1, 'pm'], [2, 'eve'], [0, 'pm']],
    {'s1': ['mon-eve'], 's2': ['fri-eve', 'sun-am'], 's3': ['mon-eve']}],
   []),
  ('normal control 6',
   [[['s3', 'MATH101', 1], ['s1', 'HIST140', 1], ['s3', 'ECON150', 5]],
    [[6, 'am'], [4, 'pm'], [6, 'eve'], [6, 'am'], [3, 'am'], [5, 'pm']],
    {'s1': ['sun-am', 'fri-eve', 'sat'], 's2': ['sun-am'], 's3': ['fri-eve']}],
   []),
  ('normal control 7',
   [[['s3', 'PHYS110', 2], ['s1', 'MATH101H', 5]],
    [[2, 'pm'], [2, 'pm'], [1, 'am'], [3, 'pm'], [2, 'am'], [5, 'eve']],
    {'s1': ['mon-eve'], 's2': ['fri-eve', 'sat'], 's3': ['fri-pm', 'sat']}],
   []),
  ('normal control 8',
   [[['s1', 'ECON150', 4], ['s2', 'CHEM120', 4], ['s1', 'BIO130', 0], ['s2', 'ECON150', 4],
     ['s3', 'CHEM120', 3], ['s3', 'MATH101H', 0]],
    [[0, 'pm'], [1, 'pm'], [5, 'pm'], [1, 'eve'], [0, 'pm'], [5, 'eve']],
    {'s1': ['fri-eve'], 's2': ['fri'], 's3': ['sun-am']}],
   [])],
 [('regression: slot onward 1',
   [[['s1', 'HIST140', 4]], [[4, 'eve'], [3, 'am'], [5, 'eve'], [6, 'pm'], [6, 'eve'], [6, 'pm']],
    {'s1': ['fri-pm', 'fri-eve', 'sun-am'], 's2': ['mon-eve', 'fri'], 's3': ['fri', 'fri-eve']}],
   [['s1', 'HIST140', 4]]),
  ('regression variant: slot onward 2',
   [[['s1', 'CHEM120', 4], ['s2', 'ECON150', 4], ['s3', 'CHEM120', 4], ['s3', 'MATH101H', 0],
     ['s2', 'PHYS110', 2]],
    [[3, 'pm'], [2, 'pm'], [3, 'pm'], [1, 'pm'], [6, 'eve'], [4, 'eve']],
    {'s3': ['sun-am', 'sat', 'fri-eve']}],
   [['s3', 'CHEM120', 4]]),
  ('partial repair guard 3',
   [[['s2', 'BIO130', 4], ['s1', 'ECON150', 1], ['s2', 'BIO130', 1], ['s2', 'ECON150', 1]],
    [[6, 'eve'], [5, 'eve'], [1, 'pm'], [5, 'eve'], [6, 'am'], [3, 'eve']],
    {'s1': ['fri-eve', 'sun-am', 'sat'], 's2': ['fri', 'fri-eve', 'sun-am'], 's3': ['sat']}],
   [['s1', 'ECON150', 1], ['s2', 'BIO130', 4]]),
  ('boundary control 4', [[['s1', 'A', 0]], [[5, 'am']], {'s1': ['sat', 'fri-pm']}], [['s1', 'A', 0]]),
  ('normal control 5',
   [[['s3', 'ECON150', 5], ['s1', 'PHYS110', 5], ['s3', 'BIO130', 4]],
    [[5, 'pm'], [0, 'eve'], [1, 'pm'], [2, 'pm'], [6, 'eve'], [0, 'pm']],
    {'s1': ['fri'], 's2': ['sat', 'sun-am'], 's3': ['sun-am', 'fri']}],
   [['s3', 'BIO130', 4]]),
  ('normal control 6',
   [[['s1', 'CHEM120', 5], ['s2', 'CHEM120', 3], ['s2', 'MATH101H', 1], ['s2', 'MATH101', 0],
     ['s3', 'MATH101', 3]],
    [[0, 'eve'], [1, 'am'], [5, 'am'], [4, 'pm'], [4, 'eve'], [1, 'eve']],
    {'s1': ['fri-pm', 'fri-eve'], 's2': ['fri-pm']}],
   [['s2', 'CHEM120', 3]]),
  ('normal control 7',
   [[['s2', 'PHYS110', 1], ['s2', 'ECON150', 2], ['s2', 'BIO130', 0], ['s3', 'CHEM120', 2]],
    [[1, 'eve'], [0, 'eve'], [5, 'eve'], [3, 'am'], [1, 'am'], [2, 'am']],
    {'s1': ['fri-pm'], 's2': ['mon-eve'], 's3': ['sat', 'fri-eve', 'fri']}],
   [['s2', 'PHYS110', 1], ['s3', 'CHEM120', 2]]),
  ('normal control 8',
   [[['s2', 'BIO130', 1], ['s1', 'ECON150', 0], ['s2', 'BIO130', 0], ['s2', 'CHEM120', 0]],
    [[0, 'eve'], [5, 'am'], [0, 'pm'], [3, 'eve'], [1, 'eve'], [6, 'pm']],
    {'s1': ['sun-am', 'mon-eve'], 's2': ['fri-pm', 'sun-am'], 's3': ['sat', 'fri-eve']}],
   [['s1', 'ECON150', 0]])],
 [('regression: slot onward 1',
   [[['s3', 'BIO130', 4], ['s3', 'MATH101', 1], ['s3', 'ECON150', 4], ['s2', 'CHEM120', 0]],
    [[6, 'pm'], [5, 'pm'], [1, 'eve'], [4, 'eve'], [3, 'am'], [3, 'pm']],
    {'s2': ['sun-am'], 's3': ['fri-eve', 'fri']}],
   [['s2', 'CHEM120', 0]]),
  ('regression variant: slot onward 2',
   [[['s3', 'ECON150', 2], ['s3', 'HIST140', 5], ['s1', 'PHYS110', 4]],
    [[2, 'am'], [2, 'pm'], [6, 'eve'], [1, 'eve'], [2, 'pm'], [2, 'pm']],
    {'s1': ['sat', 'fri', 'mon-eve'], 's2': ['sat'], 's3': ['sun-am', 'fri']}],
   [['s3', 'ECON150', 2]]),
  ('partial repair guard 3',
   [[['s2', 'ECON150', 3], ['s2', 'CHEM120', 4]],
    [[2, 'pm'], [2, 'pm'], [2, 'eve'], [0, 'eve'], [6, 'am'], [1, 'eve']],
    {'s2': ['sun-am', 'fri'], 's3': ['fri-eve', 'fri-pm', 'fri']}],
   [['s2', 'CHEM120', 4]]),
  ('boundary control 4', [[['s1', 'A', 0]], [[4, 'eve']], {'s1': ['fri-pm']}], [['s1', 'A', 0]]),
  ('normal control 5',
   [[['s1', 'MATH101H', 3], ['s1', 'ECON150', 2], ['s1', 'HIST140', 2], ['s2', 'MATH101', 3],
     ['s2', 'ECON150', 1]],
    [[2, 'am'], [5, 'eve'], [3, 'am'], [1, 'eve'], [0, 'eve'], [2, 'am']],
    {'s1': ['mon-eve', 'fri-eve'], 's2': ['fri-pm', 'fri-eve', 'mon-eve'], 's3': ['fri', 'sat', 'fri-pm']}],
   []),
  ('normal control 6',
   [[['s1', 'MATH101H', 4], ['s3', 'BIO130', 1], ['s3', 'BIO130', 2], ['s3', 'BIO130', 3],
     ['s1', 'ECON150', 4], ['s1', 'PHYS110', 3]],
    [[0, 'am'], [1, 'eve'], [3, 'eve'], [6, 'pm'], [5, 'eve'], [2, 'eve']], {'s2': ['sat']}],
   []),
  ('normal control 7',
   [[['s3', 'MATH101', 5], ['s2', 'MATH101H', 4]],
    [[3, 'eve'], [2, 'eve'], [2, 'am'], [1, 'pm'], [0, 'eve'], [2, 'pm']],
    {'s1': ['fri-pm', 'mon-eve', 'sun-am'], 's3': ['fri']}],
   []),
  ('normal control 8',
   [[['s2', 'HIST140', 3], ['s3', 'CHEM120', 1], ['s3', 'HIST140', 0], ['s2', 'ECON150', 3]],
    [[3, 'pm'], [6, 'pm'], [3, 'pm'], [0, 'pm'], [1, 'eve'], [1, 'pm']],
    {'s1': ['mon-eve', 'fri-eve', 'fri-pm'], 's2': ['mon-eve', 'sun-am'], 's3': ['fri-eve']}],
   [])]]
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 fixtureActualExpectedOutcome
regression: slot onward 1[['s1', 'A', 0]][['s1', 'A', 0]]Passed
regression variant: slot onward 2[['s3', 'BIO130', 4]][['s3', 'BIO130', 4]]Passed
partial repair guard 3[][['s3', 'MATH101H', 4]]Failed
boundary control 4[['s1', 'A', 0]][['s1', 'A', 0]]Passed
normal control 5[][]Passed
normal control 6[['s1', 'HIST140', 0]][['s1', 'BIO130', 4], ['s1', 'CHEM120', 3], ['s1', 'HIST140', 0]]Failed
normal control 7[][]Passed
normal control 8[][]Passed

SHA-256 / 289204c86855d9b40ff2735825b41843efaa0487ef0c29b2ca091c1ad0a06da7

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(sits, periods, avoid):
    names = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']
    order = ['am', 'pm', 'eve']
    out = []
    for st, ex, p in sits:
        wd, slot = periods[p]
        for rule in avoid.get(st, []):
            parts = rule.split('-')
            if parts[0] != names[wd]:
                continue
            if len(parts) == 1 or order.index(slot) >= order.index(parts[1]):
                out.append([st, ex, p])
                break
    return sorted(out)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: slot onward 1', [[['s1', 'A', 0]], [[4, 'eve']], {'s1': ['fri-pm']}], [['s1', 'A', 0]]),
  ('regression variant: slot onward 2',
   [[['s3', 'ECON150', 5], ['s1', 'PHYS110', 5], ['s3', 'BIO130', 4]],
    [[5, 'pm'], [0, 'eve'], [1, 'pm'], [2, 'pm'], [6, 'eve'], [0, 'pm']],
    {'s1': ['fri'], 's2': ['sat', 'sun-am'], 's3': ['sun-am', 'fri']}],
   [['s3', 'BIO130', 4]]),
  ('partial repair guard 3',
   [[['s3', 'MATH101H', 4]], [[6, 'am'], [5, 'eve'], [0, 'am'], [5, 'pm'], [6, 'am'], [6, 'am']],
    {'s1': ['sat', 'sun-am', 'fri-eve'], 's2': ['fri-pm', 'sun-am'], 's3': ['sun-am', 'fri', 'fri-eve']}],
   [['s3', 'MATH101H', 4]]),
  ('boundary control 4', [[['s1', 'A', 0]], [[4, 'eve']], {'s1': ['fri-eve', 'fri-pm']}], [['s1', 'A', 0]]),
  ('normal control 5',
   [[['s2', 'MATH101', 3], ['s1', 'BIO130', 2], ['s2', 'BIO130', 3]],
    [[1, 'pm'], [6, 'am'], [2, 'pm'], [2, 'pm'], [3, 'eve'], [3, 'eve']],
    {'s1': ['fri', 'sat'], 's3': ['sun-am', 'fri']}],
   []),
  ('normal control 6',
   [[['s1', 'CHEM120', 3], ['s1', 'BIO130', 4], ['s2', 'ECON150', 4], ['s1', 'HIST140', 0],
     ['s1', 'CHEM120', 1]],
    [[6, 'pm'], [3, 'pm'], [5, 'pm'], [0, 'eve'], [6, 'am'], [1, 'am']],
    {'s1': ['mon-eve', 'fri', 'sun-am'], 's2': ['sat', 'fri-pm', 'fri']}],
   [['s1', 'BIO130', 4], ['s1', 'CHEM120', 3], ['s1', 'HIST140', 0]]),
  ('normal control 7',
   [[['s1', 'ECON150', 3], ['s1', 'CHEM120', 1], ['s2', 'PHYS110', 2], ['s3', 'MATH101', 1],
     ['s3', 'PHYS110', 1], ['s3', 'ECON150', 1]],
    [[3, 'am'], [1, 'eve'], [1, 'pm'], [3, 'pm'], [1, 'am'], [4, 'am']],
    {'s1': ['sat', 'sun-am', 'fri-eve'], 's2': ['fri-eve'], 's3': ['sat', 'fri-eve', 'fri']}],
   []),
  ('normal control 8',
   [[['s3', 'BIO130', 1]], [[2, 'pm'], [0, 'am'], [2, 'am'], [6, 'eve'], [3, 'pm'], [3, 'eve']],
    {'s1': ['sun-am', 'fri-pm', 'sat'], 's3': ['fri-pm']}],
   [])],
 [('regression: slot onward 1',
   [[['s2', 'PHYS110', 4], ['s3', 'BIO130', 3], ['s1', 'CHEM120', 1], ['s1', 'HIST140', 5],
     ['s3', 'HIST140', 3], ['s3', 'HIST140', 5]],
    [[5, 'eve'], [3, 'eve'], [1, 'eve'], [6, 'eve'], [0, 'am'], [5, 'am']],
    {'s1': ['mon-eve', 'sat'], 's2': ['fri-pm'], 's3': ['mon-eve', 'sun-am']}],
   [['s1', 'HIST140', 5], ['s3', 'BIO130', 3], ['s3', 'HIST140', 3]]),
  ('regression variant: slot onward 2',
   [[['s1', 'PHYS110', 5], ['s3', 'PHYS110', 0], ['s3', 'ECON150', 0], ['s3', 'MATH101', 5],
     ['s2', 'BIO130', 3], ['s1', 'HIST140', 4]],
    [[3, 'am'], [5, 'am'], [1, 'pm'], [0, 'pm'], [5, 'eve'], [6, 'eve']],
    {'s1': ['fri-eve', 'sun-am', 'sat'], 's2': ['fri', 'sat'], 's3': ['sat', 'fri-pm', 'sun-am']}],
   [['s1', 'HIST140', 4], ['s1', 'PHYS110', 5], ['s3', 'MATH101', 5]]),
  ('partial repair guard 3',
   [[['s2', 'BIO130', 5], ['s3', 'MATH101', 3]],
    [[5, 'pm'], [5, 'eve'], [3, 'pm'], [4, 'eve'], [1, 'eve'], [2, 'am']],
    {'s2': ['fri', 'fri-eve', 'mon-eve'], 's3': ['fri-eve']}],
   [['s3', 'MATH101', 3]]),
  ('boundary control 4', [[['s1', 'A', 0]], [[4, 'am']], {'s1': ['fri-pm']}], []),
  ('normal control 5',
   [[['s1', 'HIST140', 4], ['s2', 'BIO130', 5], ['s2', 'ECON150', 5], ['s3', 'BIO130', 2],
     ['s2', 'BIO130', 4], ['s2', 'ECON150', 3]],
    [[3, 'pm'], [5, 'pm'], [1, 'pm'], [4, 'am'], [2, 'eve'], [3, 'am']],
    {'s1': ['sat'], 's3': ['fri', 'fri-eve', 'sun-am']}],
   []),
  ('normal control 6',
   [[['s3', 'MATH101', 3], ['s3', 'CHEM120', 0], ['s1', 'PHYS110', 5], ['s1', 'BIO130', 1]],
    [[3, 'eve'], [0, 'am'], [4, 'eve'], [1, 'am'], [5, 'am'], [4, 'pm']],
    {'s1': ['sun-am', 'fri-pm'], 's2': ['mon-eve', 'sun-am'], 's3': ['sun-am', 'mon-eve']}],
   [['s1', 'PHYS110', 5]]),
  ('normal control 7',
   [[['s3', 'HIST140', 2], ['s1', 'CHEM120', 3], ['s3', 'MATH101', 0], ['s2', 'PHYS110', 5]],
    [[5, 'eve'], [1, 'am'], [0, 'pm'], [5, 'pm'], [1, 'am'], [5, 'pm']],
    {'s2': ['fri-eve', 'fri', 'sat'], 's3': ['fri', 'sat']}],
   [['s2', 'PHYS110', 5], ['s3', 'MATH101', 0]]),
  ('normal control 8',
   [[['s2', 'HIST140', 4]], [[4, 'eve'], [1, 'am'], [3, 'pm'], [2, 'eve'], [1, 'am'], [6, 'am']],
    {'s1': ['sun-am', 'sat'], 's3': ['fri-pm', 'fri']}],
   [])],
 [('regression: slot onward 1',
   [[['s3', 'PHYS110', 5], ['s2', 'MATH101', 5], ['s3', 'MATH101H', 2]],
    [[1, 'am'], [2, 'eve'], [0, 'eve'], [2, 'eve'], [4, 'eve'], [6, 'eve']],
    {'s1': ['fri', 'fri-eve', 'sun-am'], 's2': ['fri-pm'], 's3': ['sun-am', 'fri']}],
   [['s3', 'PHYS110', 5]]),
  ('regression variant: slot onward 2',
   [[['s1', 'BIO130', 4], ['s3', 'MATH101H', 3], ['s2', 'CHEM120', 5], ['s1', 'MATH101', 3],
     ['s3', 'MATH101', 4]],
    [[5, 'eve'], [6, 'am'], [2, 'eve'], [4, 'eve'], [2, 'eve'], [5, 'am']],
    {'s1': ['sat', 'fri-pm'], 's2': ['sat', 'fri-pm', 'fri'], 's3': ['sat', 'sun-am']}],
   [['s1', 'MATH101', 3], ['s2', 'CHEM120', 5]]),
  ('partial repair guard 3',
   [[['s2', 'MATH101', 0], ['s1', 'PHYS110', 1]],
    [[0, 'eve'], [0, 'pm'], [2, 'pm'], [5, 'pm'], [5, 'pm'], [1, 'am']],
    {'s1': ['sun-am'], 's2': ['sun-am', 'mon-eve'], 's3': ['sun-am', 'sat']}],
   [['s2', 'MATH101', 0]]),
  ('boundary control 4', [[['s1', 'A', 0]], [[0, 'am']], {'s1': ['sun']}], []),
  ('normal control 5',
   [[['s1', 'ECON150', 5], ['s1', 'HIST140', 3], ['s3', 'HIST140', 3], ['s2', 'PHYS110', 5],
     ['s3', 'BIO130', 4], ['s3', 'BIO130', 4]],
    [[0, 'pm'], [5, 'eve'], [4, 'pm'], [1, 'pm'], [2, 'eve'], [0, 'pm']],
    {'s1': ['mon-eve'], 's2': ['fri-eve', 'sun-am'], 's3': ['mon-eve']}],
   []),
  ('normal control 6',
   [[['s3', 'MATH101', 1], ['s1', 'HIST140', 1], ['s3', 'ECON150', 5]],
    [[6, 'am'], [4, 'pm'], [6, 'eve'], [6, 'am'], [3, 'am'], [5, 'pm']],
    {'s1': ['sun-am', 'fri-eve', 'sat'], 's2': ['sun-am'], 's3': ['fri-eve']}],
   []),
  ('normal control 7',
   [[['s3', 'PHYS110', 2], ['s1', 'MATH101H', 5]],
    [[2, 'pm'], [2, 'pm'], [1, 'am'], [3, 'pm'], [2, 'am'], [5, 'eve']],
    {'s1': ['mon-eve'], 's2': ['fri-eve', 'sat'], 's3': ['fri-pm', 'sat']}],
   []),
  ('normal control 8',
   [[['s1', 'ECON150', 4], ['s2', 'CHEM120', 4], ['s1', 'BIO130', 0], ['s2', 'ECON150', 4],
     ['s3', 'CHEM120', 3], ['s3', 'MATH101H', 0]],
    [[0, 'pm'], [1, 'pm'], [5, 'pm'], [1, 'eve'], [0, 'pm'], [5, 'eve']],
    {'s1': ['fri-eve'], 's2': ['fri'], 's3': ['sun-am']}],
   [])],
 [('regression: slot onward 1',
   [[['s1', 'HIST140', 4]], [[4, 'eve'], [3, 'am'], [5, 'eve'], [6, 'pm'], [6, 'eve'], [6, 'pm']],
    {'s1': ['fri-pm', 'fri-eve', 'sun-am'], 's2': ['mon-eve', 'fri'], 's3': ['fri', 'fri-eve']}],
   [['s1', 'HIST140', 4]]),
  ('regression variant: slot onward 2',
   [[['s1', 'CHEM120', 4], ['s2', 'ECON150', 4], ['s3', 'CHEM120', 4], ['s3', 'MATH101H', 0],
     ['s2', 'PHYS110', 2]],
    [[3, 'pm'], [2, 'pm'], [3, 'pm'], [1, 'pm'], [6, 'eve'], [4, 'eve']],
    {'s3': ['sun-am', 'sat', 'fri-eve']}],
   [['s3', 'CHEM120', 4]]),
  ('partial repair guard 3',
   [[['s2', 'BIO130', 4], ['s1', 'ECON150', 1], ['s2', 'BIO130', 1], ['s2', 'ECON150', 1]],
    [[6, 'eve'], [5, 'eve'], [1, 'pm'], [5, 'eve'], [6, 'am'], [3, 'eve']],
    {'s1': ['fri-eve', 'sun-am', 'sat'], 's2': ['fri', 'fri-eve', 'sun-am'], 's3': ['sat']}],
   [['s1', 'ECON150', 1], ['s2', 'BIO130', 4]]),
  ('boundary control 4', [[['s1', 'A', 0]], [[5, 'am']], {'s1': ['sat', 'fri-pm']}], [['s1', 'A', 0]]),
  ('normal control 5',
   [[['s3', 'ECON150', 5], ['s1', 'PHYS110', 5], ['s3', 'BIO130', 4]],
    [[5, 'pm'], [0, 'eve'], [1, 'pm'], [2, 'pm'], [6, 'eve'], [0, 'pm']],
    {'s1': ['fri'], 's2': ['sat', 'sun-am'], 's3': ['sun-am', 'fri']}],
   [['s3', 'BIO130', 4]]),
  ('normal control 6',
   [[['s1', 'CHEM120', 5], ['s2', 'CHEM120', 3], ['s2', 'MATH101H', 1], ['s2', 'MATH101', 0],
     ['s3', 'MATH101', 3]],
    [[0, 'eve'], [1, 'am'], [5, 'am'], [4, 'pm'], [4, 'eve'], [1, 'eve']],
    {'s1': ['fri-pm', 'fri-eve'], 's2': ['fri-pm']}],
   [['s2', 'CHEM120', 3]]),
  ('normal control 7',
   [[['s2', 'PHYS110', 1], ['s2', 'ECON150', 2], ['s2', 'BIO130', 0], ['s3', 'CHEM120', 2]],
    [[1, 'eve'], [0, 'eve'], [5, 'eve'], [3, 'am'], [1, 'am'], [2, 'am']],
    {'s1': ['fri-pm'], 's2': ['mon-eve'], 's3': ['sat', 'fri-eve', 'fri']}],
   [['s2', 'PHYS110', 1], ['s3', 'CHEM120', 2]]),
  ('normal control 8',
   [[['s2', 'BIO130', 1], ['s1', 'ECON150', 0], ['s2', 'BIO130', 0], ['s2', 'CHEM120', 0]],
    [[0, 'eve'], [5, 'am'], [0, 'pm'], [3, 'eve'], [1, 'eve'], [6, 'pm']],
    {'s1': ['sun-am', 'mon-eve'], 's2': ['fri-pm', 'sun-am'], 's3': ['sat', 'fri-eve']}],
   [['s1', 'ECON150', 0]])],
 [('regression: slot onward 1',
   [[['s3', 'BIO130', 4], ['s3', 'MATH101', 1], ['s3', 'ECON150', 4], ['s2', 'CHEM120', 0]],
    [[6, 'pm'], [5, 'pm'], [1, 'eve'], [4, 'eve'], [3, 'am'], [3, 'pm']],
    {'s2': ['sun-am'], 's3': ['fri-eve', 'fri']}],
   [['s2', 'CHEM120', 0]]),
  ('regression variant: slot onward 2',
   [[['s3', 'ECON150', 2], ['s3', 'HIST140', 5], ['s1', 'PHYS110', 4]],
    [[2, 'am'], [2, 'pm'], [6, 'eve'], [1, 'eve'], [2, 'pm'], [2, 'pm']],
    {'s1': ['sat', 'fri', 'mon-eve'], 's2': ['sat'], 's3': ['sun-am', 'fri']}],
   [['s3', 'ECON150', 2]]),
  ('partial repair guard 3',
   [[['s2', 'ECON150', 3], ['s2', 'CHEM120', 4]],
    [[2, 'pm'], [2, 'pm'], [2, 'eve'], [0, 'eve'], [6, 'am'], [1, 'eve']],
    {'s2': ['sun-am', 'fri'], 's3': ['fri-eve', 'fri-pm', 'fri']}],
   [['s2', 'CHEM120', 4]]),
  ('boundary control 4', [[['s1', 'A', 0]], [[4, 'eve']], {'s1': ['fri-pm']}], [['s1', 'A', 0]]),
  ('normal control 5',
   [[['s1', 'MATH101H', 3], ['s1', 'ECON150', 2], ['s1', 'HIST140', 2], ['s2', 'MATH101', 3],
     ['s2', 'ECON150', 1]],
    [[2, 'am'], [5, 'eve'], [3, 'am'], [1, 'eve'], [0, 'eve'], [2, 'am']],
    {'s1': ['mon-eve', 'fri-eve'], 's2': ['fri-pm', 'fri-eve', 'mon-eve'], 's3': ['fri', 'sat', 'fri-pm']}],
   []),
  ('normal control 6',
   [[['s1', 'MATH101H', 4], ['s3', 'BIO130', 1], ['s3', 'BIO130', 2], ['s3', 'BIO130', 3],
     ['s1', 'ECON150', 4], ['s1', 'PHYS110', 3]],
    [[0, 'am'], [1, 'eve'], [3, 'eve'], [6, 'pm'], [5, 'eve'], [2, 'eve']], {'s2': ['sat']}],
   []),
  ('normal control 7',
   [[['s3', 'MATH101', 5], ['s2', 'MATH101H', 4]],
    [[3, 'eve'], [2, 'eve'], [2, 'am'], [1, 'pm'], [0, 'eve'], [2, 'pm']],
    {'s1': ['fri-pm', 'mon-eve', 'sun-am'], 's3': ['fri']}],
   []),
  ('normal control 8',
   [[['s2', 'HIST140', 3], ['s3', 'CHEM120', 1], ['s3', 'HIST140', 0], ['s2', 'ECON150', 3]],
    [[3, 'pm'], [6, 'pm'], [3, 'pm'], [0, 'pm'], [1, 'eve'], [1, 'pm']],
    {'s1': ['mon-eve', 'fri-eve', 'fri-pm'], 's2': ['mon-eve', 'sun-am'], 's3': ['fri-eve']}],
   [])]]
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 fixtureActualExpectedOutcome
regression: slot onward 1[['s1', 'A', 0]][['s1', 'A', 0]]Passed
regression variant: slot onward 2[['s3', 'BIO130', 4]][['s3', 'BIO130', 4]]Passed
partial repair guard 3[['s3', 'MATH101H', 4]][['s3', 'MATH101H', 4]]Passed
boundary control 4[['s1', 'A', 0]][['s1', 'A', 0]]Passed
normal control 5[][]Passed
normal control 6[['s1', 'BIO130', 4], ['s1', 'CHEM120', 3], ['s1', 'HIST140', 0]][['s1', 'BIO130', 4], ['s1', 'CHEM120', 3], ['s1', 'HIST140', 0]]Passed
normal control 7[][]Passed
normal control 8[][]Passed

SHA-256 / 78be08c5583faed1d9d538a7e1bc5339fc597dfb8a72392a6f176459ae917bd1

Verification & scope

Stipulated toy exam-timetabling rule set for a bounded model; it does not claim conformance with any institution's regulations or a benchmark specification, and it performs no search or optimisation. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:52:07.121794+00:00.

Case digest / 85d7713d003a1f092539cd59aa2a5b302d0dead5948e241ec02f3a8b2ec8fa85