FAILURE MAP
← Case archive

FA-94756 / Exam timetabling constraints / Open access

Fair share computed against full-time headcount · case 01

Targets sum to less than the duties when staff are part-time.

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

ROOT CAUSE

The denominator assumes everyone is full-time.

VERIFIED REPAIR

Divide by the sum of actual FTE.

Unsuccessful approach: Dividing by the largest FTE overstates every target.

Case contract

staff [name, FTE percent, duties assigned] and total duties. Each target is total * FTE / sum of FTE rounded half up. Deviation = assigned - target; flag staff whose absolute deviation exceeds one. Return [[name, target, deviation], flagged names].

Why this case matters

Invigilation duties are distributed pro rata to contracted hours; fairness reports drive reallocation.

1 / The failure

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

N = 1
observations = []
def solve(staff, total):
    tot_fte = 100 * len(staff)
    rows = []
    flag = []
    for n, f, a in staff:
        num = total * f * 2 + tot_fte
        target = num // (2 * tot_fte) if tot_fte else 0
        dev = a - target
        rows.append([n, target, dev])
        if abs(dev) > 1:
            flag.append(n)
    return [rows, flag]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: fte denominator 1', [[['a', 50, 5], ['b', 50, 5]], 5],
   [[['a', 3, 2], ['b', 3, 2]], ['a', 'b']]),
  ('regression variant: fte denominator 2', [[['st0', 80, 1], ['st1', 80, 1], ['st2', 50, 10]], 10],
   [[['st0', 4, -3], ['st1', 4, -3], ['st2', 2, 8]], ['st0', 'st1', 'st2']]),
  ('partial repair guard 3',
   [[['st0', 50, 10], ['st1', 100, 4], ['st2', 100, 0], ['st3', 20, 0], ['st4', 80, 3]], 7],
   [[['st0', 1, 9], ['st1', 2, 2], ['st2', 2, -2], ['st3', 0, 0], ['st4', 2, 1]], ['st0', 'st1', 'st2']]),
  ('boundary control 4', [[['a', 25, 1], ['b', 75, 4]], 10], [[['a', 3, -2], ['b', 8, -4]], ['a', 'b']]),
  ('normal control 5', [[['st0', 50, 12], ['st1', 60, 1], ['st2', 60, 8], ['st3', 80, 3]], 30],
   [[['st0', 6, 6], ['st1', 7, -6], ['st2', 7, 1], ['st3', 10, -7]], ['st0', 'st1', 'st3']]),
  ('normal control 6',
   [[['st0', 50, 2], ['st1', 20, 8], ['st2', 50, 6], ['st3', 100, 8], ['st4', 20, 4]], 10],
   [[['st0', 2, 0], ['st1', 1, 7], ['st2', 2, 4], ['st3', 4, 4], ['st4', 1, 3]],
    ['st1', 'st2', 'st3', 'st4']]),
  ('normal control 7', [[['st0', 80, 4], ['st1', 100, 3]], 20],
   [[['st0', 9, -5], ['st1', 11, -8]], ['st0', 'st1']]),
  ('normal control 8',
   [[['st0', 60, 5], ['st1', 20, 10], ['st2', 100, 8], ['st3', 20, 0], ['st4', 20, 8]], 20],
   [[['st0', 5, 0], ['st1', 2, 8], ['st2', 9, -1], ['st3', 2, -2], ['st4', 2, 6]], ['st1', 'st3', 'st4']])],
 [('regression: fte denominator 1', [[['a', 50, 3], ['b', 50, 2]], 7], [[['a', 4, -1], ['b', 4, -2]], ['b']]),
  ('regression variant: fte denominator 2',
   [[['st0', 100, 6], ['st1', 80, 10], ['st2', 50, 5], ['st3', 100, 4], ['st4', 50, 3]], 15],
   [[['st0', 4, 2], ['st1', 3, 7], ['st2', 2, 3], ['st3', 4, 0], ['st4', 2, 1]], ['st0', 'st1', 'st2']]),
  ('partial repair guard 3', [[['st0', 80, 1], ['st1', 80, 1], ['st2', 50, 10]], 10],
   [[['st0', 4, -3], ['st1', 4, -3], ['st2', 2, 8]], ['st0', 'st1', 'st2']]),
  ('normal control 4', [[['st0', 60, 0], ['st1', 50, 12], ['st2', 20, 8], ['st3', 20, 1]], 20],
   [[['st0', 8, -8], ['st1', 7, 5], ['st2', 3, 5], ['st3', 3, -2]], ['st0', 'st1', 'st2', 'st3']]),
  ('normal control 5', [[['st0', 50, 1], ['st1', 20, 6], ['st2', 50, 5]], 25],
   [[['st0', 10, -9], ['st1', 4, 2], ['st2', 10, -5]], ['st0', 'st1', 'st2']]),
  ('normal control 6', [[['st0', 60, 7], ['st1', 60, 11], ['st2', 50, 2]], 25],
   [[['st0', 9, -2], ['st1', 9, 2], ['st2', 7, -5]], ['st0', 'st1', 'st2']]),
  ('normal control 7', [[['st0', 50, 3], ['st1', 60, 0], ['st2', 80, 0]], 7],
   [[['st0', 2, 1], ['st1', 2, -2], ['st2', 3, -3]], ['st1', 'st2']]),
  ('normal control 8', [[['st0', 100, 7], ['st1', 60, 12], ['st2', 50, 6]], 20],
   [[['st0', 10, -3], ['st1', 6, 6], ['st2', 5, 1]], ['st0', 'st1']])],
 [('regression: fte denominator 1', [[['a', 25, 1], ['b', 75, 4]], 10],
   [[['a', 3, -2], ['b', 8, -4]], ['a', 'b']]),
  ('regression variant: fte denominator 2', [[['st0', 20, 8], ['st1', 50, 8]], 15],
   [[['st0', 4, 4], ['st1', 11, -3]], ['st0', 'st1']]),
  ('partial repair guard 3',
   [[['st0', 100, 8], ['st1', 20, 4], ['st2', 100, 3], ['st3', 80, 10], ['st4', 100, 9]], 30],
   [[['st0', 8, 0], ['st1', 2, 2], ['st2', 8, -5], ['st3', 6, 4], ['st4', 8, 1]], ['st1', 'st2', 'st3']]),
  ('boundary control 4', [[['a', 100, 2], ['b', 50, 5]], 9], [[['a', 6, -4], ['b', 3, 2]], ['a', 'b']]),
  ('normal control 5', [[['st0', 80, 11], ['st1', 100, 9], ['st2', 80, 3], ['st3', 50, 7]], 15],
   [[['st0', 4, 7], ['st1', 5, 4], ['st2', 4, -1], ['st3', 2, 5]], ['st0', 'st1', 'st3']]),
  ('normal control 6', [[['st0', 50, 4], ['st1', 100, 4]], 25],
   [[['st0', 8, -4], ['st1', 17, -13]], ['st0', 'st1']]),
  ('normal control 7', [[['st0', 100, 11], ['st1', 60, 3], ['st2', 20, 6], ['st3', 20, 12]], 10],
   [[['st0', 5, 6], ['st1', 3, 0], ['st2', 1, 5], ['st3', 1, 11]], ['st0', 'st2', 'st3']]),
  ('normal control 8',
   [[['st0', 80, 7], ['st1', 80, 10], ['st2', 60, 3], ['st3', 80, 11], ['st4', 80, 12]], 10],
   [[['st0', 2, 5], ['st1', 2, 8], ['st2', 2, 1], ['st3', 2, 9], ['st4', 2, 10]],
    ['st0', 'st1', 'st3', 'st4']])],
 [('regression: fte denominator 1', [[['a', 100, 2], ['b', 50, 5]], 9],
   [[['a', 6, -4], ['b', 3, 2]], ['a', 'b']]),
  ('regression variant: fte denominator 2', [[['st0', 80, 3], ['st1', 50, 9], ['st2', 20, 11]], 10],
   [[['st0', 5, -2], ['st1', 3, 6], ['st2', 1, 10]], ['st0', 'st1', 'st2']]),
  ('partial repair guard 3',
   [[['st0', 50, 2], ['st1', 20, 8], ['st2', 50, 6], ['st3', 100, 8], ['st4', 20, 4]], 10],
   [[['st0', 2, 0], ['st1', 1, 7], ['st2', 2, 4], ['st3', 4, 4], ['st4', 1, 3]],
    ['st1', 'st2', 'st3', 'st4']]),
  ('boundary control 4', [[['a', 100, 3], ['b', 100, 4]], 7], [[['a', 4, -1], ['b', 4, 0]], []]),
  ('normal control 5', [[['st0', 80, 7], ['st1', 80, 6], ['st2', 20, 6], ['st3', 50, 2]], 30],
   [[['st0', 10, -3], ['st1', 10, -4], ['st2', 3, 3], ['st3', 7, -5]], ['st0', 'st1', 'st2', 'st3']]),
  ('normal control 6', [[['st0', 100, 3], ['st1', 20, 5]], 7],
   [[['st0', 6, -3], ['st1', 1, 4]], ['st0', 'st1']]),
  ('normal control 7', [[['st0', 100, 3], ['st1', 60, 9], ['st2', 50, 4]], 10],
   [[['st0', 5, -2], ['st1', 3, 6], ['st2', 2, 2]], ['st0', 'st1', 'st2']]),
  ('normal control 8',
   [[['st0', 20, 9], ['st1', 60, 11], ['st2', 20, 7], ['st3', 60, 11], ['st4', 60, 5]], 15],
   [[['st0', 1, 8], ['st1', 4, 7], ['st2', 1, 6], ['st3', 4, 7], ['st4', 4, 1]],
    ['st0', 'st1', 'st2', 'st3']])],
 [('regression: fte denominator 1',
   [[['st0', 50, 4], ['st1', 100, 7], ['st2', 20, 4], ['st3', 60, 7], ['st4', 50, 0]], 25],
   [[['st0', 4, 0], ['st1', 9, -2], ['st2', 2, 2], ['st3', 5, 2], ['st4', 4, -4]],
    ['st1', 'st2', 'st3', 'st4']]),
  ('regression variant: fte denominator 2',
   [[['st0', 60, 0], ['st1', 20, 2], ['st2', 80, 9], ['st3', 80, 7], ['st4', 20, 10]], 10],
   [[['st0', 2, -2], ['st1', 1, 1], ['st2', 3, 6], ['st3', 3, 4], ['st4', 1, 9]],
    ['st0', 'st2', 'st3', 'st4']]),
  ('partial repair guard 3',
   [[['st0', 100, 2], ['st1', 80, 2], ['st2', 100, 5], ['st3', 100, 12], ['st4', 20, 8]], 25],
   [[['st0', 6, -4], ['st1', 5, -3], ['st2', 6, -1], ['st3', 6, 6], ['st4', 1, 7]],
    ['st0', 'st1', 'st3', 'st4']]),
  ('boundary control 4', [[['a', 50, 5], ['b', 50, 5]], 5], [[['a', 3, 2], ['b', 3, 2]], ['a', 'b']]),
  ('normal control 5', [[['st0', 80, 8], ['st1', 20, 3]], 10], [[['st0', 8, 0], ['st1', 2, 1]], []]),
  ('normal control 6', [[['st0', 100, 3], ['st1', 80, 3]], 30],
   [[['st0', 17, -14], ['st1', 13, -10]], ['st0', 'st1']]),
  ('normal control 7', [[['st0', 100, 1], ['st1', 80, 12], ['st2', 20, 9], ['st3', 80, 7]], 25],
   [[['st0', 9, -8], ['st1', 7, 5], ['st2', 2, 7], ['st3', 7, 0]], ['st0', 'st1', 'st2']]),
  ('normal control 8', [[['st0', 100, 0], ['st1', 60, 3], ['st2', 60, 0]], 15],
   [[['st0', 7, -7], ['st1', 4, -1], ['st2', 4, -4]], ['st0', 'st2']])]]
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: fte denominator 1[[['a', 1, 4], ['b', 1, 4]], ['a', 'b']][[['a', 3, 2], ['b', 3, 2]], ['a', 'b']]Failed
regression variant: fte denominator 2[[['st0', 3, -2], ['st1', 3, -2], ['st2', 2, 8]], ['st0', 'st1', 'st2']][[['st0', 4, -3], ['st1', 4, -3], ['st2', 2, 8]], ['st0', 'st1', 'st2']]Failed
partial repair guard 3[[['st0', 1, 9], ['st1', 1, 3], ['st2', 1, -1], ['st3', 0, 0], ['st4', 1, 2]], ['st0', 'st1', 'st4']][[['st0', 1, 9], ['st1', 2, 2], ['st2', 2, -2], ['st3', 0, 0], ['st4', 2, 1]], ['st0', 'st1', 'st2']]Failed
boundary control 4[[['a', 1, 0], ['b', 4, 0]], []][[['a', 3, -2], ['b', 8, -4]], ['a', 'b']]Failed
normal control 5[[['st0', 4, 8], ['st1', 5, -4], ['st2', 5, 3], ['st3', 6, -3]], ['st0', 'st1', 'st2', 'st3']][[['st0', 6, 6], ['st1', 7, -6], ['st2', 7, 1], ['st3', 10, -7]], ['st0', 'st1', 'st3']]Failed
normal control 6[[['st0', 1, 1], ['st1', 0, 8], ['st2', 1, 5], ['st3', 2, 6], ['st4', 0, 4]], ['st1', 'st2', 'st3', 'st4']][[['st0', 2, 0], ['st1', 1, 7], ['st2', 2, 4], ['st3', 4, 4], ['st4', 1, 3]], ['st1', 'st2', 'st3', 'st4']]Failed
normal control 7[[['st0', 8, -4], ['st1', 10, -7]], ['st0', 'st1']][[['st0', 9, -5], ['st1', 11, -8]], ['st0', 'st1']]Failed
normal control 8[[['st0', 2, 3], ['st1', 1, 9], ['st2', 4, 4], ['st3', 1, -1], ['st4', 1, 7]], ['st0', 'st1', 'st2', 'st4']][[['st0', 5, 0], ['st1', 2, 8], ['st2', 9, -1], ['st3', 2, -2], ['st4', 2, 6]], ['st1', 'st3', 'st4']]Failed

SHA-256 / e28992320b12f126d90ce486ea5fe65a4373270590f986940405f7f157c9ae34

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(staff, total):
    tot_fte = max(f for n, f, a in staff)
    rows = []
    flag = []
    for n, f, a in staff:
        num = total * f * 2 + tot_fte
        target = num // (2 * tot_fte) if tot_fte else 0
        dev = a - target
        rows.append([n, target, dev])
        if abs(dev) > 1:
            flag.append(n)
    return [rows, flag]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: fte denominator 1', [[['a', 50, 5], ['b', 50, 5]], 5],
   [[['a', 3, 2], ['b', 3, 2]], ['a', 'b']]),
  ('regression variant: fte denominator 2', [[['st0', 80, 1], ['st1', 80, 1], ['st2', 50, 10]], 10],
   [[['st0', 4, -3], ['st1', 4, -3], ['st2', 2, 8]], ['st0', 'st1', 'st2']]),
  ('partial repair guard 3',
   [[['st0', 50, 10], ['st1', 100, 4], ['st2', 100, 0], ['st3', 20, 0], ['st4', 80, 3]], 7],
   [[['st0', 1, 9], ['st1', 2, 2], ['st2', 2, -2], ['st3', 0, 0], ['st4', 2, 1]], ['st0', 'st1', 'st2']]),
  ('boundary control 4', [[['a', 25, 1], ['b', 75, 4]], 10], [[['a', 3, -2], ['b', 8, -4]], ['a', 'b']]),
  ('normal control 5', [[['st0', 50, 12], ['st1', 60, 1], ['st2', 60, 8], ['st3', 80, 3]], 30],
   [[['st0', 6, 6], ['st1', 7, -6], ['st2', 7, 1], ['st3', 10, -7]], ['st0', 'st1', 'st3']]),
  ('normal control 6',
   [[['st0', 50, 2], ['st1', 20, 8], ['st2', 50, 6], ['st3', 100, 8], ['st4', 20, 4]], 10],
   [[['st0', 2, 0], ['st1', 1, 7], ['st2', 2, 4], ['st3', 4, 4], ['st4', 1, 3]],
    ['st1', 'st2', 'st3', 'st4']]),
  ('normal control 7', [[['st0', 80, 4], ['st1', 100, 3]], 20],
   [[['st0', 9, -5], ['st1', 11, -8]], ['st0', 'st1']]),
  ('normal control 8',
   [[['st0', 60, 5], ['st1', 20, 10], ['st2', 100, 8], ['st3', 20, 0], ['st4', 20, 8]], 20],
   [[['st0', 5, 0], ['st1', 2, 8], ['st2', 9, -1], ['st3', 2, -2], ['st4', 2, 6]], ['st1', 'st3', 'st4']])],
 [('regression: fte denominator 1', [[['a', 50, 3], ['b', 50, 2]], 7], [[['a', 4, -1], ['b', 4, -2]], ['b']]),
  ('regression variant: fte denominator 2',
   [[['st0', 100, 6], ['st1', 80, 10], ['st2', 50, 5], ['st3', 100, 4], ['st4', 50, 3]], 15],
   [[['st0', 4, 2], ['st1', 3, 7], ['st2', 2, 3], ['st3', 4, 0], ['st4', 2, 1]], ['st0', 'st1', 'st2']]),
  ('partial repair guard 3', [[['st0', 80, 1], ['st1', 80, 1], ['st2', 50, 10]], 10],
   [[['st0', 4, -3], ['st1', 4, -3], ['st2', 2, 8]], ['st0', 'st1', 'st2']]),
  ('normal control 4', [[['st0', 60, 0], ['st1', 50, 12], ['st2', 20, 8], ['st3', 20, 1]], 20],
   [[['st0', 8, -8], ['st1', 7, 5], ['st2', 3, 5], ['st3', 3, -2]], ['st0', 'st1', 'st2', 'st3']]),
  ('normal control 5', [[['st0', 50, 1], ['st1', 20, 6], ['st2', 50, 5]], 25],
   [[['st0', 10, -9], ['st1', 4, 2], ['st2', 10, -5]], ['st0', 'st1', 'st2']]),
  ('normal control 6', [[['st0', 60, 7], ['st1', 60, 11], ['st2', 50, 2]], 25],
   [[['st0', 9, -2], ['st1', 9, 2], ['st2', 7, -5]], ['st0', 'st1', 'st2']]),
  ('normal control 7', [[['st0', 50, 3], ['st1', 60, 0], ['st2', 80, 0]], 7],
   [[['st0', 2, 1], ['st1', 2, -2], ['st2', 3, -3]], ['st1', 'st2']]),
  ('normal control 8', [[['st0', 100, 7], ['st1', 60, 12], ['st2', 50, 6]], 20],
   [[['st0', 10, -3], ['st1', 6, 6], ['st2', 5, 1]], ['st0', 'st1']])],
 [('regression: fte denominator 1', [[['a', 25, 1], ['b', 75, 4]], 10],
   [[['a', 3, -2], ['b', 8, -4]], ['a', 'b']]),
  ('regression variant: fte denominator 2', [[['st0', 20, 8], ['st1', 50, 8]], 15],
   [[['st0', 4, 4], ['st1', 11, -3]], ['st0', 'st1']]),
  ('partial repair guard 3',
   [[['st0', 100, 8], ['st1', 20, 4], ['st2', 100, 3], ['st3', 80, 10], ['st4', 100, 9]], 30],
   [[['st0', 8, 0], ['st1', 2, 2], ['st2', 8, -5], ['st3', 6, 4], ['st4', 8, 1]], ['st1', 'st2', 'st3']]),
  ('boundary control 4', [[['a', 100, 2], ['b', 50, 5]], 9], [[['a', 6, -4], ['b', 3, 2]], ['a', 'b']]),
  ('normal control 5', [[['st0', 80, 11], ['st1', 100, 9], ['st2', 80, 3], ['st3', 50, 7]], 15],
   [[['st0', 4, 7], ['st1', 5, 4], ['st2', 4, -1], ['st3', 2, 5]], ['st0', 'st1', 'st3']]),
  ('normal control 6', [[['st0', 50, 4], ['st1', 100, 4]], 25],
   [[['st0', 8, -4], ['st1', 17, -13]], ['st0', 'st1']]),
  ('normal control 7', [[['st0', 100, 11], ['st1', 60, 3], ['st2', 20, 6], ['st3', 20, 12]], 10],
   [[['st0', 5, 6], ['st1', 3, 0], ['st2', 1, 5], ['st3', 1, 11]], ['st0', 'st2', 'st3']]),
  ('normal control 8',
   [[['st0', 80, 7], ['st1', 80, 10], ['st2', 60, 3], ['st3', 80, 11], ['st4', 80, 12]], 10],
   [[['st0', 2, 5], ['st1', 2, 8], ['st2', 2, 1], ['st3', 2, 9], ['st4', 2, 10]],
    ['st0', 'st1', 'st3', 'st4']])],
 [('regression: fte denominator 1', [[['a', 100, 2], ['b', 50, 5]], 9],
   [[['a', 6, -4], ['b', 3, 2]], ['a', 'b']]),
  ('regression variant: fte denominator 2', [[['st0', 80, 3], ['st1', 50, 9], ['st2', 20, 11]], 10],
   [[['st0', 5, -2], ['st1', 3, 6], ['st2', 1, 10]], ['st0', 'st1', 'st2']]),
  ('partial repair guard 3',
   [[['st0', 50, 2], ['st1', 20, 8], ['st2', 50, 6], ['st3', 100, 8], ['st4', 20, 4]], 10],
   [[['st0', 2, 0], ['st1', 1, 7], ['st2', 2, 4], ['st3', 4, 4], ['st4', 1, 3]],
    ['st1', 'st2', 'st3', 'st4']]),
  ('boundary control 4', [[['a', 100, 3], ['b', 100, 4]], 7], [[['a', 4, -1], ['b', 4, 0]], []]),
  ('normal control 5', [[['st0', 80, 7], ['st1', 80, 6], ['st2', 20, 6], ['st3', 50, 2]], 30],
   [[['st0', 10, -3], ['st1', 10, -4], ['st2', 3, 3], ['st3', 7, -5]], ['st0', 'st1', 'st2', 'st3']]),
  ('normal control 6', [[['st0', 100, 3], ['st1', 20, 5]], 7],
   [[['st0', 6, -3], ['st1', 1, 4]], ['st0', 'st1']]),
  ('normal control 7', [[['st0', 100, 3], ['st1', 60, 9], ['st2', 50, 4]], 10],
   [[['st0', 5, -2], ['st1', 3, 6], ['st2', 2, 2]], ['st0', 'st1', 'st2']]),
  ('normal control 8',
   [[['st0', 20, 9], ['st1', 60, 11], ['st2', 20, 7], ['st3', 60, 11], ['st4', 60, 5]], 15],
   [[['st0', 1, 8], ['st1', 4, 7], ['st2', 1, 6], ['st3', 4, 7], ['st4', 4, 1]],
    ['st0', 'st1', 'st2', 'st3']])],
 [('regression: fte denominator 1',
   [[['st0', 50, 4], ['st1', 100, 7], ['st2', 20, 4], ['st3', 60, 7], ['st4', 50, 0]], 25],
   [[['st0', 4, 0], ['st1', 9, -2], ['st2', 2, 2], ['st3', 5, 2], ['st4', 4, -4]],
    ['st1', 'st2', 'st3', 'st4']]),
  ('regression variant: fte denominator 2',
   [[['st0', 60, 0], ['st1', 20, 2], ['st2', 80, 9], ['st3', 80, 7], ['st4', 20, 10]], 10],
   [[['st0', 2, -2], ['st1', 1, 1], ['st2', 3, 6], ['st3', 3, 4], ['st4', 1, 9]],
    ['st0', 'st2', 'st3', 'st4']]),
  ('partial repair guard 3',
   [[['st0', 100, 2], ['st1', 80, 2], ['st2', 100, 5], ['st3', 100, 12], ['st4', 20, 8]], 25],
   [[['st0', 6, -4], ['st1', 5, -3], ['st2', 6, -1], ['st3', 6, 6], ['st4', 1, 7]],
    ['st0', 'st1', 'st3', 'st4']]),
  ('boundary control 4', [[['a', 50, 5], ['b', 50, 5]], 5], [[['a', 3, 2], ['b', 3, 2]], ['a', 'b']]),
  ('normal control 5', [[['st0', 80, 8], ['st1', 20, 3]], 10], [[['st0', 8, 0], ['st1', 2, 1]], []]),
  ('normal control 6', [[['st0', 100, 3], ['st1', 80, 3]], 30],
   [[['st0', 17, -14], ['st1', 13, -10]], ['st0', 'st1']]),
  ('normal control 7', [[['st0', 100, 1], ['st1', 80, 12], ['st2', 20, 9], ['st3', 80, 7]], 25],
   [[['st0', 9, -8], ['st1', 7, 5], ['st2', 2, 7], ['st3', 7, 0]], ['st0', 'st1', 'st2']]),
  ('normal control 8', [[['st0', 100, 0], ['st1', 60, 3], ['st2', 60, 0]], 15],
   [[['st0', 7, -7], ['st1', 4, -1], ['st2', 4, -4]], ['st0', 'st2']])]]
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: fte denominator 1[[['a', 5, 0], ['b', 5, 0]], []][[['a', 3, 2], ['b', 3, 2]], ['a', 'b']]Failed
regression variant: fte denominator 2[[['st0', 10, -9], ['st1', 10, -9], ['st2', 6, 4]], ['st0', 'st1', 'st2']][[['st0', 4, -3], ['st1', 4, -3], ['st2', 2, 8]], ['st0', 'st1', 'st2']]Failed
partial repair guard 3[[['st0', 4, 6], ['st1', 7, -3], ['st2', 7, -7], ['st3', 1, -1], ['st4', 6, -3]], ['st0', 'st1', 'st2', 'st4']][[['st0', 1, 9], ['st1', 2, 2], ['st2', 2, -2], ['st3', 0, 0], ['st4', 2, 1]], ['st0', 'st1', 'st2']]Failed
boundary control 4[[['a', 3, -2], ['b', 10, -6]], ['a', 'b']][[['a', 3, -2], ['b', 8, -4]], ['a', 'b']]Failed
normal control 5[[['st0', 19, -7], ['st1', 23, -22], ['st2', 23, -15], ['st3', 30, -27]], ['st0', 'st1', 'st2', 'st3']][[['st0', 6, 6], ['st1', 7, -6], ['st2', 7, 1], ['st3', 10, -7]], ['st0', 'st1', 'st3']]Failed
normal control 6[[['st0', 5, -3], ['st1', 2, 6], ['st2', 5, 1], ['st3', 10, -2], ['st4', 2, 2]], ['st0', 'st1', 'st3', 'st4']][[['st0', 2, 0], ['st1', 1, 7], ['st2', 2, 4], ['st3', 4, 4], ['st4', 1, 3]], ['st1', 'st2', 'st3', 'st4']]Failed
normal control 7[[['st0', 16, -12], ['st1', 20, -17]], ['st0', 'st1']][[['st0', 9, -5], ['st1', 11, -8]], ['st0', 'st1']]Failed
normal control 8[[['st0', 12, -7], ['st1', 4, 6], ['st2', 20, -12], ['st3', 4, -4], ['st4', 4, 4]], ['st0', 'st1', 'st2', 'st3', 'st4']][[['st0', 5, 0], ['st1', 2, 8], ['st2', 9, -1], ['st3', 2, -2], ['st4', 2, 6]], ['st1', 'st3', 'st4']]Failed

SHA-256 / b35915b8f80635621900cc61e95892da606b5a70898a0b4312a09f11d09735a8

3 / The verified repair

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

N = 1
observations = []
def solve(staff, total):
    tot_fte = sum(f for n, f, a in staff)
    rows = []
    flag = []
    for n, f, a in staff:
        num = total * f * 2 + tot_fte
        target = num // (2 * tot_fte) if tot_fte else 0
        dev = a - target
        rows.append([n, target, dev])
        if abs(dev) > 1:
            flag.append(n)
    return [rows, flag]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: fte denominator 1', [[['a', 50, 5], ['b', 50, 5]], 5],
   [[['a', 3, 2], ['b', 3, 2]], ['a', 'b']]),
  ('regression variant: fte denominator 2', [[['st0', 80, 1], ['st1', 80, 1], ['st2', 50, 10]], 10],
   [[['st0', 4, -3], ['st1', 4, -3], ['st2', 2, 8]], ['st0', 'st1', 'st2']]),
  ('partial repair guard 3',
   [[['st0', 50, 10], ['st1', 100, 4], ['st2', 100, 0], ['st3', 20, 0], ['st4', 80, 3]], 7],
   [[['st0', 1, 9], ['st1', 2, 2], ['st2', 2, -2], ['st3', 0, 0], ['st4', 2, 1]], ['st0', 'st1', 'st2']]),
  ('boundary control 4', [[['a', 25, 1], ['b', 75, 4]], 10], [[['a', 3, -2], ['b', 8, -4]], ['a', 'b']]),
  ('normal control 5', [[['st0', 50, 12], ['st1', 60, 1], ['st2', 60, 8], ['st3', 80, 3]], 30],
   [[['st0', 6, 6], ['st1', 7, -6], ['st2', 7, 1], ['st3', 10, -7]], ['st0', 'st1', 'st3']]),
  ('normal control 6',
   [[['st0', 50, 2], ['st1', 20, 8], ['st2', 50, 6], ['st3', 100, 8], ['st4', 20, 4]], 10],
   [[['st0', 2, 0], ['st1', 1, 7], ['st2', 2, 4], ['st3', 4, 4], ['st4', 1, 3]],
    ['st1', 'st2', 'st3', 'st4']]),
  ('normal control 7', [[['st0', 80, 4], ['st1', 100, 3]], 20],
   [[['st0', 9, -5], ['st1', 11, -8]], ['st0', 'st1']]),
  ('normal control 8',
   [[['st0', 60, 5], ['st1', 20, 10], ['st2', 100, 8], ['st3', 20, 0], ['st4', 20, 8]], 20],
   [[['st0', 5, 0], ['st1', 2, 8], ['st2', 9, -1], ['st3', 2, -2], ['st4', 2, 6]], ['st1', 'st3', 'st4']])],
 [('regression: fte denominator 1', [[['a', 50, 3], ['b', 50, 2]], 7], [[['a', 4, -1], ['b', 4, -2]], ['b']]),
  ('regression variant: fte denominator 2',
   [[['st0', 100, 6], ['st1', 80, 10], ['st2', 50, 5], ['st3', 100, 4], ['st4', 50, 3]], 15],
   [[['st0', 4, 2], ['st1', 3, 7], ['st2', 2, 3], ['st3', 4, 0], ['st4', 2, 1]], ['st0', 'st1', 'st2']]),
  ('partial repair guard 3', [[['st0', 80, 1], ['st1', 80, 1], ['st2', 50, 10]], 10],
   [[['st0', 4, -3], ['st1', 4, -3], ['st2', 2, 8]], ['st0', 'st1', 'st2']]),
  ('normal control 4', [[['st0', 60, 0], ['st1', 50, 12], ['st2', 20, 8], ['st3', 20, 1]], 20],
   [[['st0', 8, -8], ['st1', 7, 5], ['st2', 3, 5], ['st3', 3, -2]], ['st0', 'st1', 'st2', 'st3']]),
  ('normal control 5', [[['st0', 50, 1], ['st1', 20, 6], ['st2', 50, 5]], 25],
   [[['st0', 10, -9], ['st1', 4, 2], ['st2', 10, -5]], ['st0', 'st1', 'st2']]),
  ('normal control 6', [[['st0', 60, 7], ['st1', 60, 11], ['st2', 50, 2]], 25],
   [[['st0', 9, -2], ['st1', 9, 2], ['st2', 7, -5]], ['st0', 'st1', 'st2']]),
  ('normal control 7', [[['st0', 50, 3], ['st1', 60, 0], ['st2', 80, 0]], 7],
   [[['st0', 2, 1], ['st1', 2, -2], ['st2', 3, -3]], ['st1', 'st2']]),
  ('normal control 8', [[['st0', 100, 7], ['st1', 60, 12], ['st2', 50, 6]], 20],
   [[['st0', 10, -3], ['st1', 6, 6], ['st2', 5, 1]], ['st0', 'st1']])],
 [('regression: fte denominator 1', [[['a', 25, 1], ['b', 75, 4]], 10],
   [[['a', 3, -2], ['b', 8, -4]], ['a', 'b']]),
  ('regression variant: fte denominator 2', [[['st0', 20, 8], ['st1', 50, 8]], 15],
   [[['st0', 4, 4], ['st1', 11, -3]], ['st0', 'st1']]),
  ('partial repair guard 3',
   [[['st0', 100, 8], ['st1', 20, 4], ['st2', 100, 3], ['st3', 80, 10], ['st4', 100, 9]], 30],
   [[['st0', 8, 0], ['st1', 2, 2], ['st2', 8, -5], ['st3', 6, 4], ['st4', 8, 1]], ['st1', 'st2', 'st3']]),
  ('boundary control 4', [[['a', 100, 2], ['b', 50, 5]], 9], [[['a', 6, -4], ['b', 3, 2]], ['a', 'b']]),
  ('normal control 5', [[['st0', 80, 11], ['st1', 100, 9], ['st2', 80, 3], ['st3', 50, 7]], 15],
   [[['st0', 4, 7], ['st1', 5, 4], ['st2', 4, -1], ['st3', 2, 5]], ['st0', 'st1', 'st3']]),
  ('normal control 6', [[['st0', 50, 4], ['st1', 100, 4]], 25],
   [[['st0', 8, -4], ['st1', 17, -13]], ['st0', 'st1']]),
  ('normal control 7', [[['st0', 100, 11], ['st1', 60, 3], ['st2', 20, 6], ['st3', 20, 12]], 10],
   [[['st0', 5, 6], ['st1', 3, 0], ['st2', 1, 5], ['st3', 1, 11]], ['st0', 'st2', 'st3']]),
  ('normal control 8',
   [[['st0', 80, 7], ['st1', 80, 10], ['st2', 60, 3], ['st3', 80, 11], ['st4', 80, 12]], 10],
   [[['st0', 2, 5], ['st1', 2, 8], ['st2', 2, 1], ['st3', 2, 9], ['st4', 2, 10]],
    ['st0', 'st1', 'st3', 'st4']])],
 [('regression: fte denominator 1', [[['a', 100, 2], ['b', 50, 5]], 9],
   [[['a', 6, -4], ['b', 3, 2]], ['a', 'b']]),
  ('regression variant: fte denominator 2', [[['st0', 80, 3], ['st1', 50, 9], ['st2', 20, 11]], 10],
   [[['st0', 5, -2], ['st1', 3, 6], ['st2', 1, 10]], ['st0', 'st1', 'st2']]),
  ('partial repair guard 3',
   [[['st0', 50, 2], ['st1', 20, 8], ['st2', 50, 6], ['st3', 100, 8], ['st4', 20, 4]], 10],
   [[['st0', 2, 0], ['st1', 1, 7], ['st2', 2, 4], ['st3', 4, 4], ['st4', 1, 3]],
    ['st1', 'st2', 'st3', 'st4']]),
  ('boundary control 4', [[['a', 100, 3], ['b', 100, 4]], 7], [[['a', 4, -1], ['b', 4, 0]], []]),
  ('normal control 5', [[['st0', 80, 7], ['st1', 80, 6], ['st2', 20, 6], ['st3', 50, 2]], 30],
   [[['st0', 10, -3], ['st1', 10, -4], ['st2', 3, 3], ['st3', 7, -5]], ['st0', 'st1', 'st2', 'st3']]),
  ('normal control 6', [[['st0', 100, 3], ['st1', 20, 5]], 7],
   [[['st0', 6, -3], ['st1', 1, 4]], ['st0', 'st1']]),
  ('normal control 7', [[['st0', 100, 3], ['st1', 60, 9], ['st2', 50, 4]], 10],
   [[['st0', 5, -2], ['st1', 3, 6], ['st2', 2, 2]], ['st0', 'st1', 'st2']]),
  ('normal control 8',
   [[['st0', 20, 9], ['st1', 60, 11], ['st2', 20, 7], ['st3', 60, 11], ['st4', 60, 5]], 15],
   [[['st0', 1, 8], ['st1', 4, 7], ['st2', 1, 6], ['st3', 4, 7], ['st4', 4, 1]],
    ['st0', 'st1', 'st2', 'st3']])],
 [('regression: fte denominator 1',
   [[['st0', 50, 4], ['st1', 100, 7], ['st2', 20, 4], ['st3', 60, 7], ['st4', 50, 0]], 25],
   [[['st0', 4, 0], ['st1', 9, -2], ['st2', 2, 2], ['st3', 5, 2], ['st4', 4, -4]],
    ['st1', 'st2', 'st3', 'st4']]),
  ('regression variant: fte denominator 2',
   [[['st0', 60, 0], ['st1', 20, 2], ['st2', 80, 9], ['st3', 80, 7], ['st4', 20, 10]], 10],
   [[['st0', 2, -2], ['st1', 1, 1], ['st2', 3, 6], ['st3', 3, 4], ['st4', 1, 9]],
    ['st0', 'st2', 'st3', 'st4']]),
  ('partial repair guard 3',
   [[['st0', 100, 2], ['st1', 80, 2], ['st2', 100, 5], ['st3', 100, 12], ['st4', 20, 8]], 25],
   [[['st0', 6, -4], ['st1', 5, -3], ['st2', 6, -1], ['st3', 6, 6], ['st4', 1, 7]],
    ['st0', 'st1', 'st3', 'st4']]),
  ('boundary control 4', [[['a', 50, 5], ['b', 50, 5]], 5], [[['a', 3, 2], ['b', 3, 2]], ['a', 'b']]),
  ('normal control 5', [[['st0', 80, 8], ['st1', 20, 3]], 10], [[['st0', 8, 0], ['st1', 2, 1]], []]),
  ('normal control 6', [[['st0', 100, 3], ['st1', 80, 3]], 30],
   [[['st0', 17, -14], ['st1', 13, -10]], ['st0', 'st1']]),
  ('normal control 7', [[['st0', 100, 1], ['st1', 80, 12], ['st2', 20, 9], ['st3', 80, 7]], 25],
   [[['st0', 9, -8], ['st1', 7, 5], ['st2', 2, 7], ['st3', 7, 0]], ['st0', 'st1', 'st2']]),
  ('normal control 8', [[['st0', 100, 0], ['st1', 60, 3], ['st2', 60, 0]], 15],
   [[['st0', 7, -7], ['st1', 4, -1], ['st2', 4, -4]], ['st0', 'st2']])]]
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: fte denominator 1[[['a', 3, 2], ['b', 3, 2]], ['a', 'b']][[['a', 3, 2], ['b', 3, 2]], ['a', 'b']]Passed
regression variant: fte denominator 2[[['st0', 4, -3], ['st1', 4, -3], ['st2', 2, 8]], ['st0', 'st1', 'st2']][[['st0', 4, -3], ['st1', 4, -3], ['st2', 2, 8]], ['st0', 'st1', 'st2']]Passed
partial repair guard 3[[['st0', 1, 9], ['st1', 2, 2], ['st2', 2, -2], ['st3', 0, 0], ['st4', 2, 1]], ['st0', 'st1', 'st2']][[['st0', 1, 9], ['st1', 2, 2], ['st2', 2, -2], ['st3', 0, 0], ['st4', 2, 1]], ['st0', 'st1', 'st2']]Passed
boundary control 4[[['a', 3, -2], ['b', 8, -4]], ['a', 'b']][[['a', 3, -2], ['b', 8, -4]], ['a', 'b']]Passed
normal control 5[[['st0', 6, 6], ['st1', 7, -6], ['st2', 7, 1], ['st3', 10, -7]], ['st0', 'st1', 'st3']][[['st0', 6, 6], ['st1', 7, -6], ['st2', 7, 1], ['st3', 10, -7]], ['st0', 'st1', 'st3']]Passed
normal control 6[[['st0', 2, 0], ['st1', 1, 7], ['st2', 2, 4], ['st3', 4, 4], ['st4', 1, 3]], ['st1', 'st2', 'st3', 'st4']][[['st0', 2, 0], ['st1', 1, 7], ['st2', 2, 4], ['st3', 4, 4], ['st4', 1, 3]], ['st1', 'st2', 'st3', 'st4']]Passed
normal control 7[[['st0', 9, -5], ['st1', 11, -8]], ['st0', 'st1']][[['st0', 9, -5], ['st1', 11, -8]], ['st0', 'st1']]Passed
normal control 8[[['st0', 5, 0], ['st1', 2, 8], ['st2', 9, -1], ['st3', 2, -2], ['st4', 2, 6]], ['st1', 'st3', 'st4']][[['st0', 5, 0], ['st1', 2, 8], ['st2', 9, -1], ['st3', 2, -2], ['st4', 2, 6]], ['st1', 'st3', 'st4']]Passed

SHA-256 / 4c784ec7391c725690008a93fd3c5e68c68e705d78cd53bb8e972d4b5e7e360e

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

Case digest / b3cccf9b826cc578e7ffcace7fa590264e3c1bba0ac688eb274101c6582ea490