FA-95111 / Warehouse slotting and bin packing / Open access
Reserve allocation: pallets ordered by quantity · case 01
Allocation favours small pallets regardless of age.
ROOT CAUSE
Pallets are ordered by quantity instead of received day.
VERIFIED REPAIR
Order pallets by received day, then plate.
Unsuccessful approach: Ordering by plate only assumes plates are issued in receipt order.
Case contract
pallets [[license_plate, received_day, qty]]; need units. Order pallets by received_day then plate. Pass 1 takes whole pallets (qty > 0) whose qty fits the remaining need, oldest first, skipping ones that are too large. Pass 2 takes partial quantity from remaining pallets oldest first. Return [[[plate, qty] in pick order], shortfall].
Why this case matters
Reserve allocation decides which pallets feed replenishment and order picks.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(pallets, need):
order = sorted(pallets, key=lambda p: (p[2], p[0]))
rem = need
alloc = []
taken = set()
for lp, day, q in order:
if 0 < q <= rem:
alloc.append([lp, q])
taken.add(lp)
rem -= q
for lp, day, q in order:
if rem == 0:
break
if lp in taken:
continue
t = min(q, rem)
if t > 0:
alloc.append([lp, t])
rem -= t
return [alloc, rem]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['clean-out skip big', [[['A', 1, 50], ['B', 2, 20], ['C', 3, 10]], 30], [[['B', 20], ['C', 10]], 0]], ['generated mix 7', [[['P0', 8, 20], ['P1', 8, 30], ['P2', 3, 10], ['P3', 5, 20]], 60], [[['P2', 10], ['P3', 20], ['P0', 20], ['P1', 10]], 0]], ['exact whole', [[['A', 1, 30]], 30], [[['A', 30]], 0]], ['shortfall', [[['A', 1, 10]], 25], [[['A', 10]], 15]], ['zero need', [[['A', 1, 10]], 0], [[], 0]], ['partial oldest', [[['A', 1, 50], ['B', 2, 60]], 30], [[['A', 30]], 0]], ['equal qty pallets', [[['A', 1, 20], ['B', 2, 20], ['C', 3, 40]], 50], [[['A', 20], ['B', 20], ['C', 10]], 0]], ['generated mix 9', [[['P0', 1, 20], ['P1', 2, 48], ['P2', 2, 20]], 20], [[['P0', 20]], 0]]], [['generated mix 11', [[['P0', 5, 20], ['P1', 3, 40], ['P2', 3, 0], ['P3', 3, 20], ['P4', 3, 0], ['P5', 1, 20]], 20], [[['P5', 20]], 0]], ['generated mix 19', [[['P0', 5, 10], ['P1', 3, 40], ['P2', 1, 30], ['P3', 3, 30]], 60], [[['P2', 30], ['P3', 30]], 0]], ['shortfall', [[['A', 1, 10]], 25], [[['A', 10]], 15]], ['zero need', [[['A', 1, 10]], 0], [[], 0]], ['exact whole', [[['A', 1, 30]], 30], [[['A', 30]], 0]], ['generated mix 9', [[['P0', 1, 20], ['P1', 2, 48], ['P2', 2, 20]], 20], [[['P0', 20]], 0]], ['generated mix 18', [[['P0', 3, 0], ['P1', 3, 40]], 90], [[['P1', 40]], 50]], ['generated mix 27', [[['P0', 8, 20], ['P1', 5, 48], ['P2', 5, 20]], 90], [[['P1', 48], ['P2', 20], ['P0', 20]], 2]]], [['generated mix 30', [[['P0', 1, 20], ['P1', 5, 40], ['P2', 3, 48], ['P3', 2, 10], ['P4', 1, 48], ['P5', 2, 20]], 90], [[['P0', 20], ['P4', 48], ['P3', 10], ['P5', 12]], 0]], ['generated mix 31', [[['P0', 5, 20], ['P1', 3, 20], ['P2', 2, 40], ['P3', 5, 20]], 30], [[['P1', 20], ['P2', 10]], 0]], ['clean-out skip big', [[['A', 1, 50], ['B', 2, 20], ['C', 3, 10]], 30], [[['B', 20], ['C', 10]], 0]], ['partial oldest', [[['A', 1, 50], ['B', 2, 60]], 30], [[['A', 30]], 0]], ['equal qty pallets', [[['A', 1, 20], ['B', 2, 20], ['C', 3, 40]], 50], [[['A', 20], ['B', 20], ['C', 10]], 0]], ['generated mix 20', [[['P0', 2, 0], ['P1', 3, 48], ['P2', 2, 30]], 60], [[['P2', 30], ['P1', 30]], 0]], ['generated mix 28', [[['P0', 3, 40]], 90], [[['P0', 40]], 50]], ['generated mix 38', [[['P0', 3, 40], ['P1', 3, 20], ['P2', 2, 20], ['P3', 5, 10], ['P4', 2, 20]], 60], [[['P2', 20], ['P4', 20], ['P1', 20]], 0]]], [['generated mix 45', [[['P0', 3, 10], ['P1', 8, 0], ['P2', 3, 30], ['P3', 3, 48], ['P4', 1, 48], ['P5', 3, 30]], 90], [[['P4', 48], ['P0', 10], ['P2', 30], ['P3', 2]], 0]], ['generated mix 42', [[['P0', 5, 20], ['P1', 3, 30], ['P2', 2, 0]], 90], [[['P1', 30], ['P0', 20]], 40]], ['shortfall', [[['A', 1, 10]], 25], [[['A', 10]], 15]], ['zero need', [[['A', 1, 10]], 0], [[], 0]], ['exact whole', [[['A', 1, 30]], 30], [[['A', 30]], 0]], ['generated mix 31', [[['P0', 5, 20], ['P1', 3, 20], ['P2', 2, 40], ['P3', 5, 20]], 30], [[['P1', 20], ['P2', 10]], 0]], ['generated mix 39', [[['P0', 5, 30], ['P1', 5, 40], ['P2', 8, 20]], 25], [[['P2', 20], ['P0', 5]], 0]], ['generated mix 49', [[['P0', 3, 20], ['P1', 1, 0], ['P2', 8, 40], ['P3', 5, 20], ['P4', 5, 30], ['P5', 3, 40]], 25], [[['P0', 20], ['P5', 5]], 0]]], [['generated mix 60', [[['P0', 3, 20], ['P1', 5, 20], ['P2', 3, 20], ['P3', 3, 30]], 30], [[['P0', 20], ['P2', 10]], 0]], ['generated mix 53', [[['P0', 5, 48], ['P1', 3, 48], ['P2', 3, 20], ['P3', 3, 48], ['P4', 3, 10], ['P5', 3, 48]], 50], [[['P1', 48], ['P2', 2]], 0]], ['clean-out skip big', [[['A', 1, 50], ['B', 2, 20], ['C', 3, 10]], 30], [[['B', 20], ['C', 10]], 0]], ['partial oldest', [[['A', 1, 50], ['B', 2, 60]], 30], [[['A', 30]], 0]], ['equal qty pallets', [[['A', 1, 20], ['B', 2, 20], ['C', 3, 40]], 50], [[['A', 20], ['B', 20], ['C', 10]], 0]], ['generated mix 42', [[['P0', 5, 20], ['P1', 3, 30], ['P2', 2, 0]], 90], [[['P1', 30], ['P0', 20]], 40]], ['generated mix 50', [[['P0', 8, 20], ['P1', 8, 20], ['P2', 2, 20], ['P3', 3, 0]], 20], [[['P2', 20]], 0]], ['generated mix 59', [[['P0', 3, 20], ['P1', 2, 40], ['P2', 3, 0], ['P3', 3, 20], ['P4', 5, 40]], 10], [[['P1', 10]], 0]]]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| clean-out skip big | [[['C', 10], ['B', 20]], 0] | [[['B', 20], ['C', 10]], 0] | Failed |
| generated mix 7 | [[['P2', 10], ['P0', 20], ['P3', 20], ['P1', 10]], 0] | [[['P2', 10], ['P3', 20], ['P0', 20], ['P1', 10]], 0] | Failed |
| exact whole | [[['A', 30]], 0] | [[['A', 30]], 0] | Passed |
| shortfall | [[['A', 10]], 15] | [[['A', 10]], 15] | Passed |
| zero need | [[], 0] | [[], 0] | Passed |
| partial oldest | [[['A', 30]], 0] | [[['A', 30]], 0] | Passed |
| equal qty pallets | [[['A', 20], ['B', 20], ['C', 10]], 0] | [[['A', 20], ['B', 20], ['C', 10]], 0] | Passed |
| generated mix 9 | [[['P0', 20]], 0] | [[['P0', 20]], 0] | Passed |
SHA-256 / 34e259b0de011fb7ae76888cc15b2dcc9d8de38e63cbd21d019f56af24c19da9
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(pallets, need):
order = sorted(pallets, key=lambda p: p[0])
rem = need
alloc = []
taken = set()
for lp, day, q in order:
if 0 < q <= rem:
alloc.append([lp, q])
taken.add(lp)
rem -= q
for lp, day, q in order:
if rem == 0:
break
if lp in taken:
continue
t = min(q, rem)
if t > 0:
alloc.append([lp, t])
rem -= t
return [alloc, rem]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['clean-out skip big', [[['A', 1, 50], ['B', 2, 20], ['C', 3, 10]], 30], [[['B', 20], ['C', 10]], 0]], ['generated mix 7', [[['P0', 8, 20], ['P1', 8, 30], ['P2', 3, 10], ['P3', 5, 20]], 60], [[['P2', 10], ['P3', 20], ['P0', 20], ['P1', 10]], 0]], ['exact whole', [[['A', 1, 30]], 30], [[['A', 30]], 0]], ['shortfall', [[['A', 1, 10]], 25], [[['A', 10]], 15]], ['zero need', [[['A', 1, 10]], 0], [[], 0]], ['partial oldest', [[['A', 1, 50], ['B', 2, 60]], 30], [[['A', 30]], 0]], ['equal qty pallets', [[['A', 1, 20], ['B', 2, 20], ['C', 3, 40]], 50], [[['A', 20], ['B', 20], ['C', 10]], 0]], ['generated mix 9', [[['P0', 1, 20], ['P1', 2, 48], ['P2', 2, 20]], 20], [[['P0', 20]], 0]]], [['generated mix 11', [[['P0', 5, 20], ['P1', 3, 40], ['P2', 3, 0], ['P3', 3, 20], ['P4', 3, 0], ['P5', 1, 20]], 20], [[['P5', 20]], 0]], ['generated mix 19', [[['P0', 5, 10], ['P1', 3, 40], ['P2', 1, 30], ['P3', 3, 30]], 60], [[['P2', 30], ['P3', 30]], 0]], ['shortfall', [[['A', 1, 10]], 25], [[['A', 10]], 15]], ['zero need', [[['A', 1, 10]], 0], [[], 0]], ['exact whole', [[['A', 1, 30]], 30], [[['A', 30]], 0]], ['generated mix 9', [[['P0', 1, 20], ['P1', 2, 48], ['P2', 2, 20]], 20], [[['P0', 20]], 0]], ['generated mix 18', [[['P0', 3, 0], ['P1', 3, 40]], 90], [[['P1', 40]], 50]], ['generated mix 27', [[['P0', 8, 20], ['P1', 5, 48], ['P2', 5, 20]], 90], [[['P1', 48], ['P2', 20], ['P0', 20]], 2]]], [['generated mix 30', [[['P0', 1, 20], ['P1', 5, 40], ['P2', 3, 48], ['P3', 2, 10], ['P4', 1, 48], ['P5', 2, 20]], 90], [[['P0', 20], ['P4', 48], ['P3', 10], ['P5', 12]], 0]], ['generated mix 31', [[['P0', 5, 20], ['P1', 3, 20], ['P2', 2, 40], ['P3', 5, 20]], 30], [[['P1', 20], ['P2', 10]], 0]], ['clean-out skip big', [[['A', 1, 50], ['B', 2, 20], ['C', 3, 10]], 30], [[['B', 20], ['C', 10]], 0]], ['partial oldest', [[['A', 1, 50], ['B', 2, 60]], 30], [[['A', 30]], 0]], ['equal qty pallets', [[['A', 1, 20], ['B', 2, 20], ['C', 3, 40]], 50], [[['A', 20], ['B', 20], ['C', 10]], 0]], ['generated mix 20', [[['P0', 2, 0], ['P1', 3, 48], ['P2', 2, 30]], 60], [[['P2', 30], ['P1', 30]], 0]], ['generated mix 28', [[['P0', 3, 40]], 90], [[['P0', 40]], 50]], ['generated mix 38', [[['P0', 3, 40], ['P1', 3, 20], ['P2', 2, 20], ['P3', 5, 10], ['P4', 2, 20]], 60], [[['P2', 20], ['P4', 20], ['P1', 20]], 0]]], [['generated mix 45', [[['P0', 3, 10], ['P1', 8, 0], ['P2', 3, 30], ['P3', 3, 48], ['P4', 1, 48], ['P5', 3, 30]], 90], [[['P4', 48], ['P0', 10], ['P2', 30], ['P3', 2]], 0]], ['generated mix 42', [[['P0', 5, 20], ['P1', 3, 30], ['P2', 2, 0]], 90], [[['P1', 30], ['P0', 20]], 40]], ['shortfall', [[['A', 1, 10]], 25], [[['A', 10]], 15]], ['zero need', [[['A', 1, 10]], 0], [[], 0]], ['exact whole', [[['A', 1, 30]], 30], [[['A', 30]], 0]], ['generated mix 31', [[['P0', 5, 20], ['P1', 3, 20], ['P2', 2, 40], ['P3', 5, 20]], 30], [[['P1', 20], ['P2', 10]], 0]], ['generated mix 39', [[['P0', 5, 30], ['P1', 5, 40], ['P2', 8, 20]], 25], [[['P2', 20], ['P0', 5]], 0]], ['generated mix 49', [[['P0', 3, 20], ['P1', 1, 0], ['P2', 8, 40], ['P3', 5, 20], ['P4', 5, 30], ['P5', 3, 40]], 25], [[['P0', 20], ['P5', 5]], 0]]], [['generated mix 60', [[['P0', 3, 20], ['P1', 5, 20], ['P2', 3, 20], ['P3', 3, 30]], 30], [[['P0', 20], ['P2', 10]], 0]], ['generated mix 53', [[['P0', 5, 48], ['P1', 3, 48], ['P2', 3, 20], ['P3', 3, 48], ['P4', 3, 10], ['P5', 3, 48]], 50], [[['P1', 48], ['P2', 2]], 0]], ['clean-out skip big', [[['A', 1, 50], ['B', 2, 20], ['C', 3, 10]], 30], [[['B', 20], ['C', 10]], 0]], ['partial oldest', [[['A', 1, 50], ['B', 2, 60]], 30], [[['A', 30]], 0]], ['equal qty pallets', [[['A', 1, 20], ['B', 2, 20], ['C', 3, 40]], 50], [[['A', 20], ['B', 20], ['C', 10]], 0]], ['generated mix 42', [[['P0', 5, 20], ['P1', 3, 30], ['P2', 2, 0]], 90], [[['P1', 30], ['P0', 20]], 40]], ['generated mix 50', [[['P0', 8, 20], ['P1', 8, 20], ['P2', 2, 20], ['P3', 3, 0]], 20], [[['P2', 20]], 0]], ['generated mix 59', [[['P0', 3, 20], ['P1', 2, 40], ['P2', 3, 0], ['P3', 3, 20], ['P4', 5, 40]], 10], [[['P1', 10]], 0]]]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| clean-out skip big | [[['B', 20], ['C', 10]], 0] | [[['B', 20], ['C', 10]], 0] | Passed |
| generated mix 7 | [[['P0', 20], ['P1', 30], ['P2', 10]], 0] | [[['P2', 10], ['P3', 20], ['P0', 20], ['P1', 10]], 0] | Failed |
| exact whole | [[['A', 30]], 0] | [[['A', 30]], 0] | Passed |
| shortfall | [[['A', 10]], 15] | [[['A', 10]], 15] | Passed |
| zero need | [[], 0] | [[], 0] | Passed |
| partial oldest | [[['A', 30]], 0] | [[['A', 30]], 0] | Passed |
| equal qty pallets | [[['A', 20], ['B', 20], ['C', 10]], 0] | [[['A', 20], ['B', 20], ['C', 10]], 0] | Passed |
| generated mix 9 | [[['P0', 20]], 0] | [[['P0', 20]], 0] | Passed |
SHA-256 / 2037bcda5d9b31519a03ec6e563ba40d4e580f2cce31215f6337037235861339
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(pallets, need):
order = sorted(pallets, key=lambda p: (p[1], p[0]))
rem = need
alloc = []
taken = set()
for lp, day, q in order:
if 0 < q <= rem:
alloc.append([lp, q])
taken.add(lp)
rem -= q
for lp, day, q in order:
if rem == 0:
break
if lp in taken:
continue
t = min(q, rem)
if t > 0:
alloc.append([lp, t])
rem -= t
return [alloc, rem]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['clean-out skip big', [[['A', 1, 50], ['B', 2, 20], ['C', 3, 10]], 30], [[['B', 20], ['C', 10]], 0]], ['generated mix 7', [[['P0', 8, 20], ['P1', 8, 30], ['P2', 3, 10], ['P3', 5, 20]], 60], [[['P2', 10], ['P3', 20], ['P0', 20], ['P1', 10]], 0]], ['exact whole', [[['A', 1, 30]], 30], [[['A', 30]], 0]], ['shortfall', [[['A', 1, 10]], 25], [[['A', 10]], 15]], ['zero need', [[['A', 1, 10]], 0], [[], 0]], ['partial oldest', [[['A', 1, 50], ['B', 2, 60]], 30], [[['A', 30]], 0]], ['equal qty pallets', [[['A', 1, 20], ['B', 2, 20], ['C', 3, 40]], 50], [[['A', 20], ['B', 20], ['C', 10]], 0]], ['generated mix 9', [[['P0', 1, 20], ['P1', 2, 48], ['P2', 2, 20]], 20], [[['P0', 20]], 0]]], [['generated mix 11', [[['P0', 5, 20], ['P1', 3, 40], ['P2', 3, 0], ['P3', 3, 20], ['P4', 3, 0], ['P5', 1, 20]], 20], [[['P5', 20]], 0]], ['generated mix 19', [[['P0', 5, 10], ['P1', 3, 40], ['P2', 1, 30], ['P3', 3, 30]], 60], [[['P2', 30], ['P3', 30]], 0]], ['shortfall', [[['A', 1, 10]], 25], [[['A', 10]], 15]], ['zero need', [[['A', 1, 10]], 0], [[], 0]], ['exact whole', [[['A', 1, 30]], 30], [[['A', 30]], 0]], ['generated mix 9', [[['P0', 1, 20], ['P1', 2, 48], ['P2', 2, 20]], 20], [[['P0', 20]], 0]], ['generated mix 18', [[['P0', 3, 0], ['P1', 3, 40]], 90], [[['P1', 40]], 50]], ['generated mix 27', [[['P0', 8, 20], ['P1', 5, 48], ['P2', 5, 20]], 90], [[['P1', 48], ['P2', 20], ['P0', 20]], 2]]], [['generated mix 30', [[['P0', 1, 20], ['P1', 5, 40], ['P2', 3, 48], ['P3', 2, 10], ['P4', 1, 48], ['P5', 2, 20]], 90], [[['P0', 20], ['P4', 48], ['P3', 10], ['P5', 12]], 0]], ['generated mix 31', [[['P0', 5, 20], ['P1', 3, 20], ['P2', 2, 40], ['P3', 5, 20]], 30], [[['P1', 20], ['P2', 10]], 0]], ['clean-out skip big', [[['A', 1, 50], ['B', 2, 20], ['C', 3, 10]], 30], [[['B', 20], ['C', 10]], 0]], ['partial oldest', [[['A', 1, 50], ['B', 2, 60]], 30], [[['A', 30]], 0]], ['equal qty pallets', [[['A', 1, 20], ['B', 2, 20], ['C', 3, 40]], 50], [[['A', 20], ['B', 20], ['C', 10]], 0]], ['generated mix 20', [[['P0', 2, 0], ['P1', 3, 48], ['P2', 2, 30]], 60], [[['P2', 30], ['P1', 30]], 0]], ['generated mix 28', [[['P0', 3, 40]], 90], [[['P0', 40]], 50]], ['generated mix 38', [[['P0', 3, 40], ['P1', 3, 20], ['P2', 2, 20], ['P3', 5, 10], ['P4', 2, 20]], 60], [[['P2', 20], ['P4', 20], ['P1', 20]], 0]]], [['generated mix 45', [[['P0', 3, 10], ['P1', 8, 0], ['P2', 3, 30], ['P3', 3, 48], ['P4', 1, 48], ['P5', 3, 30]], 90], [[['P4', 48], ['P0', 10], ['P2', 30], ['P3', 2]], 0]], ['generated mix 42', [[['P0', 5, 20], ['P1', 3, 30], ['P2', 2, 0]], 90], [[['P1', 30], ['P0', 20]], 40]], ['shortfall', [[['A', 1, 10]], 25], [[['A', 10]], 15]], ['zero need', [[['A', 1, 10]], 0], [[], 0]], ['exact whole', [[['A', 1, 30]], 30], [[['A', 30]], 0]], ['generated mix 31', [[['P0', 5, 20], ['P1', 3, 20], ['P2', 2, 40], ['P3', 5, 20]], 30], [[['P1', 20], ['P2', 10]], 0]], ['generated mix 39', [[['P0', 5, 30], ['P1', 5, 40], ['P2', 8, 20]], 25], [[['P2', 20], ['P0', 5]], 0]], ['generated mix 49', [[['P0', 3, 20], ['P1', 1, 0], ['P2', 8, 40], ['P3', 5, 20], ['P4', 5, 30], ['P5', 3, 40]], 25], [[['P0', 20], ['P5', 5]], 0]]], [['generated mix 60', [[['P0', 3, 20], ['P1', 5, 20], ['P2', 3, 20], ['P3', 3, 30]], 30], [[['P0', 20], ['P2', 10]], 0]], ['generated mix 53', [[['P0', 5, 48], ['P1', 3, 48], ['P2', 3, 20], ['P3', 3, 48], ['P4', 3, 10], ['P5', 3, 48]], 50], [[['P1', 48], ['P2', 2]], 0]], ['clean-out skip big', [[['A', 1, 50], ['B', 2, 20], ['C', 3, 10]], 30], [[['B', 20], ['C', 10]], 0]], ['partial oldest', [[['A', 1, 50], ['B', 2, 60]], 30], [[['A', 30]], 0]], ['equal qty pallets', [[['A', 1, 20], ['B', 2, 20], ['C', 3, 40]], 50], [[['A', 20], ['B', 20], ['C', 10]], 0]], ['generated mix 42', [[['P0', 5, 20], ['P1', 3, 30], ['P2', 2, 0]], 90], [[['P1', 30], ['P0', 20]], 40]], ['generated mix 50', [[['P0', 8, 20], ['P1', 8, 20], ['P2', 2, 20], ['P3', 3, 0]], 20], [[['P2', 20]], 0]], ['generated mix 59', [[['P0', 3, 20], ['P1', 2, 40], ['P2', 3, 0], ['P3', 3, 20], ['P4', 5, 40]], 10], [[['P1', 10]], 0]]]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| clean-out skip big | [[['B', 20], ['C', 10]], 0] | [[['B', 20], ['C', 10]], 0] | Passed |
| generated mix 7 | [[['P2', 10], ['P3', 20], ['P0', 20], ['P1', 10]], 0] | [[['P2', 10], ['P3', 20], ['P0', 20], ['P1', 10]], 0] | Passed |
| exact whole | [[['A', 30]], 0] | [[['A', 30]], 0] | Passed |
| shortfall | [[['A', 10]], 15] | [[['A', 10]], 15] | Passed |
| zero need | [[], 0] | [[], 0] | Passed |
| partial oldest | [[['A', 30]], 0] | [[['A', 30]], 0] | Passed |
| equal qty pallets | [[['A', 20], ['B', 20], ['C', 10]], 0] | [[['A', 20], ['B', 20], ['C', 10]], 0] | Passed |
| generated mix 9 | [[['P0', 20]], 0] | [[['P0', 20]], 0] | Passed |
SHA-256 / 657299895349446bb547848fe1ba11e0ad0976fe141482fccfb55e1fc2901e1a
Verification & scope
Stipulated clean-out policy; no lot, expiry, or location travel considerations. 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:10.705398+00:00.
Case digest / 700cf875858d2d05513734a75466147ee2a525ec77c998d65aa2693a5563c497