FAILURE MAP
← Case archive

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.

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

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 fixtureActualExpectedOutcome
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 fixtureActualExpectedOutcome
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 fixtureActualExpectedOutcome
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