FAILURE MAP
← Case archive

FA-94746 / Exam timetabling constraints / Open access

Duplicate enrolment rows send duplicate notices · case 01

Students receive the same change notice twice.

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

ROOT CAUSE

Notification rows are not deduplicated.

VERIFIED REPAIR

Deduplicate rows and sort by student then exam.

Unsuccessful approach: Sorting exam-major breaks the contract order.

Case contract

old/new timetables map exam -> [period, room]; rooms room -> venue; enrol [student, exam] rows (may repeat). Reasons: added, removed, moved (period changed; takes precedence), venue (same period, different venue). A room change within the same venue needs no notice. Return distinct [student, exam, reason] rows sorted by student, exam.

Why this case matters

Republishing a timetable must notify exactly the affected candidates.

1 / The failure

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

N = 1
observations = []
def solve(old, new, rooms, enrol):
    reasons = {}
    for ex in set(old) | set(new):
        if ex not in old:
            reasons[ex] = 'added'
        elif ex not in new:
            reasons[ex] = 'removed'
        elif old[ex][0] != new[ex][0]:
            reasons[ex] = 'moved'
        elif rooms[old[ex][1]] != rooms[new[ex][1]]:
            reasons[ex] = 'venue'
    out = sorted((st, ex, reasons[ex]) for st, ex in enrol if ex in reasons)
    return [list(t) for t in out]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: notification dedupe 1',
   [{'MATH101H': [0, 'L1'], 'BIO130': [2, 'H2']},
    {'MATH101': [3, 'H1'],
     'MATH101H': [3, 'G1'],
     'PHYS110': [2, 'L2'],
     'CHEM120': [2, 'L2'],
     'BIO130': [2, 'H2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s5', 'BIO130'], ['s2', 'MATH101H'], ['s1', 'BIO130'], ['s2', 'HIST140'], ['s2', 'MATH101'],
     ['s5', 'CHEM120'], ['s5', 'HIST140'], ['s4', 'MATH101H'], ['s4', 'BIO130'], ['s2', 'CHEM120'],
     ['s4', 'HIST140'], ['s4', 'MATH101'], ['s1', 'CHEM120'], ['s5', 'CHEM120']]],
   [['s1', 'CHEM120', 'added'], ['s2', 'CHEM120', 'added'], ['s2', 'MATH101', 'added'],
    ['s2', 'MATH101H', 'moved'], ['s4', 'MATH101', 'added'], ['s4', 'MATH101H', 'moved'],
    ['s5', 'CHEM120', 'added']]),
  ('regression variant: notification dedupe 2',
   [{'MATH101': [3, 'L2'], 'MATH101H': [2, 'H2'], 'CHEM120': [3, 'G1']},
    {'MATH101': [3, 'L2'], 'MATH101H': [2, 'H2'], 'PHYS110': [1, 'G1'], 'BIO130': [0, 'L1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s2', 'MATH101'], ['s3', 'ECON150'], ['s4', 'CHEM120'], ['s2', 'CHEM120'], ['s1', 'BIO130'],
     ['s2', 'HIST140'], ['s5', 'HIST140'], ['s4', 'CHEM120'], ['s4', 'MATH101H'], ['s4', 'ECON150'],
     ['s2', 'BIO130'], ['s5', 'MATH101']]],
   [['s1', 'BIO130', 'added'], ['s2', 'BIO130', 'added'], ['s2', 'CHEM120', 'removed'],
    ['s4', 'CHEM120', 'removed']]),
  ('partial repair guard 3',
   [{'MATH101': [1, 'L1'],
     'MATH101H': [3, 'G1'],
     'PHYS110': [2, 'H2'],
     'CHEM120': [3, 'H2'],
     'BIO130': [0, 'H1']},
    {'MATH101': [2, 'G1'], 'CHEM120': [3, 'H1'], 'BIO130': [0, 'H1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s4', 'ECON150'], ['s4', 'PHYS110'], ['s1', 'HIST140'], ['s4', 'PHYS110'], ['s5', 'BIO130'],
     ['s2', 'ECON150'], ['s2', 'HIST140'], ['s5', 'MATH101H']]],
   [['s4', 'PHYS110', 'removed'], ['s5', 'MATH101H', 'removed']]),
  ('boundary control 4',
   [{'A': [0, 'H1']}, {'A': [0, 'G1']}, {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'A'], ['s1', 'A']]],
   []),
  ('normal control 5',
   [{'BIO130': [0, 'H1']},
    {'MATH101': [2, 'G1'], 'MATH101H': [1, 'H1'], 'CHEM120': [2, 'L1'], 'BIO130': [1, 'L1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'ECON150'], ['s1', 'BIO130'], ['s1', 'HIST140'], ['s3', 'MATH101H'], ['s4', 'CHEM120'],
     ['s3', 'CHEM120'], ['s1', 'CHEM120'], ['s2', 'MATH101'], ['s1', 'PHYS110'], ['s4', 'HIST140'],
     ['s3', 'BIO130'], ['s1', 'CHEM120']]],
   [['s1', 'BIO130', 'moved'], ['s1', 'CHEM120', 'added'], ['s2', 'MATH101', 'added'],
    ['s3', 'BIO130', 'moved'], ['s3', 'CHEM120', 'added'], ['s3', 'MATH101H', 'added'],
    ['s4', 'CHEM120', 'added']]),
  ('normal control 6',
   [{'MATH101': [0, 'H2'], 'MATH101H': [1, 'H2'], 'PHYS110': [3, 'G1'], 'BIO130': [0, 'L2']},
    {'MATH101': [0, 'H2'],
     'MATH101H': [1, 'H2'],
     'PHYS110': [3, 'G1'],
     'CHEM120': [3, 'L1'],
     'BIO130': [0, 'L2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'MATH101H'], ['s1', 'CHEM120'], ['s1', 'MATH101'], ['s1', 'BIO130']]],
   [['s1', 'CHEM120', 'added']]),
  ('normal control 7',
   [{'MATH101': [2, 'L1'], 'MATH101H': [3, 'L1'], 'PHYS110': [1, 'G1'], 'BIO130': [1, 'H2']},
    {'MATH101': [2, 'L1'], 'MATH101H': [3, 'L1'], 'PHYS110': [1, 'G1'], 'BIO130': [1, 'L1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'PHYS110'], ['s2', 'MATH101H'], ['s5', 'MATH101H'], ['s5', 'BIO130'], ['s4', 'ECON150'],
     ['s5', 'MATH101'], ['s2', 'CHEM120'], ['s4', 'MATH101H'], ['s4', 'BIO130'], ['s5', 'CHEM120']]],
   [['s4', 'BIO130', 'venue'], ['s5', 'BIO130', 'venue']]),
  ('normal control 8',
   [{'MATH101': [0, 'H1'],
     'MATH101H': [0, 'H2'],
     'PHYS110': [3, 'L1'],
     'CHEM120': [3, 'L1'],
     'BIO130': [1, 'L1']},
    {'MATH101': [2, 'L2'],
     'MATH101H': [2, 'L1'],
     'PHYS110': [3, 'L1'],
     'CHEM120': [2, 'H2'],
     'BIO130': [0, 'G1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'ECON150'], ['s1', 'BIO130'], ['s1', 'MATH101H'], ['s1', 'HIST140']]],
   [['s1', 'BIO130', 'moved'], ['s1', 'MATH101H', 'moved']])],
 [('regression: notification dedupe 1',
   [{'MATH101': [2, 'G1'],
     'MATH101H': [0, 'G1'],
     'PHYS110': [3, 'L1'],
     'CHEM120': [1, 'L1'],
     'BIO130': [3, 'H1']},
    {'MATH101': [2, 'G1'], 'MATH101H': [0, 'G1'], 'PHYS110': [3, 'L1'], 'BIO130': [3, 'H1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'CHEM120'], ['s4', 'BIO130'], ['s2', 'PHYS110'], ['s3', 'BIO130'], ['s4', 'ECON150'],
     ['s3', 'CHEM120'], ['s4', 'MATH101H'], ['s3', 'ECON150'], ['s4', 'CHEM120'], ['s2', 'CHEM120']]],
   [['s2', 'CHEM120', 'removed'], ['s3', 'CHEM120', 'removed'], ['s4', 'CHEM120', 'removed']]),
  ('regression variant: notification dedupe 2',
   [{'MATH101': [2, 'L2'],
     'MATH101H': [2, 'H1'],
     'PHYS110': [1, 'H2'],
     'CHEM120': [1, 'L2'],
     'BIO130': [2, 'H2']},
    {'MATH101': [2, 'L2'], 'MATH101H': [2, 'G1'], 'PHYS110': [3, 'H1'], 'BIO130': [2, 'H2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'PHYS110'], ['s1', 'PHYS110']]],
   [['s1', 'PHYS110', 'moved']]),
  ('partial repair guard 3',
   [{'MATH101': [0, 'L2'], 'MATH101H': [2, 'G1'], 'CHEM120': [0, 'L1'], 'BIO130': [3, 'G1']},
    {'MATH101': [0, 'L2'],
     'MATH101H': [2, 'G1'],
     'PHYS110': [2, 'H2'],
     'CHEM120': [0, 'L1'],
     'BIO130': [2, 'L2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'HIST140'], ['s3', 'BIO130'], ['s2', 'BIO130'], ['s1', 'MATH101H'], ['s5', 'ECON150'],
     ['s1', 'HIST140'], ['s4', 'MATH101'], ['s1', 'BIO130'], ['s4', 'HIST140'], ['s2', 'PHYS110']]],
   [['s1', 'BIO130', 'moved'], ['s2', 'BIO130', 'moved'], ['s2', 'PHYS110', 'added'],
    ['s3', 'BIO130', 'moved']]),
  ('boundary control 4',
   [{'A': [0, 'H1']}, {'A': [1, 'L1']}, {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'A']]],
   [['s1', 'A', 'moved']]),
  ('normal control 5',
   [{'MATH101': [0, 'G1'], 'MATH101H': [3, 'L2'], 'CHEM120': [0, 'L1']},
    {'MATH101': [0, 'G1'], 'PHYS110': [3, 'H2'], 'CHEM120': [0, 'L1'], 'BIO130': [3, 'L1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'PHYS110'], ['s4', 'CHEM120'], ['s1', 'BIO130'], ['s4', 'MATH101'], ['s5', 'MATH101'],
     ['s2', 'PHYS110'], ['s1', 'HIST140'], ['s1', 'PHYS110'], ['s2', 'MATH101'], ['s4', 'ECON150'],
     ['s2', 'ECON150'], ['s5', 'MATH101H'], ['s5', 'ECON150'], ['s4', 'PHYS110']]],
   [['s1', 'BIO130', 'added'], ['s1', 'PHYS110', 'added'], ['s2', 'PHYS110', 'added'],
    ['s3', 'PHYS110', 'added'], ['s4', 'PHYS110', 'added'], ['s5', 'MATH101H', 'removed']]),
  ('normal control 6',
   [{'MATH101': [2, 'G1'],
     'MATH101H': [1, 'H1'],
     'PHYS110': [1, 'H2'],
     'CHEM120': [2, 'H1'],
     'BIO130': [1, 'L2']},
    {'MATH101': [2, 'L1'],
     'MATH101H': [2, 'H1'],
     'PHYS110': [3, 'H1'],
     'CHEM120': [2, 'H1'],
     'BIO130': [1, 'L2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'MATH101'], ['s4', 'HIST140'], ['s4', 'BIO130'], ['s3', 'HIST140'], ['s4', 'CHEM120']]],
   [['s3', 'MATH101', 'venue']]),
  ('normal control 7',
   [{'MATH101': [2, 'H1'],
     'MATH101H': [0, 'H1'],
     'PHYS110': [1, 'L1'],
     'CHEM120': [1, 'G1'],
     'BIO130': [2, 'L2']},
    {'MATH101': [2, 'H1'],
     'MATH101H': [0, 'L1'],
     'PHYS110': [0, 'H2'],
     'CHEM120': [1, 'G1'],
     'BIO130': [2, 'L1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'}, [['s2', 'BIO130']]],
   []),
  ('normal control 8',
   [{'MATH101': [1, 'L2'], 'MATH101H': [1, 'L1'], 'CHEM120': [2, 'G1'], 'BIO130': [1, 'L1']},
    {'MATH101': [1, 'L2'],
     'MATH101H': [0, 'G1'],
     'PHYS110': [3, 'G1'],
     'CHEM120': [3, 'H1'],
     'BIO130': [1, 'L1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'MATH101'], ['s2', 'MATH101'], ['s4', 'MATH101'], ['s2', 'MATH101H'], ['s2', 'ECON150'],
     ['s4', 'ECON150'], ['s5', 'PHYS110'], ['s2', 'HIST140'], ['s3', 'CHEM120'], ['s5', 'ECON150'],
     ['s1', 'CHEM120'], ['s4', 'MATH101H'], ['s5', 'PHYS110']]],
   [['s1', 'CHEM120', 'moved'], ['s2', 'MATH101H', 'moved'], ['s3', 'CHEM120', 'moved'],
    ['s4', 'MATH101H', 'moved'], ['s5', 'PHYS110', 'added']])],
 [('regression: notification dedupe 1',
   [{'MATH101': [1, 'H1'],
     'MATH101H': [3, 'H1'],
     'PHYS110': [0, 'H2'],
     'CHEM120': [1, 'H2'],
     'BIO130': [0, 'H1']},
    {'MATH101': [1, 'H1'],
     'MATH101H': [3, 'H1'],
     'PHYS110': [3, 'L2'],
     'CHEM120': [2, 'G1'],
     'BIO130': [0, 'H1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s5', 'HIST140'], ['s3', 'BIO130'], ['s5', 'MATH101H'], ['s1', 'MATH101H'], ['s3', 'PHYS110'],
     ['s5', 'MATH101'], ['s5', 'CHEM120'], ['s3', 'PHYS110'], ['s3', 'MATH101H']]],
   [['s3', 'PHYS110', 'moved'], ['s5', 'CHEM120', 'moved']]),
  ('regression variant: notification dedupe 2',
   [{'MATH101': [0, 'H2'], 'PHYS110': [0, 'H2'], 'CHEM120': [3, 'G1'], 'BIO130': [3, 'H1']},
    {'MATH101H': [2, 'H2'], 'PHYS110': [3, 'L1'], 'BIO130': [2, 'G1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'PHYS110'], ['s4', 'ECON150'], ['s5', 'ECON150'], ['s3', 'MATH101'], ['s1', 'MATH101H'],
     ['s4', 'HIST140'], ['s1', 'PHYS110'], ['s5', 'CHEM120'], ['s3', 'MATH101H'], ['s1', 'BIO130'],
     ['s5', 'MATH101H'], ['s1', 'CHEM120'], ['s5', 'MATH101H'], ['s4', 'MATH101'], ['s5', 'HIST140'],
     ['s4', 'BIO130']]],
   [['s1', 'BIO130', 'moved'], ['s1', 'CHEM120', 'removed'], ['s1', 'MATH101H', 'added'],
    ['s1', 'PHYS110', 'moved'], ['s3', 'MATH101', 'removed'], ['s3', 'MATH101H', 'added'],
    ['s3', 'PHYS110', 'moved'], ['s4', 'BIO130', 'moved'], ['s4', 'MATH101', 'removed'],
    ['s5', 'CHEM120', 'removed'], ['s5', 'MATH101H', 'added']]),
  ('partial repair guard 3',
   [{'MATH101': [1, 'H1'],
     'MATH101H': [2, 'G1'],
     'PHYS110': [2, 'L1'],
     'CHEM120': [3, 'L1'],
     'BIO130': [1, 'L1']},
    {'MATH101': [2, 'L2'],
     'MATH101H': [2, 'G1'],
     'PHYS110': [2, 'L1'],
     'CHEM120': [1, 'H2'],
     'BIO130': [2, 'H2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s5', 'PHYS110'], ['s1', 'PHYS110'], ['s2', 'MATH101H'], ['s5', 'BIO130'], ['s4', 'MATH101'],
     ['s5', 'BIO130']]],
   [['s4', 'MATH101', 'moved'], ['s5', 'BIO130', 'moved']]),
  ('boundary control 4',
   [{'A': [0, 'H1'], 'B': [1, 'L1']}, {'A': [2, 'H1'], 'B': [1, 'H2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s2', 'A'], ['s1', 'B'], ['s1', 'A']]],
   [['s1', 'A', 'moved'], ['s1', 'B', 'venue'], ['s2', 'A', 'moved']]),
  ('normal control 5',
   [{'MATH101': [0, 'L2'], 'MATH101H': [2, 'G1'], 'CHEM120': [0, 'L1'], 'BIO130': [3, 'G1']},
    {'MATH101': [0, 'L2'],
     'MATH101H': [2, 'G1'],
     'PHYS110': [2, 'H2'],
     'CHEM120': [0, 'L1'],
     'BIO130': [2, 'L2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'HIST140'], ['s3', 'BIO130'], ['s2', 'BIO130'], ['s1', 'MATH101H'], ['s5', 'ECON150'],
     ['s1', 'HIST140'], ['s4', 'MATH101'], ['s1', 'BIO130'], ['s4', 'HIST140'], ['s2', 'PHYS110']]],
   [['s1', 'BIO130', 'moved'], ['s2', 'BIO130', 'moved'], ['s2', 'PHYS110', 'added'],
    ['s3', 'BIO130', 'moved']]),
  ('normal control 6',
   [{'MATH101H': [1, 'L2'], 'PHYS110': [2, 'L2'], 'CHEM120': [0, 'G1'], 'BIO130': [2, 'H2']},
    {'MATH101H': [2, 'H2'], 'PHYS110': [2, 'L2'], 'CHEM120': [0, 'G1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s4', 'CHEM120'], ['s3', 'MATH101H'], ['s2', 'HIST140'], ['s5', 'CHEM120'], ['s2', 'BIO130'],
     ['s3', 'PHYS110'], ['s2', 'MATH101'], ['s3', 'CHEM120'], ['s4', 'HIST140'], ['s1', 'CHEM120'],
     ['s3', 'HIST140'], ['s3', 'PHYS110'], ['s4', 'PHYS110']]],
   [['s2', 'BIO130', 'removed'], ['s3', 'MATH101H', 'moved']]),
  ('normal control 7',
   [{'MATH101': [2, 'H1'], 'MATH101H': [0, 'L2'], 'CHEM120': [2, 'L2']},
    {'MATH101': [2, 'H1'],
     'MATH101H': [2, 'G1'],
     'PHYS110': [0, 'G1'],
     'CHEM120': [2, 'L2'],
     'BIO130': [3, 'G1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s4', 'HIST140'], ['s4', 'BIO130'], ['s4', 'MATH101H'], ['s2', 'BIO130']]],
   [['s2', 'BIO130', 'added'], ['s4', 'BIO130', 'added'], ['s4', 'MATH101H', 'moved']]),
  ('normal control 8',
   [{'MATH101': [3, 'L1'], 'MATH101H': [1, 'G1'], 'PHYS110': [2, 'H1'], 'BIO130': [3, 'L2']},
    {'MATH101': [3, 'L1'],
     'MATH101H': [1, 'G1'],
     'PHYS110': [2, 'H1'],
     'CHEM120': [2, 'H2'],
     'BIO130': [3, 'L2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s4', 'MATH101'], ['s4', 'MATH101'], ['s4', 'PHYS110'], ['s4', 'MATH101H']]],
   [])],
 [('regression: notification dedupe 1',
   [{'MATH101': [1, 'L1'],
     'MATH101H': [3, 'G1'],
     'PHYS110': [2, 'H2'],
     'CHEM120': [3, 'H2'],
     'BIO130': [0, 'H1']},
    {'MATH101': [2, 'G1'], 'CHEM120': [3, 'H1'], 'BIO130': [0, 'H1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s4', 'ECON150'], ['s4', 'PHYS110'], ['s1', 'HIST140'], ['s4', 'PHYS110'], ['s5', 'BIO130'],
     ['s2', 'ECON150'], ['s2', 'HIST140'], ['s5', 'MATH101H']]],
   [['s4', 'PHYS110', 'removed'], ['s5', 'MATH101H', 'removed']]),
  ('regression variant: notification dedupe 2',
   [{'BIO130': [0, 'H1']},
    {'MATH101': [2, 'G1'], 'MATH101H': [1, 'H1'], 'CHEM120': [2, 'L1'], 'BIO130': [1, 'L1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'ECON150'], ['s1', 'BIO130'], ['s1', 'HIST140'], ['s3', 'MATH101H'], ['s4', 'CHEM120'],
     ['s3', 'CHEM120'], ['s1', 'CHEM120'], ['s2', 'MATH101'], ['s1', 'PHYS110'], ['s4', 'HIST140'],
     ['s3', 'BIO130'], ['s1', 'CHEM120']]],
   [['s1', 'BIO130', 'moved'], ['s1', 'CHEM120', 'added'], ['s2', 'MATH101', 'added'],
    ['s3', 'BIO130', 'moved'], ['s3', 'CHEM120', 'added'], ['s3', 'MATH101H', 'added'],
    ['s4', 'CHEM120', 'added']]),
  ('partial repair guard 3',
   [{'MATH101': [3, 'L2'],
     'MATH101H': [0, 'G1'],
     'PHYS110': [2, 'L1'],
     'CHEM120': [2, 'H1'],
     'BIO130': [2, 'H1']},
    {'MATH101': [3, 'L2'],
     'MATH101H': [1, 'G1'],
     'PHYS110': [3, 'L1'],
     'CHEM120': [1, 'L1'],
     'BIO130': [2, 'H1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s4', 'MATH101H'], ['s5', 'MATH101'], ['s2', 'CHEM120'], ['s2', 'MATH101'], ['s5', 'CHEM120'],
     ['s2', 'MATH101H'], ['s1', 'HIST140'], ['s5', 'MATH101'], ['s1', 'BIO130'], ['s4', 'BIO130']]],
   [['s2', 'CHEM120', 'moved'], ['s2', 'MATH101H', 'moved'], ['s4', 'MATH101H', 'moved'],
    ['s5', 'CHEM120', 'moved']]),
  ('boundary control 4',
   [{'A': [0, 'H1']}, {}, {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'A']]],
   [['s1', 'A', 'removed']]),
  ('normal control 5',
   [{'MATH101H': [1, 'G1'], 'PHYS110': [0, 'L1'], 'CHEM120': [3, 'G1'], 'BIO130': [0, 'H2']},
    {'MATH101': [3, 'L2'],
     'MATH101H': [1, 'G1'],
     'PHYS110': [3, 'H2'],
     'CHEM120': [3, 'G1'],
     'BIO130': [1, 'H1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'MATH101H'], ['s5', 'HIST140'], ['s4', 'ECON150'], ['s3', 'MATH101'], ['s5', 'MATH101H'],
     ['s2', 'PHYS110'], ['s4', 'MATH101H'], ['s2', 'CHEM120'], ['s2', 'MATH101'], ['s5', 'BIO130'],
     ['s5', 'CHEM120'], ['s2', 'HIST140']]],
   [['s2', 'MATH101', 'added'], ['s2', 'PHYS110', 'moved'], ['s3', 'MATH101', 'added'],
    ['s5', 'BIO130', 'moved']]),
  ('normal control 6',
   [{'MATH101': [0, 'H1'], 'MATH101H': [2, 'L1'], 'CHEM120': [3, 'L2'], 'BIO130': [0, 'G1']},
    {'MATH101': [0, 'H1'],
     'MATH101H': [0, 'L2'],
     'PHYS110': [2, 'L2'],
     'CHEM120': [0, 'H1'],
     'BIO130': [0, 'H1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s4', 'PHYS110'], ['s5', 'HIST140'], ['s4', 'MATH101H'], ['s4', 'ECON150'], ['s5', 'MATH101H'],
     ['s3', 'PHYS110']]],
   [['s3', 'PHYS110', 'added'], ['s4', 'MATH101H', 'moved'], ['s4', 'PHYS110', 'added'],
    ['s5', 'MATH101H', 'moved']]),
  ('normal control 7',
   [{'MATH101': [1, 'L1'], 'MATH101H': [2, 'G1'], 'PHYS110': [2, 'L2'], 'CHEM120': [1, 'G1']},
    {'MATH101': [1, 'L1'], 'MATH101H': [0, 'G1'], 'PHYS110': [0, 'G1'], 'CHEM120': [1, 'G1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'MATH101'], ['s2', 'HIST140'], ['s2', 'BIO130'], ['s1', 'BIO130'], ['s1', 'MATH101H'],
     ['s2', 'BIO130']]],
   [['s1', 'MATH101H', 'moved']]),
  ('normal control 8',
   [{'MATH101': [1, 'L1'],
     'MATH101H': [2, 'H1'],
     'PHYS110': [3, 'H1'],
     'CHEM120': [2, 'G1'],
     'BIO130': [1, 'G1']},
    {'MATH101': [1, 'L1'],
     'MATH101H': [2, 'H1'],
     'PHYS110': [3, 'H1'],
     'CHEM120': [2, 'G1'],
     'BIO130': [0, 'L1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'BIO130'], ['s3', 'CHEM120'], ['s5', 'HIST140'], ['s2', 'PHYS110'], ['s2', 'BIO130'],
     ['s1', 'MATH101H'], ['s1', 'ECON150'], ['s5', 'ECON150'], ['s1', 'MATH101'], ['s1', 'BIO130'],
     ['s3', 'HIST140'], ['s2', 'MATH101H']]],
   [['s1', 'BIO130', 'moved'], ['s2', 'BIO130', 'moved'], ['s3', 'BIO130', 'moved']])],
 [('regression: notification dedupe 1',
   [{'MATH101': [1, 'L1'],
     'MATH101H': [0, 'H1'],
     'PHYS110': [2, 'G1'],
     'CHEM120': [0, 'G1'],
     'BIO130': [3, 'H2']},
    {'MATH101': [1, 'L1'],
     'MATH101H': [2, 'H1'],
     'PHYS110': [3, 'H2'],
     'CHEM120': [0, 'L2'],
     'BIO130': [3, 'H2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s2', 'MATH101'], ['s5', 'CHEM120'], ['s5', 'HIST140'], ['s1', 'MATH101'], ['s1', 'ECON150'],
     ['s2', 'ECON150'], ['s1', 'CHEM120'], ['s5', 'MATH101'], ['s1', 'CHEM120'], ['s5', 'BIO130'],
     ['s2', 'PHYS110'], ['s2', 'CHEM120']]],
   [['s1', 'CHEM120', 'venue'], ['s2', 'CHEM120', 'venue'], ['s2', 'PHYS110', 'moved'],
    ['s5', 'CHEM120', 'venue']]),
  ('regression variant: notification dedupe 2',
   [{'MATH101': [2, 'G1'], 'MATH101H': [3, 'H1'], 'PHYS110': [0, 'H1'], 'CHEM120': [1, 'H2']},
    {'MATH101': [2, 'G1'],
     'MATH101H': [3, 'H1'],
     'PHYS110': [2, 'H1'],
     'CHEM120': [0, 'L1'],
     'BIO130': [2, 'H1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'MATH101'], ['s5', 'BIO130'], ['s5', 'CHEM120'], ['s1', 'ECON150'], ['s5', 'ECON150'],
     ['s5', 'CHEM120'], ['s1', 'CHEM120'], ['s3', 'BIO130'], ['s4', 'BIO130'], ['s1', 'BIO130'],
     ['s5', 'MATH101H']]],
   [['s1', 'BIO130', 'added'], ['s1', 'CHEM120', 'moved'], ['s3', 'BIO130', 'added'],
    ['s4', 'BIO130', 'added'], ['s5', 'BIO130', 'added'], ['s5', 'CHEM120', 'moved']]),
  ('partial repair guard 3',
   [{'MATH101': [2, 'L2'], 'MATH101H': [2, 'L1'], 'CHEM120': [3, 'H2'], 'BIO130': [0, 'L2']},
    {'MATH101H': [2, 'G1'], 'PHYS110': [3, 'H1'], 'CHEM120': [3, 'H2'], 'BIO130': [0, 'L2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'MATH101'], ['s2', 'MATH101'], ['s3', 'BIO130'], ['s2', 'PHYS110'], ['s3', 'PHYS110'],
     ['s2', 'CHEM120'], ['s3', 'HIST140'], ['s5', 'ECON150'], ['s5', 'PHYS110']]],
   [['s2', 'MATH101', 'removed'], ['s2', 'PHYS110', 'added'], ['s3', 'MATH101', 'removed'],
    ['s3', 'PHYS110', 'added'], ['s5', 'PHYS110', 'added']]),
  ('boundary control 4',
   [{'A': [0, 'H1']}, {'A': [0, 'H2']}, {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'A']]],
   []),
  ('normal control 5',
   [{'MATH101': [3, 'L2'],
     'MATH101H': [0, 'L2'],
     'PHYS110': [3, 'L1'],
     'CHEM120': [1, 'L1'],
     'BIO130': [1, 'H2']},
    {'MATH101': [1, 'H1'],
     'MATH101H': [3, 'H1'],
     'PHYS110': [3, 'L1'],
     'CHEM120': [1, 'L1'],
     'BIO130': [1, 'H2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'ECON150'], ['s1', 'ECON150']]],
   []),
  ('normal control 6',
   [{'MATH101': [3, 'G1'], 'PHYS110': [1, 'L1'], 'CHEM120': [2, 'H1'], 'BIO130': [1, 'H2']},
    {'MATH101': [3, 'G1'],
     'MATH101H': [2, 'L1'],
     'PHYS110': [1, 'H2'],
     'CHEM120': [2, 'H1'],
     'BIO130': [1, 'H2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s2', 'MATH101H'], ['s5', 'ECON150'], ['s3', 'MATH101'], ['s1', 'BIO130'], ['s1', 'CHEM120'],
     ['s4', 'ECON150'], ['s5', 'MATH101H'], ['s1', 'ECON150'], ['s1', 'MATH101'], ['s3', 'ECON150'],
     ['s4', 'HIST140'], ['s4', 'BIO130'], ['s2', 'MATH101'], ['s2', 'CHEM120'], ['s3', 'CHEM120']]],
   [['s2', 'MATH101H', 'added'], ['s5', 'MATH101H', 'added']]),
  ('normal control 7',
   [{'MATH101': [0, 'H1'],
     'MATH101H': [3, 'G1'],
     'PHYS110': [1, 'L1'],
     'CHEM120': [0, 'L2'],
     'BIO130': [3, 'G1']},
    {'MATH101': [0, 'H1'],
     'MATH101H': [0, 'L1'],
     'PHYS110': [1, 'L1'],
     'CHEM120': [0, 'L2'],
     'BIO130': [3, 'G1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'MATH101'], ['s2', 'ECON150'], ['s2', 'CHEM120'], ['s3', 'CHEM120'], ['s1', 'MATH101H'],
     ['s4', 'CHEM120'], ['s3', 'ECON150'], ['s2', 'MATH101'], ['s1', 'HIST140'], ['s3', 'HIST140'],
     ['s2', 'MATH101H'], ['s5', 'HIST140']]],
   [['s1', 'MATH101H', 'moved'], ['s2', 'MATH101H', 'moved']]),
  ('normal control 8',
   [{'MATH101': [3, 'H1'],
     'MATH101H': [3, 'H1'],
     'PHYS110': [2, 'G1'],
     'CHEM120': [0, 'H1'],
     'BIO130': [0, 'H1']},
    {'MATH101H': [3, 'H1'], 'PHYS110': [2, 'H1'], 'BIO130': [0, 'H1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s2', 'MATH101H'], ['s4', 'CHEM120'], ['s4', 'HIST140'], ['s1', 'ECON150'], ['s5', 'ECON150'],
     ['s4', 'ECON150'], ['s2', 'MATH101'], ['s5', 'MATH101'], ['s1', 'BIO130'], ['s5', 'MATH101H'],
     ['s4', 'MATH101'], ['s2', 'HIST140'], ['s5', 'PHYS110']]],
   [['s2', 'MATH101', 'removed'], ['s4', 'CHEM120', 'removed'], ['s4', 'MATH101', 'removed'],
    ['s5', 'MATH101', 'removed']])]]
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: notification dedupe 1[['s1', 'CHEM120', 'added'], ['s2', 'CHEM120', 'added'], ['s2', 'MATH101', 'added'], ['s2', 'MATH101H', 'moved'], ['s4', 'MATH101', 'added'], ['s4', 'MATH101H', 'moved'], ['s5', 'CHEM120', 'added'], ['s5', 'CHEM120', 'added']][['s1', 'CHEM120', 'added'], ['s2', 'CHEM120', 'added'], ['s2', 'MATH101', 'added'], ['s2', 'MATH101H', 'moved'], ['s4', 'MATH101', 'added'], ['s4', 'MATH101H', 'moved'], ['s5', 'CHEM120', 'added']]Failed
regression variant: notification dedupe 2[['s1', 'BIO130', 'added'], ['s2', 'BIO130', 'added'], ['s2', 'CHEM120', 'removed'], ['s4', 'CHEM120', 'removed'], ['s4', 'CHEM120', 'removed']][['s1', 'BIO130', 'added'], ['s2', 'BIO130', 'added'], ['s2', 'CHEM120', 'removed'], ['s4', 'CHEM120', 'removed']]Failed
partial repair guard 3[['s4', 'PHYS110', 'removed'], ['s4', 'PHYS110', 'removed'], ['s5', 'MATH101H', 'removed']][['s4', 'PHYS110', 'removed'], ['s5', 'MATH101H', 'removed']]Failed
boundary control 4[][]Passed
normal control 5[['s1', 'BIO130', 'moved'], ['s1', 'CHEM120', 'added'], ['s1', 'CHEM120', 'added'], ['s2', 'MATH101', 'added'], ['s3', 'BIO130', 'moved'], ['s3', 'CHEM120', 'added'], ['s3', 'MATH101H', 'added'], ['s4', 'CHEM120', 'added']][['s1', 'BIO130', 'moved'], ['s1', 'CHEM120', 'added'], ['s2', 'MATH101', 'added'], ['s3', 'BIO130', 'moved'], ['s3', 'CHEM120', 'added'], ['s3', 'MATH101H', 'added'], ['s4', 'CHEM120', 'added']]Failed
normal control 6[['s1', 'CHEM120', 'added']][['s1', 'CHEM120', 'added']]Passed
normal control 7[['s4', 'BIO130', 'venue'], ['s5', 'BIO130', 'venue']][['s4', 'BIO130', 'venue'], ['s5', 'BIO130', 'venue']]Passed
normal control 8[['s1', 'BIO130', 'moved'], ['s1', 'MATH101H', 'moved']][['s1', 'BIO130', 'moved'], ['s1', 'MATH101H', 'moved']]Passed

SHA-256 / 09bd9f40d4a054875ff35c27803104ab09d3f5c2e178daeb0f26b2bbd18bccda

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(old, new, rooms, enrol):
    reasons = {}
    for ex in set(old) | set(new):
        if ex not in old:
            reasons[ex] = 'added'
        elif ex not in new:
            reasons[ex] = 'removed'
        elif old[ex][0] != new[ex][0]:
            reasons[ex] = 'moved'
        elif rooms[old[ex][1]] != rooms[new[ex][1]]:
            reasons[ex] = 'venue'
    out = sorted(dict.fromkeys((st, ex, reasons[ex]) for st, ex in enrol if ex in reasons), key=lambda t: (t[1], t[0]))
    return [list(t) for t in out]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: notification dedupe 1',
   [{'MATH101H': [0, 'L1'], 'BIO130': [2, 'H2']},
    {'MATH101': [3, 'H1'],
     'MATH101H': [3, 'G1'],
     'PHYS110': [2, 'L2'],
     'CHEM120': [2, 'L2'],
     'BIO130': [2, 'H2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s5', 'BIO130'], ['s2', 'MATH101H'], ['s1', 'BIO130'], ['s2', 'HIST140'], ['s2', 'MATH101'],
     ['s5', 'CHEM120'], ['s5', 'HIST140'], ['s4', 'MATH101H'], ['s4', 'BIO130'], ['s2', 'CHEM120'],
     ['s4', 'HIST140'], ['s4', 'MATH101'], ['s1', 'CHEM120'], ['s5', 'CHEM120']]],
   [['s1', 'CHEM120', 'added'], ['s2', 'CHEM120', 'added'], ['s2', 'MATH101', 'added'],
    ['s2', 'MATH101H', 'moved'], ['s4', 'MATH101', 'added'], ['s4', 'MATH101H', 'moved'],
    ['s5', 'CHEM120', 'added']]),
  ('regression variant: notification dedupe 2',
   [{'MATH101': [3, 'L2'], 'MATH101H': [2, 'H2'], 'CHEM120': [3, 'G1']},
    {'MATH101': [3, 'L2'], 'MATH101H': [2, 'H2'], 'PHYS110': [1, 'G1'], 'BIO130': [0, 'L1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s2', 'MATH101'], ['s3', 'ECON150'], ['s4', 'CHEM120'], ['s2', 'CHEM120'], ['s1', 'BIO130'],
     ['s2', 'HIST140'], ['s5', 'HIST140'], ['s4', 'CHEM120'], ['s4', 'MATH101H'], ['s4', 'ECON150'],
     ['s2', 'BIO130'], ['s5', 'MATH101']]],
   [['s1', 'BIO130', 'added'], ['s2', 'BIO130', 'added'], ['s2', 'CHEM120', 'removed'],
    ['s4', 'CHEM120', 'removed']]),
  ('partial repair guard 3',
   [{'MATH101': [1, 'L1'],
     'MATH101H': [3, 'G1'],
     'PHYS110': [2, 'H2'],
     'CHEM120': [3, 'H2'],
     'BIO130': [0, 'H1']},
    {'MATH101': [2, 'G1'], 'CHEM120': [3, 'H1'], 'BIO130': [0, 'H1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s4', 'ECON150'], ['s4', 'PHYS110'], ['s1', 'HIST140'], ['s4', 'PHYS110'], ['s5', 'BIO130'],
     ['s2', 'ECON150'], ['s2', 'HIST140'], ['s5', 'MATH101H']]],
   [['s4', 'PHYS110', 'removed'], ['s5', 'MATH101H', 'removed']]),
  ('boundary control 4',
   [{'A': [0, 'H1']}, {'A': [0, 'G1']}, {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'A'], ['s1', 'A']]],
   []),
  ('normal control 5',
   [{'BIO130': [0, 'H1']},
    {'MATH101': [2, 'G1'], 'MATH101H': [1, 'H1'], 'CHEM120': [2, 'L1'], 'BIO130': [1, 'L1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'ECON150'], ['s1', 'BIO130'], ['s1', 'HIST140'], ['s3', 'MATH101H'], ['s4', 'CHEM120'],
     ['s3', 'CHEM120'], ['s1', 'CHEM120'], ['s2', 'MATH101'], ['s1', 'PHYS110'], ['s4', 'HIST140'],
     ['s3', 'BIO130'], ['s1', 'CHEM120']]],
   [['s1', 'BIO130', 'moved'], ['s1', 'CHEM120', 'added'], ['s2', 'MATH101', 'added'],
    ['s3', 'BIO130', 'moved'], ['s3', 'CHEM120', 'added'], ['s3', 'MATH101H', 'added'],
    ['s4', 'CHEM120', 'added']]),
  ('normal control 6',
   [{'MATH101': [0, 'H2'], 'MATH101H': [1, 'H2'], 'PHYS110': [3, 'G1'], 'BIO130': [0, 'L2']},
    {'MATH101': [0, 'H2'],
     'MATH101H': [1, 'H2'],
     'PHYS110': [3, 'G1'],
     'CHEM120': [3, 'L1'],
     'BIO130': [0, 'L2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'MATH101H'], ['s1', 'CHEM120'], ['s1', 'MATH101'], ['s1', 'BIO130']]],
   [['s1', 'CHEM120', 'added']]),
  ('normal control 7',
   [{'MATH101': [2, 'L1'], 'MATH101H': [3, 'L1'], 'PHYS110': [1, 'G1'], 'BIO130': [1, 'H2']},
    {'MATH101': [2, 'L1'], 'MATH101H': [3, 'L1'], 'PHYS110': [1, 'G1'], 'BIO130': [1, 'L1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'PHYS110'], ['s2', 'MATH101H'], ['s5', 'MATH101H'], ['s5', 'BIO130'], ['s4', 'ECON150'],
     ['s5', 'MATH101'], ['s2', 'CHEM120'], ['s4', 'MATH101H'], ['s4', 'BIO130'], ['s5', 'CHEM120']]],
   [['s4', 'BIO130', 'venue'], ['s5', 'BIO130', 'venue']]),
  ('normal control 8',
   [{'MATH101': [0, 'H1'],
     'MATH101H': [0, 'H2'],
     'PHYS110': [3, 'L1'],
     'CHEM120': [3, 'L1'],
     'BIO130': [1, 'L1']},
    {'MATH101': [2, 'L2'],
     'MATH101H': [2, 'L1'],
     'PHYS110': [3, 'L1'],
     'CHEM120': [2, 'H2'],
     'BIO130': [0, 'G1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'ECON150'], ['s1', 'BIO130'], ['s1', 'MATH101H'], ['s1', 'HIST140']]],
   [['s1', 'BIO130', 'moved'], ['s1', 'MATH101H', 'moved']])],
 [('regression: notification dedupe 1',
   [{'MATH101': [2, 'G1'],
     'MATH101H': [0, 'G1'],
     'PHYS110': [3, 'L1'],
     'CHEM120': [1, 'L1'],
     'BIO130': [3, 'H1']},
    {'MATH101': [2, 'G1'], 'MATH101H': [0, 'G1'], 'PHYS110': [3, 'L1'], 'BIO130': [3, 'H1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'CHEM120'], ['s4', 'BIO130'], ['s2', 'PHYS110'], ['s3', 'BIO130'], ['s4', 'ECON150'],
     ['s3', 'CHEM120'], ['s4', 'MATH101H'], ['s3', 'ECON150'], ['s4', 'CHEM120'], ['s2', 'CHEM120']]],
   [['s2', 'CHEM120', 'removed'], ['s3', 'CHEM120', 'removed'], ['s4', 'CHEM120', 'removed']]),
  ('regression variant: notification dedupe 2',
   [{'MATH101': [2, 'L2'],
     'MATH101H': [2, 'H1'],
     'PHYS110': [1, 'H2'],
     'CHEM120': [1, 'L2'],
     'BIO130': [2, 'H2']},
    {'MATH101': [2, 'L2'], 'MATH101H': [2, 'G1'], 'PHYS110': [3, 'H1'], 'BIO130': [2, 'H2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'PHYS110'], ['s1', 'PHYS110']]],
   [['s1', 'PHYS110', 'moved']]),
  ('partial repair guard 3',
   [{'MATH101': [0, 'L2'], 'MATH101H': [2, 'G1'], 'CHEM120': [0, 'L1'], 'BIO130': [3, 'G1']},
    {'MATH101': [0, 'L2'],
     'MATH101H': [2, 'G1'],
     'PHYS110': [2, 'H2'],
     'CHEM120': [0, 'L1'],
     'BIO130': [2, 'L2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'HIST140'], ['s3', 'BIO130'], ['s2', 'BIO130'], ['s1', 'MATH101H'], ['s5', 'ECON150'],
     ['s1', 'HIST140'], ['s4', 'MATH101'], ['s1', 'BIO130'], ['s4', 'HIST140'], ['s2', 'PHYS110']]],
   [['s1', 'BIO130', 'moved'], ['s2', 'BIO130', 'moved'], ['s2', 'PHYS110', 'added'],
    ['s3', 'BIO130', 'moved']]),
  ('boundary control 4',
   [{'A': [0, 'H1']}, {'A': [1, 'L1']}, {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'A']]],
   [['s1', 'A', 'moved']]),
  ('normal control 5',
   [{'MATH101': [0, 'G1'], 'MATH101H': [3, 'L2'], 'CHEM120': [0, 'L1']},
    {'MATH101': [0, 'G1'], 'PHYS110': [3, 'H2'], 'CHEM120': [0, 'L1'], 'BIO130': [3, 'L1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'PHYS110'], ['s4', 'CHEM120'], ['s1', 'BIO130'], ['s4', 'MATH101'], ['s5', 'MATH101'],
     ['s2', 'PHYS110'], ['s1', 'HIST140'], ['s1', 'PHYS110'], ['s2', 'MATH101'], ['s4', 'ECON150'],
     ['s2', 'ECON150'], ['s5', 'MATH101H'], ['s5', 'ECON150'], ['s4', 'PHYS110']]],
   [['s1', 'BIO130', 'added'], ['s1', 'PHYS110', 'added'], ['s2', 'PHYS110', 'added'],
    ['s3', 'PHYS110', 'added'], ['s4', 'PHYS110', 'added'], ['s5', 'MATH101H', 'removed']]),
  ('normal control 6',
   [{'MATH101': [2, 'G1'],
     'MATH101H': [1, 'H1'],
     'PHYS110': [1, 'H2'],
     'CHEM120': [2, 'H1'],
     'BIO130': [1, 'L2']},
    {'MATH101': [2, 'L1'],
     'MATH101H': [2, 'H1'],
     'PHYS110': [3, 'H1'],
     'CHEM120': [2, 'H1'],
     'BIO130': [1, 'L2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'MATH101'], ['s4', 'HIST140'], ['s4', 'BIO130'], ['s3', 'HIST140'], ['s4', 'CHEM120']]],
   [['s3', 'MATH101', 'venue']]),
  ('normal control 7',
   [{'MATH101': [2, 'H1'],
     'MATH101H': [0, 'H1'],
     'PHYS110': [1, 'L1'],
     'CHEM120': [1, 'G1'],
     'BIO130': [2, 'L2']},
    {'MATH101': [2, 'H1'],
     'MATH101H': [0, 'L1'],
     'PHYS110': [0, 'H2'],
     'CHEM120': [1, 'G1'],
     'BIO130': [2, 'L1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'}, [['s2', 'BIO130']]],
   []),
  ('normal control 8',
   [{'MATH101': [1, 'L2'], 'MATH101H': [1, 'L1'], 'CHEM120': [2, 'G1'], 'BIO130': [1, 'L1']},
    {'MATH101': [1, 'L2'],
     'MATH101H': [0, 'G1'],
     'PHYS110': [3, 'G1'],
     'CHEM120': [3, 'H1'],
     'BIO130': [1, 'L1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'MATH101'], ['s2', 'MATH101'], ['s4', 'MATH101'], ['s2', 'MATH101H'], ['s2', 'ECON150'],
     ['s4', 'ECON150'], ['s5', 'PHYS110'], ['s2', 'HIST140'], ['s3', 'CHEM120'], ['s5', 'ECON150'],
     ['s1', 'CHEM120'], ['s4', 'MATH101H'], ['s5', 'PHYS110']]],
   [['s1', 'CHEM120', 'moved'], ['s2', 'MATH101H', 'moved'], ['s3', 'CHEM120', 'moved'],
    ['s4', 'MATH101H', 'moved'], ['s5', 'PHYS110', 'added']])],
 [('regression: notification dedupe 1',
   [{'MATH101': [1, 'H1'],
     'MATH101H': [3, 'H1'],
     'PHYS110': [0, 'H2'],
     'CHEM120': [1, 'H2'],
     'BIO130': [0, 'H1']},
    {'MATH101': [1, 'H1'],
     'MATH101H': [3, 'H1'],
     'PHYS110': [3, 'L2'],
     'CHEM120': [2, 'G1'],
     'BIO130': [0, 'H1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s5', 'HIST140'], ['s3', 'BIO130'], ['s5', 'MATH101H'], ['s1', 'MATH101H'], ['s3', 'PHYS110'],
     ['s5', 'MATH101'], ['s5', 'CHEM120'], ['s3', 'PHYS110'], ['s3', 'MATH101H']]],
   [['s3', 'PHYS110', 'moved'], ['s5', 'CHEM120', 'moved']]),
  ('regression variant: notification dedupe 2',
   [{'MATH101': [0, 'H2'], 'PHYS110': [0, 'H2'], 'CHEM120': [3, 'G1'], 'BIO130': [3, 'H1']},
    {'MATH101H': [2, 'H2'], 'PHYS110': [3, 'L1'], 'BIO130': [2, 'G1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'PHYS110'], ['s4', 'ECON150'], ['s5', 'ECON150'], ['s3', 'MATH101'], ['s1', 'MATH101H'],
     ['s4', 'HIST140'], ['s1', 'PHYS110'], ['s5', 'CHEM120'], ['s3', 'MATH101H'], ['s1', 'BIO130'],
     ['s5', 'MATH101H'], ['s1', 'CHEM120'], ['s5', 'MATH101H'], ['s4', 'MATH101'], ['s5', 'HIST140'],
     ['s4', 'BIO130']]],
   [['s1', 'BIO130', 'moved'], ['s1', 'CHEM120', 'removed'], ['s1', 'MATH101H', 'added'],
    ['s1', 'PHYS110', 'moved'], ['s3', 'MATH101', 'removed'], ['s3', 'MATH101H', 'added'],
    ['s3', 'PHYS110', 'moved'], ['s4', 'BIO130', 'moved'], ['s4', 'MATH101', 'removed'],
    ['s5', 'CHEM120', 'removed'], ['s5', 'MATH101H', 'added']]),
  ('partial repair guard 3',
   [{'MATH101': [1, 'H1'],
     'MATH101H': [2, 'G1'],
     'PHYS110': [2, 'L1'],
     'CHEM120': [3, 'L1'],
     'BIO130': [1, 'L1']},
    {'MATH101': [2, 'L2'],
     'MATH101H': [2, 'G1'],
     'PHYS110': [2, 'L1'],
     'CHEM120': [1, 'H2'],
     'BIO130': [2, 'H2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s5', 'PHYS110'], ['s1', 'PHYS110'], ['s2', 'MATH101H'], ['s5', 'BIO130'], ['s4', 'MATH101'],
     ['s5', 'BIO130']]],
   [['s4', 'MATH101', 'moved'], ['s5', 'BIO130', 'moved']]),
  ('boundary control 4',
   [{'A': [0, 'H1'], 'B': [1, 'L1']}, {'A': [2, 'H1'], 'B': [1, 'H2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s2', 'A'], ['s1', 'B'], ['s1', 'A']]],
   [['s1', 'A', 'moved'], ['s1', 'B', 'venue'], ['s2', 'A', 'moved']]),
  ('normal control 5',
   [{'MATH101': [0, 'L2'], 'MATH101H': [2, 'G1'], 'CHEM120': [0, 'L1'], 'BIO130': [3, 'G1']},
    {'MATH101': [0, 'L2'],
     'MATH101H': [2, 'G1'],
     'PHYS110': [2, 'H2'],
     'CHEM120': [0, 'L1'],
     'BIO130': [2, 'L2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'HIST140'], ['s3', 'BIO130'], ['s2', 'BIO130'], ['s1', 'MATH101H'], ['s5', 'ECON150'],
     ['s1', 'HIST140'], ['s4', 'MATH101'], ['s1', 'BIO130'], ['s4', 'HIST140'], ['s2', 'PHYS110']]],
   [['s1', 'BIO130', 'moved'], ['s2', 'BIO130', 'moved'], ['s2', 'PHYS110', 'added'],
    ['s3', 'BIO130', 'moved']]),
  ('normal control 6',
   [{'MATH101H': [1, 'L2'], 'PHYS110': [2, 'L2'], 'CHEM120': [0, 'G1'], 'BIO130': [2, 'H2']},
    {'MATH101H': [2, 'H2'], 'PHYS110': [2, 'L2'], 'CHEM120': [0, 'G1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s4', 'CHEM120'], ['s3', 'MATH101H'], ['s2', 'HIST140'], ['s5', 'CHEM120'], ['s2', 'BIO130'],
     ['s3', 'PHYS110'], ['s2', 'MATH101'], ['s3', 'CHEM120'], ['s4', 'HIST140'], ['s1', 'CHEM120'],
     ['s3', 'HIST140'], ['s3', 'PHYS110'], ['s4', 'PHYS110']]],
   [['s2', 'BIO130', 'removed'], ['s3', 'MATH101H', 'moved']]),
  ('normal control 7',
   [{'MATH101': [2, 'H1'], 'MATH101H': [0, 'L2'], 'CHEM120': [2, 'L2']},
    {'MATH101': [2, 'H1'],
     'MATH101H': [2, 'G1'],
     'PHYS110': [0, 'G1'],
     'CHEM120': [2, 'L2'],
     'BIO130': [3, 'G1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s4', 'HIST140'], ['s4', 'BIO130'], ['s4', 'MATH101H'], ['s2', 'BIO130']]],
   [['s2', 'BIO130', 'added'], ['s4', 'BIO130', 'added'], ['s4', 'MATH101H', 'moved']]),
  ('normal control 8',
   [{'MATH101': [3, 'L1'], 'MATH101H': [1, 'G1'], 'PHYS110': [2, 'H1'], 'BIO130': [3, 'L2']},
    {'MATH101': [3, 'L1'],
     'MATH101H': [1, 'G1'],
     'PHYS110': [2, 'H1'],
     'CHEM120': [2, 'H2'],
     'BIO130': [3, 'L2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s4', 'MATH101'], ['s4', 'MATH101'], ['s4', 'PHYS110'], ['s4', 'MATH101H']]],
   [])],
 [('regression: notification dedupe 1',
   [{'MATH101': [1, 'L1'],
     'MATH101H': [3, 'G1'],
     'PHYS110': [2, 'H2'],
     'CHEM120': [3, 'H2'],
     'BIO130': [0, 'H1']},
    {'MATH101': [2, 'G1'], 'CHEM120': [3, 'H1'], 'BIO130': [0, 'H1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s4', 'ECON150'], ['s4', 'PHYS110'], ['s1', 'HIST140'], ['s4', 'PHYS110'], ['s5', 'BIO130'],
     ['s2', 'ECON150'], ['s2', 'HIST140'], ['s5', 'MATH101H']]],
   [['s4', 'PHYS110', 'removed'], ['s5', 'MATH101H', 'removed']]),
  ('regression variant: notification dedupe 2',
   [{'BIO130': [0, 'H1']},
    {'MATH101': [2, 'G1'], 'MATH101H': [1, 'H1'], 'CHEM120': [2, 'L1'], 'BIO130': [1, 'L1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'ECON150'], ['s1', 'BIO130'], ['s1', 'HIST140'], ['s3', 'MATH101H'], ['s4', 'CHEM120'],
     ['s3', 'CHEM120'], ['s1', 'CHEM120'], ['s2', 'MATH101'], ['s1', 'PHYS110'], ['s4', 'HIST140'],
     ['s3', 'BIO130'], ['s1', 'CHEM120']]],
   [['s1', 'BIO130', 'moved'], ['s1', 'CHEM120', 'added'], ['s2', 'MATH101', 'added'],
    ['s3', 'BIO130', 'moved'], ['s3', 'CHEM120', 'added'], ['s3', 'MATH101H', 'added'],
    ['s4', 'CHEM120', 'added']]),
  ('partial repair guard 3',
   [{'MATH101': [3, 'L2'],
     'MATH101H': [0, 'G1'],
     'PHYS110': [2, 'L1'],
     'CHEM120': [2, 'H1'],
     'BIO130': [2, 'H1']},
    {'MATH101': [3, 'L2'],
     'MATH101H': [1, 'G1'],
     'PHYS110': [3, 'L1'],
     'CHEM120': [1, 'L1'],
     'BIO130': [2, 'H1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s4', 'MATH101H'], ['s5', 'MATH101'], ['s2', 'CHEM120'], ['s2', 'MATH101'], ['s5', 'CHEM120'],
     ['s2', 'MATH101H'], ['s1', 'HIST140'], ['s5', 'MATH101'], ['s1', 'BIO130'], ['s4', 'BIO130']]],
   [['s2', 'CHEM120', 'moved'], ['s2', 'MATH101H', 'moved'], ['s4', 'MATH101H', 'moved'],
    ['s5', 'CHEM120', 'moved']]),
  ('boundary control 4',
   [{'A': [0, 'H1']}, {}, {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'A']]],
   [['s1', 'A', 'removed']]),
  ('normal control 5',
   [{'MATH101H': [1, 'G1'], 'PHYS110': [0, 'L1'], 'CHEM120': [3, 'G1'], 'BIO130': [0, 'H2']},
    {'MATH101': [3, 'L2'],
     'MATH101H': [1, 'G1'],
     'PHYS110': [3, 'H2'],
     'CHEM120': [3, 'G1'],
     'BIO130': [1, 'H1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'MATH101H'], ['s5', 'HIST140'], ['s4', 'ECON150'], ['s3', 'MATH101'], ['s5', 'MATH101H'],
     ['s2', 'PHYS110'], ['s4', 'MATH101H'], ['s2', 'CHEM120'], ['s2', 'MATH101'], ['s5', 'BIO130'],
     ['s5', 'CHEM120'], ['s2', 'HIST140']]],
   [['s2', 'MATH101', 'added'], ['s2', 'PHYS110', 'moved'], ['s3', 'MATH101', 'added'],
    ['s5', 'BIO130', 'moved']]),
  ('normal control 6',
   [{'MATH101': [0, 'H1'], 'MATH101H': [2, 'L1'], 'CHEM120': [3, 'L2'], 'BIO130': [0, 'G1']},
    {'MATH101': [0, 'H1'],
     'MATH101H': [0, 'L2'],
     'PHYS110': [2, 'L2'],
     'CHEM120': [0, 'H1'],
     'BIO130': [0, 'H1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s4', 'PHYS110'], ['s5', 'HIST140'], ['s4', 'MATH101H'], ['s4', 'ECON150'], ['s5', 'MATH101H'],
     ['s3', 'PHYS110']]],
   [['s3', 'PHYS110', 'added'], ['s4', 'MATH101H', 'moved'], ['s4', 'PHYS110', 'added'],
    ['s5', 'MATH101H', 'moved']]),
  ('normal control 7',
   [{'MATH101': [1, 'L1'], 'MATH101H': [2, 'G1'], 'PHYS110': [2, 'L2'], 'CHEM120': [1, 'G1']},
    {'MATH101': [1, 'L1'], 'MATH101H': [0, 'G1'], 'PHYS110': [0, 'G1'], 'CHEM120': [1, 'G1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'MATH101'], ['s2', 'HIST140'], ['s2', 'BIO130'], ['s1', 'BIO130'], ['s1', 'MATH101H'],
     ['s2', 'BIO130']]],
   [['s1', 'MATH101H', 'moved']]),
  ('normal control 8',
   [{'MATH101': [1, 'L1'],
     'MATH101H': [2, 'H1'],
     'PHYS110': [3, 'H1'],
     'CHEM120': [2, 'G1'],
     'BIO130': [1, 'G1']},
    {'MATH101': [1, 'L1'],
     'MATH101H': [2, 'H1'],
     'PHYS110': [3, 'H1'],
     'CHEM120': [2, 'G1'],
     'BIO130': [0, 'L1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'BIO130'], ['s3', 'CHEM120'], ['s5', 'HIST140'], ['s2', 'PHYS110'], ['s2', 'BIO130'],
     ['s1', 'MATH101H'], ['s1', 'ECON150'], ['s5', 'ECON150'], ['s1', 'MATH101'], ['s1', 'BIO130'],
     ['s3', 'HIST140'], ['s2', 'MATH101H']]],
   [['s1', 'BIO130', 'moved'], ['s2', 'BIO130', 'moved'], ['s3', 'BIO130', 'moved']])],
 [('regression: notification dedupe 1',
   [{'MATH101': [1, 'L1'],
     'MATH101H': [0, 'H1'],
     'PHYS110': [2, 'G1'],
     'CHEM120': [0, 'G1'],
     'BIO130': [3, 'H2']},
    {'MATH101': [1, 'L1'],
     'MATH101H': [2, 'H1'],
     'PHYS110': [3, 'H2'],
     'CHEM120': [0, 'L2'],
     'BIO130': [3, 'H2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s2', 'MATH101'], ['s5', 'CHEM120'], ['s5', 'HIST140'], ['s1', 'MATH101'], ['s1', 'ECON150'],
     ['s2', 'ECON150'], ['s1', 'CHEM120'], ['s5', 'MATH101'], ['s1', 'CHEM120'], ['s5', 'BIO130'],
     ['s2', 'PHYS110'], ['s2', 'CHEM120']]],
   [['s1', 'CHEM120', 'venue'], ['s2', 'CHEM120', 'venue'], ['s2', 'PHYS110', 'moved'],
    ['s5', 'CHEM120', 'venue']]),
  ('regression variant: notification dedupe 2',
   [{'MATH101': [2, 'G1'], 'MATH101H': [3, 'H1'], 'PHYS110': [0, 'H1'], 'CHEM120': [1, 'H2']},
    {'MATH101': [2, 'G1'],
     'MATH101H': [3, 'H1'],
     'PHYS110': [2, 'H1'],
     'CHEM120': [0, 'L1'],
     'BIO130': [2, 'H1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'MATH101'], ['s5', 'BIO130'], ['s5', 'CHEM120'], ['s1', 'ECON150'], ['s5', 'ECON150'],
     ['s5', 'CHEM120'], ['s1', 'CHEM120'], ['s3', 'BIO130'], ['s4', 'BIO130'], ['s1', 'BIO130'],
     ['s5', 'MATH101H']]],
   [['s1', 'BIO130', 'added'], ['s1', 'CHEM120', 'moved'], ['s3', 'BIO130', 'added'],
    ['s4', 'BIO130', 'added'], ['s5', 'BIO130', 'added'], ['s5', 'CHEM120', 'moved']]),
  ('partial repair guard 3',
   [{'MATH101': [2, 'L2'], 'MATH101H': [2, 'L1'], 'CHEM120': [3, 'H2'], 'BIO130': [0, 'L2']},
    {'MATH101H': [2, 'G1'], 'PHYS110': [3, 'H1'], 'CHEM120': [3, 'H2'], 'BIO130': [0, 'L2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'MATH101'], ['s2', 'MATH101'], ['s3', 'BIO130'], ['s2', 'PHYS110'], ['s3', 'PHYS110'],
     ['s2', 'CHEM120'], ['s3', 'HIST140'], ['s5', 'ECON150'], ['s5', 'PHYS110']]],
   [['s2', 'MATH101', 'removed'], ['s2', 'PHYS110', 'added'], ['s3', 'MATH101', 'removed'],
    ['s3', 'PHYS110', 'added'], ['s5', 'PHYS110', 'added']]),
  ('boundary control 4',
   [{'A': [0, 'H1']}, {'A': [0, 'H2']}, {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'A']]],
   []),
  ('normal control 5',
   [{'MATH101': [3, 'L2'],
     'MATH101H': [0, 'L2'],
     'PHYS110': [3, 'L1'],
     'CHEM120': [1, 'L1'],
     'BIO130': [1, 'H2']},
    {'MATH101': [1, 'H1'],
     'MATH101H': [3, 'H1'],
     'PHYS110': [3, 'L1'],
     'CHEM120': [1, 'L1'],
     'BIO130': [1, 'H2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'ECON150'], ['s1', 'ECON150']]],
   []),
  ('normal control 6',
   [{'MATH101': [3, 'G1'], 'PHYS110': [1, 'L1'], 'CHEM120': [2, 'H1'], 'BIO130': [1, 'H2']},
    {'MATH101': [3, 'G1'],
     'MATH101H': [2, 'L1'],
     'PHYS110': [1, 'H2'],
     'CHEM120': [2, 'H1'],
     'BIO130': [1, 'H2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s2', 'MATH101H'], ['s5', 'ECON150'], ['s3', 'MATH101'], ['s1', 'BIO130'], ['s1', 'CHEM120'],
     ['s4', 'ECON150'], ['s5', 'MATH101H'], ['s1', 'ECON150'], ['s1', 'MATH101'], ['s3', 'ECON150'],
     ['s4', 'HIST140'], ['s4', 'BIO130'], ['s2', 'MATH101'], ['s2', 'CHEM120'], ['s3', 'CHEM120']]],
   [['s2', 'MATH101H', 'added'], ['s5', 'MATH101H', 'added']]),
  ('normal control 7',
   [{'MATH101': [0, 'H1'],
     'MATH101H': [3, 'G1'],
     'PHYS110': [1, 'L1'],
     'CHEM120': [0, 'L2'],
     'BIO130': [3, 'G1']},
    {'MATH101': [0, 'H1'],
     'MATH101H': [0, 'L1'],
     'PHYS110': [1, 'L1'],
     'CHEM120': [0, 'L2'],
     'BIO130': [3, 'G1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'MATH101'], ['s2', 'ECON150'], ['s2', 'CHEM120'], ['s3', 'CHEM120'], ['s1', 'MATH101H'],
     ['s4', 'CHEM120'], ['s3', 'ECON150'], ['s2', 'MATH101'], ['s1', 'HIST140'], ['s3', 'HIST140'],
     ['s2', 'MATH101H'], ['s5', 'HIST140']]],
   [['s1', 'MATH101H', 'moved'], ['s2', 'MATH101H', 'moved']]),
  ('normal control 8',
   [{'MATH101': [3, 'H1'],
     'MATH101H': [3, 'H1'],
     'PHYS110': [2, 'G1'],
     'CHEM120': [0, 'H1'],
     'BIO130': [0, 'H1']},
    {'MATH101H': [3, 'H1'], 'PHYS110': [2, 'H1'], 'BIO130': [0, 'H1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s2', 'MATH101H'], ['s4', 'CHEM120'], ['s4', 'HIST140'], ['s1', 'ECON150'], ['s5', 'ECON150'],
     ['s4', 'ECON150'], ['s2', 'MATH101'], ['s5', 'MATH101'], ['s1', 'BIO130'], ['s5', 'MATH101H'],
     ['s4', 'MATH101'], ['s2', 'HIST140'], ['s5', 'PHYS110']]],
   [['s2', 'MATH101', 'removed'], ['s4', 'CHEM120', 'removed'], ['s4', 'MATH101', 'removed'],
    ['s5', 'MATH101', 'removed']])]]
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: notification dedupe 1[['s1', 'CHEM120', 'added'], ['s2', 'CHEM120', 'added'], ['s5', 'CHEM120', 'added'], ['s2', 'MATH101', 'added'], ['s4', 'MATH101', 'added'], ['s2', 'MATH101H', 'moved'], ['s4', 'MATH101H', 'moved']][['s1', 'CHEM120', 'added'], ['s2', 'CHEM120', 'added'], ['s2', 'MATH101', 'added'], ['s2', 'MATH101H', 'moved'], ['s4', 'MATH101', 'added'], ['s4', 'MATH101H', 'moved'], ['s5', 'CHEM120', 'added']]Failed
regression variant: notification dedupe 2[['s1', 'BIO130', 'added'], ['s2', 'BIO130', 'added'], ['s2', 'CHEM120', 'removed'], ['s4', 'CHEM120', 'removed']][['s1', 'BIO130', 'added'], ['s2', 'BIO130', 'added'], ['s2', 'CHEM120', 'removed'], ['s4', 'CHEM120', 'removed']]Passed
partial repair guard 3[['s5', 'MATH101H', 'removed'], ['s4', 'PHYS110', 'removed']][['s4', 'PHYS110', 'removed'], ['s5', 'MATH101H', 'removed']]Failed
boundary control 4[][]Passed
normal control 5[['s1', 'BIO130', 'moved'], ['s3', 'BIO130', 'moved'], ['s1', 'CHEM120', 'added'], ['s3', 'CHEM120', 'added'], ['s4', 'CHEM120', 'added'], ['s2', 'MATH101', 'added'], ['s3', 'MATH101H', 'added']][['s1', 'BIO130', 'moved'], ['s1', 'CHEM120', 'added'], ['s2', 'MATH101', 'added'], ['s3', 'BIO130', 'moved'], ['s3', 'CHEM120', 'added'], ['s3', 'MATH101H', 'added'], ['s4', 'CHEM120', 'added']]Failed
normal control 6[['s1', 'CHEM120', 'added']][['s1', 'CHEM120', 'added']]Passed
normal control 7[['s4', 'BIO130', 'venue'], ['s5', 'BIO130', 'venue']][['s4', 'BIO130', 'venue'], ['s5', 'BIO130', 'venue']]Passed
normal control 8[['s1', 'BIO130', 'moved'], ['s1', 'MATH101H', 'moved']][['s1', 'BIO130', 'moved'], ['s1', 'MATH101H', 'moved']]Passed

SHA-256 / bd177ef43be47da5d7353bab914920c1234aa0ce79d642f9f49e106763183f68

3 / The verified repair

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

N = 1
observations = []
def solve(old, new, rooms, enrol):
    reasons = {}
    for ex in set(old) | set(new):
        if ex not in old:
            reasons[ex] = 'added'
        elif ex not in new:
            reasons[ex] = 'removed'
        elif old[ex][0] != new[ex][0]:
            reasons[ex] = 'moved'
        elif rooms[old[ex][1]] != rooms[new[ex][1]]:
            reasons[ex] = 'venue'
    out = sorted(set((st, ex, reasons[ex]) for st, ex in enrol if ex in reasons))
    return [list(t) for t in out]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: notification dedupe 1',
   [{'MATH101H': [0, 'L1'], 'BIO130': [2, 'H2']},
    {'MATH101': [3, 'H1'],
     'MATH101H': [3, 'G1'],
     'PHYS110': [2, 'L2'],
     'CHEM120': [2, 'L2'],
     'BIO130': [2, 'H2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s5', 'BIO130'], ['s2', 'MATH101H'], ['s1', 'BIO130'], ['s2', 'HIST140'], ['s2', 'MATH101'],
     ['s5', 'CHEM120'], ['s5', 'HIST140'], ['s4', 'MATH101H'], ['s4', 'BIO130'], ['s2', 'CHEM120'],
     ['s4', 'HIST140'], ['s4', 'MATH101'], ['s1', 'CHEM120'], ['s5', 'CHEM120']]],
   [['s1', 'CHEM120', 'added'], ['s2', 'CHEM120', 'added'], ['s2', 'MATH101', 'added'],
    ['s2', 'MATH101H', 'moved'], ['s4', 'MATH101', 'added'], ['s4', 'MATH101H', 'moved'],
    ['s5', 'CHEM120', 'added']]),
  ('regression variant: notification dedupe 2',
   [{'MATH101': [3, 'L2'], 'MATH101H': [2, 'H2'], 'CHEM120': [3, 'G1']},
    {'MATH101': [3, 'L2'], 'MATH101H': [2, 'H2'], 'PHYS110': [1, 'G1'], 'BIO130': [0, 'L1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s2', 'MATH101'], ['s3', 'ECON150'], ['s4', 'CHEM120'], ['s2', 'CHEM120'], ['s1', 'BIO130'],
     ['s2', 'HIST140'], ['s5', 'HIST140'], ['s4', 'CHEM120'], ['s4', 'MATH101H'], ['s4', 'ECON150'],
     ['s2', 'BIO130'], ['s5', 'MATH101']]],
   [['s1', 'BIO130', 'added'], ['s2', 'BIO130', 'added'], ['s2', 'CHEM120', 'removed'],
    ['s4', 'CHEM120', 'removed']]),
  ('partial repair guard 3',
   [{'MATH101': [1, 'L1'],
     'MATH101H': [3, 'G1'],
     'PHYS110': [2, 'H2'],
     'CHEM120': [3, 'H2'],
     'BIO130': [0, 'H1']},
    {'MATH101': [2, 'G1'], 'CHEM120': [3, 'H1'], 'BIO130': [0, 'H1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s4', 'ECON150'], ['s4', 'PHYS110'], ['s1', 'HIST140'], ['s4', 'PHYS110'], ['s5', 'BIO130'],
     ['s2', 'ECON150'], ['s2', 'HIST140'], ['s5', 'MATH101H']]],
   [['s4', 'PHYS110', 'removed'], ['s5', 'MATH101H', 'removed']]),
  ('boundary control 4',
   [{'A': [0, 'H1']}, {'A': [0, 'G1']}, {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'A'], ['s1', 'A']]],
   []),
  ('normal control 5',
   [{'BIO130': [0, 'H1']},
    {'MATH101': [2, 'G1'], 'MATH101H': [1, 'H1'], 'CHEM120': [2, 'L1'], 'BIO130': [1, 'L1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'ECON150'], ['s1', 'BIO130'], ['s1', 'HIST140'], ['s3', 'MATH101H'], ['s4', 'CHEM120'],
     ['s3', 'CHEM120'], ['s1', 'CHEM120'], ['s2', 'MATH101'], ['s1', 'PHYS110'], ['s4', 'HIST140'],
     ['s3', 'BIO130'], ['s1', 'CHEM120']]],
   [['s1', 'BIO130', 'moved'], ['s1', 'CHEM120', 'added'], ['s2', 'MATH101', 'added'],
    ['s3', 'BIO130', 'moved'], ['s3', 'CHEM120', 'added'], ['s3', 'MATH101H', 'added'],
    ['s4', 'CHEM120', 'added']]),
  ('normal control 6',
   [{'MATH101': [0, 'H2'], 'MATH101H': [1, 'H2'], 'PHYS110': [3, 'G1'], 'BIO130': [0, 'L2']},
    {'MATH101': [0, 'H2'],
     'MATH101H': [1, 'H2'],
     'PHYS110': [3, 'G1'],
     'CHEM120': [3, 'L1'],
     'BIO130': [0, 'L2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'MATH101H'], ['s1', 'CHEM120'], ['s1', 'MATH101'], ['s1', 'BIO130']]],
   [['s1', 'CHEM120', 'added']]),
  ('normal control 7',
   [{'MATH101': [2, 'L1'], 'MATH101H': [3, 'L1'], 'PHYS110': [1, 'G1'], 'BIO130': [1, 'H2']},
    {'MATH101': [2, 'L1'], 'MATH101H': [3, 'L1'], 'PHYS110': [1, 'G1'], 'BIO130': [1, 'L1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'PHYS110'], ['s2', 'MATH101H'], ['s5', 'MATH101H'], ['s5', 'BIO130'], ['s4', 'ECON150'],
     ['s5', 'MATH101'], ['s2', 'CHEM120'], ['s4', 'MATH101H'], ['s4', 'BIO130'], ['s5', 'CHEM120']]],
   [['s4', 'BIO130', 'venue'], ['s5', 'BIO130', 'venue']]),
  ('normal control 8',
   [{'MATH101': [0, 'H1'],
     'MATH101H': [0, 'H2'],
     'PHYS110': [3, 'L1'],
     'CHEM120': [3, 'L1'],
     'BIO130': [1, 'L1']},
    {'MATH101': [2, 'L2'],
     'MATH101H': [2, 'L1'],
     'PHYS110': [3, 'L1'],
     'CHEM120': [2, 'H2'],
     'BIO130': [0, 'G1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'ECON150'], ['s1', 'BIO130'], ['s1', 'MATH101H'], ['s1', 'HIST140']]],
   [['s1', 'BIO130', 'moved'], ['s1', 'MATH101H', 'moved']])],
 [('regression: notification dedupe 1',
   [{'MATH101': [2, 'G1'],
     'MATH101H': [0, 'G1'],
     'PHYS110': [3, 'L1'],
     'CHEM120': [1, 'L1'],
     'BIO130': [3, 'H1']},
    {'MATH101': [2, 'G1'], 'MATH101H': [0, 'G1'], 'PHYS110': [3, 'L1'], 'BIO130': [3, 'H1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'CHEM120'], ['s4', 'BIO130'], ['s2', 'PHYS110'], ['s3', 'BIO130'], ['s4', 'ECON150'],
     ['s3', 'CHEM120'], ['s4', 'MATH101H'], ['s3', 'ECON150'], ['s4', 'CHEM120'], ['s2', 'CHEM120']]],
   [['s2', 'CHEM120', 'removed'], ['s3', 'CHEM120', 'removed'], ['s4', 'CHEM120', 'removed']]),
  ('regression variant: notification dedupe 2',
   [{'MATH101': [2, 'L2'],
     'MATH101H': [2, 'H1'],
     'PHYS110': [1, 'H2'],
     'CHEM120': [1, 'L2'],
     'BIO130': [2, 'H2']},
    {'MATH101': [2, 'L2'], 'MATH101H': [2, 'G1'], 'PHYS110': [3, 'H1'], 'BIO130': [2, 'H2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'PHYS110'], ['s1', 'PHYS110']]],
   [['s1', 'PHYS110', 'moved']]),
  ('partial repair guard 3',
   [{'MATH101': [0, 'L2'], 'MATH101H': [2, 'G1'], 'CHEM120': [0, 'L1'], 'BIO130': [3, 'G1']},
    {'MATH101': [0, 'L2'],
     'MATH101H': [2, 'G1'],
     'PHYS110': [2, 'H2'],
     'CHEM120': [0, 'L1'],
     'BIO130': [2, 'L2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'HIST140'], ['s3', 'BIO130'], ['s2', 'BIO130'], ['s1', 'MATH101H'], ['s5', 'ECON150'],
     ['s1', 'HIST140'], ['s4', 'MATH101'], ['s1', 'BIO130'], ['s4', 'HIST140'], ['s2', 'PHYS110']]],
   [['s1', 'BIO130', 'moved'], ['s2', 'BIO130', 'moved'], ['s2', 'PHYS110', 'added'],
    ['s3', 'BIO130', 'moved']]),
  ('boundary control 4',
   [{'A': [0, 'H1']}, {'A': [1, 'L1']}, {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'A']]],
   [['s1', 'A', 'moved']]),
  ('normal control 5',
   [{'MATH101': [0, 'G1'], 'MATH101H': [3, 'L2'], 'CHEM120': [0, 'L1']},
    {'MATH101': [0, 'G1'], 'PHYS110': [3, 'H2'], 'CHEM120': [0, 'L1'], 'BIO130': [3, 'L1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'PHYS110'], ['s4', 'CHEM120'], ['s1', 'BIO130'], ['s4', 'MATH101'], ['s5', 'MATH101'],
     ['s2', 'PHYS110'], ['s1', 'HIST140'], ['s1', 'PHYS110'], ['s2', 'MATH101'], ['s4', 'ECON150'],
     ['s2', 'ECON150'], ['s5', 'MATH101H'], ['s5', 'ECON150'], ['s4', 'PHYS110']]],
   [['s1', 'BIO130', 'added'], ['s1', 'PHYS110', 'added'], ['s2', 'PHYS110', 'added'],
    ['s3', 'PHYS110', 'added'], ['s4', 'PHYS110', 'added'], ['s5', 'MATH101H', 'removed']]),
  ('normal control 6',
   [{'MATH101': [2, 'G1'],
     'MATH101H': [1, 'H1'],
     'PHYS110': [1, 'H2'],
     'CHEM120': [2, 'H1'],
     'BIO130': [1, 'L2']},
    {'MATH101': [2, 'L1'],
     'MATH101H': [2, 'H1'],
     'PHYS110': [3, 'H1'],
     'CHEM120': [2, 'H1'],
     'BIO130': [1, 'L2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'MATH101'], ['s4', 'HIST140'], ['s4', 'BIO130'], ['s3', 'HIST140'], ['s4', 'CHEM120']]],
   [['s3', 'MATH101', 'venue']]),
  ('normal control 7',
   [{'MATH101': [2, 'H1'],
     'MATH101H': [0, 'H1'],
     'PHYS110': [1, 'L1'],
     'CHEM120': [1, 'G1'],
     'BIO130': [2, 'L2']},
    {'MATH101': [2, 'H1'],
     'MATH101H': [0, 'L1'],
     'PHYS110': [0, 'H2'],
     'CHEM120': [1, 'G1'],
     'BIO130': [2, 'L1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'}, [['s2', 'BIO130']]],
   []),
  ('normal control 8',
   [{'MATH101': [1, 'L2'], 'MATH101H': [1, 'L1'], 'CHEM120': [2, 'G1'], 'BIO130': [1, 'L1']},
    {'MATH101': [1, 'L2'],
     'MATH101H': [0, 'G1'],
     'PHYS110': [3, 'G1'],
     'CHEM120': [3, 'H1'],
     'BIO130': [1, 'L1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'MATH101'], ['s2', 'MATH101'], ['s4', 'MATH101'], ['s2', 'MATH101H'], ['s2', 'ECON150'],
     ['s4', 'ECON150'], ['s5', 'PHYS110'], ['s2', 'HIST140'], ['s3', 'CHEM120'], ['s5', 'ECON150'],
     ['s1', 'CHEM120'], ['s4', 'MATH101H'], ['s5', 'PHYS110']]],
   [['s1', 'CHEM120', 'moved'], ['s2', 'MATH101H', 'moved'], ['s3', 'CHEM120', 'moved'],
    ['s4', 'MATH101H', 'moved'], ['s5', 'PHYS110', 'added']])],
 [('regression: notification dedupe 1',
   [{'MATH101': [1, 'H1'],
     'MATH101H': [3, 'H1'],
     'PHYS110': [0, 'H2'],
     'CHEM120': [1, 'H2'],
     'BIO130': [0, 'H1']},
    {'MATH101': [1, 'H1'],
     'MATH101H': [3, 'H1'],
     'PHYS110': [3, 'L2'],
     'CHEM120': [2, 'G1'],
     'BIO130': [0, 'H1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s5', 'HIST140'], ['s3', 'BIO130'], ['s5', 'MATH101H'], ['s1', 'MATH101H'], ['s3', 'PHYS110'],
     ['s5', 'MATH101'], ['s5', 'CHEM120'], ['s3', 'PHYS110'], ['s3', 'MATH101H']]],
   [['s3', 'PHYS110', 'moved'], ['s5', 'CHEM120', 'moved']]),
  ('regression variant: notification dedupe 2',
   [{'MATH101': [0, 'H2'], 'PHYS110': [0, 'H2'], 'CHEM120': [3, 'G1'], 'BIO130': [3, 'H1']},
    {'MATH101H': [2, 'H2'], 'PHYS110': [3, 'L1'], 'BIO130': [2, 'G1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'PHYS110'], ['s4', 'ECON150'], ['s5', 'ECON150'], ['s3', 'MATH101'], ['s1', 'MATH101H'],
     ['s4', 'HIST140'], ['s1', 'PHYS110'], ['s5', 'CHEM120'], ['s3', 'MATH101H'], ['s1', 'BIO130'],
     ['s5', 'MATH101H'], ['s1', 'CHEM120'], ['s5', 'MATH101H'], ['s4', 'MATH101'], ['s5', 'HIST140'],
     ['s4', 'BIO130']]],
   [['s1', 'BIO130', 'moved'], ['s1', 'CHEM120', 'removed'], ['s1', 'MATH101H', 'added'],
    ['s1', 'PHYS110', 'moved'], ['s3', 'MATH101', 'removed'], ['s3', 'MATH101H', 'added'],
    ['s3', 'PHYS110', 'moved'], ['s4', 'BIO130', 'moved'], ['s4', 'MATH101', 'removed'],
    ['s5', 'CHEM120', 'removed'], ['s5', 'MATH101H', 'added']]),
  ('partial repair guard 3',
   [{'MATH101': [1, 'H1'],
     'MATH101H': [2, 'G1'],
     'PHYS110': [2, 'L1'],
     'CHEM120': [3, 'L1'],
     'BIO130': [1, 'L1']},
    {'MATH101': [2, 'L2'],
     'MATH101H': [2, 'G1'],
     'PHYS110': [2, 'L1'],
     'CHEM120': [1, 'H2'],
     'BIO130': [2, 'H2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s5', 'PHYS110'], ['s1', 'PHYS110'], ['s2', 'MATH101H'], ['s5', 'BIO130'], ['s4', 'MATH101'],
     ['s5', 'BIO130']]],
   [['s4', 'MATH101', 'moved'], ['s5', 'BIO130', 'moved']]),
  ('boundary control 4',
   [{'A': [0, 'H1'], 'B': [1, 'L1']}, {'A': [2, 'H1'], 'B': [1, 'H2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s2', 'A'], ['s1', 'B'], ['s1', 'A']]],
   [['s1', 'A', 'moved'], ['s1', 'B', 'venue'], ['s2', 'A', 'moved']]),
  ('normal control 5',
   [{'MATH101': [0, 'L2'], 'MATH101H': [2, 'G1'], 'CHEM120': [0, 'L1'], 'BIO130': [3, 'G1']},
    {'MATH101': [0, 'L2'],
     'MATH101H': [2, 'G1'],
     'PHYS110': [2, 'H2'],
     'CHEM120': [0, 'L1'],
     'BIO130': [2, 'L2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'HIST140'], ['s3', 'BIO130'], ['s2', 'BIO130'], ['s1', 'MATH101H'], ['s5', 'ECON150'],
     ['s1', 'HIST140'], ['s4', 'MATH101'], ['s1', 'BIO130'], ['s4', 'HIST140'], ['s2', 'PHYS110']]],
   [['s1', 'BIO130', 'moved'], ['s2', 'BIO130', 'moved'], ['s2', 'PHYS110', 'added'],
    ['s3', 'BIO130', 'moved']]),
  ('normal control 6',
   [{'MATH101H': [1, 'L2'], 'PHYS110': [2, 'L2'], 'CHEM120': [0, 'G1'], 'BIO130': [2, 'H2']},
    {'MATH101H': [2, 'H2'], 'PHYS110': [2, 'L2'], 'CHEM120': [0, 'G1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s4', 'CHEM120'], ['s3', 'MATH101H'], ['s2', 'HIST140'], ['s5', 'CHEM120'], ['s2', 'BIO130'],
     ['s3', 'PHYS110'], ['s2', 'MATH101'], ['s3', 'CHEM120'], ['s4', 'HIST140'], ['s1', 'CHEM120'],
     ['s3', 'HIST140'], ['s3', 'PHYS110'], ['s4', 'PHYS110']]],
   [['s2', 'BIO130', 'removed'], ['s3', 'MATH101H', 'moved']]),
  ('normal control 7',
   [{'MATH101': [2, 'H1'], 'MATH101H': [0, 'L2'], 'CHEM120': [2, 'L2']},
    {'MATH101': [2, 'H1'],
     'MATH101H': [2, 'G1'],
     'PHYS110': [0, 'G1'],
     'CHEM120': [2, 'L2'],
     'BIO130': [3, 'G1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s4', 'HIST140'], ['s4', 'BIO130'], ['s4', 'MATH101H'], ['s2', 'BIO130']]],
   [['s2', 'BIO130', 'added'], ['s4', 'BIO130', 'added'], ['s4', 'MATH101H', 'moved']]),
  ('normal control 8',
   [{'MATH101': [3, 'L1'], 'MATH101H': [1, 'G1'], 'PHYS110': [2, 'H1'], 'BIO130': [3, 'L2']},
    {'MATH101': [3, 'L1'],
     'MATH101H': [1, 'G1'],
     'PHYS110': [2, 'H1'],
     'CHEM120': [2, 'H2'],
     'BIO130': [3, 'L2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s4', 'MATH101'], ['s4', 'MATH101'], ['s4', 'PHYS110'], ['s4', 'MATH101H']]],
   [])],
 [('regression: notification dedupe 1',
   [{'MATH101': [1, 'L1'],
     'MATH101H': [3, 'G1'],
     'PHYS110': [2, 'H2'],
     'CHEM120': [3, 'H2'],
     'BIO130': [0, 'H1']},
    {'MATH101': [2, 'G1'], 'CHEM120': [3, 'H1'], 'BIO130': [0, 'H1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s4', 'ECON150'], ['s4', 'PHYS110'], ['s1', 'HIST140'], ['s4', 'PHYS110'], ['s5', 'BIO130'],
     ['s2', 'ECON150'], ['s2', 'HIST140'], ['s5', 'MATH101H']]],
   [['s4', 'PHYS110', 'removed'], ['s5', 'MATH101H', 'removed']]),
  ('regression variant: notification dedupe 2',
   [{'BIO130': [0, 'H1']},
    {'MATH101': [2, 'G1'], 'MATH101H': [1, 'H1'], 'CHEM120': [2, 'L1'], 'BIO130': [1, 'L1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'ECON150'], ['s1', 'BIO130'], ['s1', 'HIST140'], ['s3', 'MATH101H'], ['s4', 'CHEM120'],
     ['s3', 'CHEM120'], ['s1', 'CHEM120'], ['s2', 'MATH101'], ['s1', 'PHYS110'], ['s4', 'HIST140'],
     ['s3', 'BIO130'], ['s1', 'CHEM120']]],
   [['s1', 'BIO130', 'moved'], ['s1', 'CHEM120', 'added'], ['s2', 'MATH101', 'added'],
    ['s3', 'BIO130', 'moved'], ['s3', 'CHEM120', 'added'], ['s3', 'MATH101H', 'added'],
    ['s4', 'CHEM120', 'added']]),
  ('partial repair guard 3',
   [{'MATH101': [3, 'L2'],
     'MATH101H': [0, 'G1'],
     'PHYS110': [2, 'L1'],
     'CHEM120': [2, 'H1'],
     'BIO130': [2, 'H1']},
    {'MATH101': [3, 'L2'],
     'MATH101H': [1, 'G1'],
     'PHYS110': [3, 'L1'],
     'CHEM120': [1, 'L1'],
     'BIO130': [2, 'H1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s4', 'MATH101H'], ['s5', 'MATH101'], ['s2', 'CHEM120'], ['s2', 'MATH101'], ['s5', 'CHEM120'],
     ['s2', 'MATH101H'], ['s1', 'HIST140'], ['s5', 'MATH101'], ['s1', 'BIO130'], ['s4', 'BIO130']]],
   [['s2', 'CHEM120', 'moved'], ['s2', 'MATH101H', 'moved'], ['s4', 'MATH101H', 'moved'],
    ['s5', 'CHEM120', 'moved']]),
  ('boundary control 4',
   [{'A': [0, 'H1']}, {}, {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'A']]],
   [['s1', 'A', 'removed']]),
  ('normal control 5',
   [{'MATH101H': [1, 'G1'], 'PHYS110': [0, 'L1'], 'CHEM120': [3, 'G1'], 'BIO130': [0, 'H2']},
    {'MATH101': [3, 'L2'],
     'MATH101H': [1, 'G1'],
     'PHYS110': [3, 'H2'],
     'CHEM120': [3, 'G1'],
     'BIO130': [1, 'H1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'MATH101H'], ['s5', 'HIST140'], ['s4', 'ECON150'], ['s3', 'MATH101'], ['s5', 'MATH101H'],
     ['s2', 'PHYS110'], ['s4', 'MATH101H'], ['s2', 'CHEM120'], ['s2', 'MATH101'], ['s5', 'BIO130'],
     ['s5', 'CHEM120'], ['s2', 'HIST140']]],
   [['s2', 'MATH101', 'added'], ['s2', 'PHYS110', 'moved'], ['s3', 'MATH101', 'added'],
    ['s5', 'BIO130', 'moved']]),
  ('normal control 6',
   [{'MATH101': [0, 'H1'], 'MATH101H': [2, 'L1'], 'CHEM120': [3, 'L2'], 'BIO130': [0, 'G1']},
    {'MATH101': [0, 'H1'],
     'MATH101H': [0, 'L2'],
     'PHYS110': [2, 'L2'],
     'CHEM120': [0, 'H1'],
     'BIO130': [0, 'H1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s4', 'PHYS110'], ['s5', 'HIST140'], ['s4', 'MATH101H'], ['s4', 'ECON150'], ['s5', 'MATH101H'],
     ['s3', 'PHYS110']]],
   [['s3', 'PHYS110', 'added'], ['s4', 'MATH101H', 'moved'], ['s4', 'PHYS110', 'added'],
    ['s5', 'MATH101H', 'moved']]),
  ('normal control 7',
   [{'MATH101': [1, 'L1'], 'MATH101H': [2, 'G1'], 'PHYS110': [2, 'L2'], 'CHEM120': [1, 'G1']},
    {'MATH101': [1, 'L1'], 'MATH101H': [0, 'G1'], 'PHYS110': [0, 'G1'], 'CHEM120': [1, 'G1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'MATH101'], ['s2', 'HIST140'], ['s2', 'BIO130'], ['s1', 'BIO130'], ['s1', 'MATH101H'],
     ['s2', 'BIO130']]],
   [['s1', 'MATH101H', 'moved']]),
  ('normal control 8',
   [{'MATH101': [1, 'L1'],
     'MATH101H': [2, 'H1'],
     'PHYS110': [3, 'H1'],
     'CHEM120': [2, 'G1'],
     'BIO130': [1, 'G1']},
    {'MATH101': [1, 'L1'],
     'MATH101H': [2, 'H1'],
     'PHYS110': [3, 'H1'],
     'CHEM120': [2, 'G1'],
     'BIO130': [0, 'L1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'BIO130'], ['s3', 'CHEM120'], ['s5', 'HIST140'], ['s2', 'PHYS110'], ['s2', 'BIO130'],
     ['s1', 'MATH101H'], ['s1', 'ECON150'], ['s5', 'ECON150'], ['s1', 'MATH101'], ['s1', 'BIO130'],
     ['s3', 'HIST140'], ['s2', 'MATH101H']]],
   [['s1', 'BIO130', 'moved'], ['s2', 'BIO130', 'moved'], ['s3', 'BIO130', 'moved']])],
 [('regression: notification dedupe 1',
   [{'MATH101': [1, 'L1'],
     'MATH101H': [0, 'H1'],
     'PHYS110': [2, 'G1'],
     'CHEM120': [0, 'G1'],
     'BIO130': [3, 'H2']},
    {'MATH101': [1, 'L1'],
     'MATH101H': [2, 'H1'],
     'PHYS110': [3, 'H2'],
     'CHEM120': [0, 'L2'],
     'BIO130': [3, 'H2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s2', 'MATH101'], ['s5', 'CHEM120'], ['s5', 'HIST140'], ['s1', 'MATH101'], ['s1', 'ECON150'],
     ['s2', 'ECON150'], ['s1', 'CHEM120'], ['s5', 'MATH101'], ['s1', 'CHEM120'], ['s5', 'BIO130'],
     ['s2', 'PHYS110'], ['s2', 'CHEM120']]],
   [['s1', 'CHEM120', 'venue'], ['s2', 'CHEM120', 'venue'], ['s2', 'PHYS110', 'moved'],
    ['s5', 'CHEM120', 'venue']]),
  ('regression variant: notification dedupe 2',
   [{'MATH101': [2, 'G1'], 'MATH101H': [3, 'H1'], 'PHYS110': [0, 'H1'], 'CHEM120': [1, 'H2']},
    {'MATH101': [2, 'G1'],
     'MATH101H': [3, 'H1'],
     'PHYS110': [2, 'H1'],
     'CHEM120': [0, 'L1'],
     'BIO130': [2, 'H1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'MATH101'], ['s5', 'BIO130'], ['s5', 'CHEM120'], ['s1', 'ECON150'], ['s5', 'ECON150'],
     ['s5', 'CHEM120'], ['s1', 'CHEM120'], ['s3', 'BIO130'], ['s4', 'BIO130'], ['s1', 'BIO130'],
     ['s5', 'MATH101H']]],
   [['s1', 'BIO130', 'added'], ['s1', 'CHEM120', 'moved'], ['s3', 'BIO130', 'added'],
    ['s4', 'BIO130', 'added'], ['s5', 'BIO130', 'added'], ['s5', 'CHEM120', 'moved']]),
  ('partial repair guard 3',
   [{'MATH101': [2, 'L2'], 'MATH101H': [2, 'L1'], 'CHEM120': [3, 'H2'], 'BIO130': [0, 'L2']},
    {'MATH101H': [2, 'G1'], 'PHYS110': [3, 'H1'], 'CHEM120': [3, 'H2'], 'BIO130': [0, 'L2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s3', 'MATH101'], ['s2', 'MATH101'], ['s3', 'BIO130'], ['s2', 'PHYS110'], ['s3', 'PHYS110'],
     ['s2', 'CHEM120'], ['s3', 'HIST140'], ['s5', 'ECON150'], ['s5', 'PHYS110']]],
   [['s2', 'MATH101', 'removed'], ['s2', 'PHYS110', 'added'], ['s3', 'MATH101', 'removed'],
    ['s3', 'PHYS110', 'added'], ['s5', 'PHYS110', 'added']]),
  ('boundary control 4',
   [{'A': [0, 'H1']}, {'A': [0, 'H2']}, {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'A']]],
   []),
  ('normal control 5',
   [{'MATH101': [3, 'L2'],
     'MATH101H': [0, 'L2'],
     'PHYS110': [3, 'L1'],
     'CHEM120': [1, 'L1'],
     'BIO130': [1, 'H2']},
    {'MATH101': [1, 'H1'],
     'MATH101H': [3, 'H1'],
     'PHYS110': [3, 'L1'],
     'CHEM120': [1, 'L1'],
     'BIO130': [1, 'H2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'ECON150'], ['s1', 'ECON150']]],
   []),
  ('normal control 6',
   [{'MATH101': [3, 'G1'], 'PHYS110': [1, 'L1'], 'CHEM120': [2, 'H1'], 'BIO130': [1, 'H2']},
    {'MATH101': [3, 'G1'],
     'MATH101H': [2, 'L1'],
     'PHYS110': [1, 'H2'],
     'CHEM120': [2, 'H1'],
     'BIO130': [1, 'H2']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s2', 'MATH101H'], ['s5', 'ECON150'], ['s3', 'MATH101'], ['s1', 'BIO130'], ['s1', 'CHEM120'],
     ['s4', 'ECON150'], ['s5', 'MATH101H'], ['s1', 'ECON150'], ['s1', 'MATH101'], ['s3', 'ECON150'],
     ['s4', 'HIST140'], ['s4', 'BIO130'], ['s2', 'MATH101'], ['s2', 'CHEM120'], ['s3', 'CHEM120']]],
   [['s2', 'MATH101H', 'added'], ['s5', 'MATH101H', 'added']]),
  ('normal control 7',
   [{'MATH101': [0, 'H1'],
     'MATH101H': [3, 'G1'],
     'PHYS110': [1, 'L1'],
     'CHEM120': [0, 'L2'],
     'BIO130': [3, 'G1']},
    {'MATH101': [0, 'H1'],
     'MATH101H': [0, 'L1'],
     'PHYS110': [1, 'L1'],
     'CHEM120': [0, 'L2'],
     'BIO130': [3, 'G1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s1', 'MATH101'], ['s2', 'ECON150'], ['s2', 'CHEM120'], ['s3', 'CHEM120'], ['s1', 'MATH101H'],
     ['s4', 'CHEM120'], ['s3', 'ECON150'], ['s2', 'MATH101'], ['s1', 'HIST140'], ['s3', 'HIST140'],
     ['s2', 'MATH101H'], ['s5', 'HIST140']]],
   [['s1', 'MATH101H', 'moved'], ['s2', 'MATH101H', 'moved']]),
  ('normal control 8',
   [{'MATH101': [3, 'H1'],
     'MATH101H': [3, 'H1'],
     'PHYS110': [2, 'G1'],
     'CHEM120': [0, 'H1'],
     'BIO130': [0, 'H1']},
    {'MATH101H': [3, 'H1'], 'PHYS110': [2, 'H1'], 'BIO130': [0, 'H1']},
    {'H1': 'hall', 'H2': 'hall', 'G1': 'hall', 'L1': 'lib', 'L2': 'lib'},
    [['s2', 'MATH101H'], ['s4', 'CHEM120'], ['s4', 'HIST140'], ['s1', 'ECON150'], ['s5', 'ECON150'],
     ['s4', 'ECON150'], ['s2', 'MATH101'], ['s5', 'MATH101'], ['s1', 'BIO130'], ['s5', 'MATH101H'],
     ['s4', 'MATH101'], ['s2', 'HIST140'], ['s5', 'PHYS110']]],
   [['s2', 'MATH101', 'removed'], ['s4', 'CHEM120', 'removed'], ['s4', 'MATH101', 'removed'],
    ['s5', 'MATH101', 'removed']])]]
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: notification dedupe 1[['s1', 'CHEM120', 'added'], ['s2', 'CHEM120', 'added'], ['s2', 'MATH101', 'added'], ['s2', 'MATH101H', 'moved'], ['s4', 'MATH101', 'added'], ['s4', 'MATH101H', 'moved'], ['s5', 'CHEM120', 'added']][['s1', 'CHEM120', 'added'], ['s2', 'CHEM120', 'added'], ['s2', 'MATH101', 'added'], ['s2', 'MATH101H', 'moved'], ['s4', 'MATH101', 'added'], ['s4', 'MATH101H', 'moved'], ['s5', 'CHEM120', 'added']]Passed
regression variant: notification dedupe 2[['s1', 'BIO130', 'added'], ['s2', 'BIO130', 'added'], ['s2', 'CHEM120', 'removed'], ['s4', 'CHEM120', 'removed']][['s1', 'BIO130', 'added'], ['s2', 'BIO130', 'added'], ['s2', 'CHEM120', 'removed'], ['s4', 'CHEM120', 'removed']]Passed
partial repair guard 3[['s4', 'PHYS110', 'removed'], ['s5', 'MATH101H', 'removed']][['s4', 'PHYS110', 'removed'], ['s5', 'MATH101H', 'removed']]Passed
boundary control 4[][]Passed
normal control 5[['s1', 'BIO130', 'moved'], ['s1', 'CHEM120', 'added'], ['s2', 'MATH101', 'added'], ['s3', 'BIO130', 'moved'], ['s3', 'CHEM120', 'added'], ['s3', 'MATH101H', 'added'], ['s4', 'CHEM120', 'added']][['s1', 'BIO130', 'moved'], ['s1', 'CHEM120', 'added'], ['s2', 'MATH101', 'added'], ['s3', 'BIO130', 'moved'], ['s3', 'CHEM120', 'added'], ['s3', 'MATH101H', 'added'], ['s4', 'CHEM120', 'added']]Passed
normal control 6[['s1', 'CHEM120', 'added']][['s1', 'CHEM120', 'added']]Passed
normal control 7[['s4', 'BIO130', 'venue'], ['s5', 'BIO130', 'venue']][['s4', 'BIO130', 'venue'], ['s5', 'BIO130', 'venue']]Passed
normal control 8[['s1', 'BIO130', 'moved'], ['s1', 'MATH101H', 'moved']][['s1', 'BIO130', 'moved'], ['s1', 'MATH101H', 'moved']]Passed

SHA-256 / 3eb5a3bd611b4f24ce058ee3b0a2638b5e83c1dba6bf4cc14f6207dfe8091a41

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.213349+00:00.

Case digest / 5e2cb2b987280d6feadea75993d6cff9209a3fa6ee6a873692968b0e0125f203