FA-94896 / Warehouse slotting and bin packing / Open access
Replenishment: face sitting at min not triggered · case 01
A pick face whose on-hand equals its minimum is not replenished and stocks out during the next wave.
ROOT CAUSE
The trigger skips faces at exactly the minimum, treating min as an exclusive reorder point.
VERIFIED REPAIR
Trigger replenishment whenever on-hand is at or below the minimum.
Unsuccessful approach: Shifting the threshold by one unit triggers faces sitting one unit above min.
Case contract
faces [[loc, on_hand, min, max, case_pack, reserve_units]], min >= 1. Replenish when on_hand <= min. Quantity is the largest number of full cases that keeps on_hand <= max, limited to full cases available in reserve. A stocked-out face whose max leaves no room for a full case still gets one case if reserve has one. Zero-quantity tasks are dropped. Tasks are ordered by on_hand/min ascending, then loc.
Why this case matters
Min/max replenishment keeps forward pick faces stocked from reserve.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
N = 1
observations = []
def solve(faces):
tasks = []
for loc, oh, mn, mx, cp, reserve in faces:
if oh >= mn:
continue
avail = reserve // cp * cp
qty = (mx - oh) // cp * cp
qty = min(qty, avail)
if qty == 0 and oh == 0 and avail >= cp:
qty = cp
if qty == 0:
continue
tasks.append((Fraction(oh, mn), loc, qty))
tasks.sort()
return [[loc, qty] for _, loc, qty in tasks]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['at min triggers', [[['A', 10, 10, 34, 12, 100]]], [['A', 24]]], ['generated mix 16', [[['F0', 6, 6, 36, 1, 0], ['F1', 1, 10, 22, 1, 3], ['F2', 5, 4, 16, 6, 24], ['F3', 7, 6, 36, 6, 24]]], [['F1', 3]]], ['above min idle', [[['A', 11, 10, 34, 12, 100]]], []], ['stockout small max', [[['B', 0, 2, 5, 6, 12]]], [['B', 6]]], ['priority by ratio', [[['X', 5, 10, 40, 5, 100], ['Y', 2, 8, 40, 5, 100], ['Z', 0, 6, 40, 5, 100]]], [['Z', 40], ['Y', 35], ['X', 35]]], ['reserve partial case', [[['A', 0, 5, 30, 12, 20]]], [['A', 12]]], ['stockout no reserve', [[['B', 0, 2, 20, 6, 5]]], []], ['generated mix 8', [[['F0', 0, 12, 15, 6, 0], ['F1', 1, 10, 22, 6, 12]]], [['F1', 12]]]], [['generated mix 21', [[['F0', 0, 4, 16, 1, 24], ['F1', 11, 10, 22, 6, 12], ['F2', 0, 6, 18, 4, 24], ['F3', 3, 4, 34, 6, 48], ['F4', 12, 12, 24, 12, 100]]], [['F0', 16], ['F2', 16], ['F3', 30], ['F4', 12]]], ['generated mix 26', [[['F0', 7, 6, 6, 12, 48], ['F1', 0, 4, 28, 6, 12], ['F2', 0, 6, 30, 6, 0], ['F3', 1, 6, 6, 1, 3]]], [['F1', 12], ['F3', 3]]], ['stockout small max', [[['B', 0, 2, 5, 6, 12]]], [['B', 6]]], ['priority by ratio', [[['X', 5, 10, 40, 5, 100], ['Y', 2, 8, 40, 5, 100], ['Z', 0, 6, 40, 5, 100]]], [['Z', 40], ['Y', 35], ['X', 35]]], ['above min idle', [[['A', 11, 10, 34, 12, 100]]], []], ['generated mix 9', [[['F0', 6, 6, 9, 1, 100], ['F1', 1, 12, 18, 6, 0]]], [['F0', 3]]], ['generated mix 17', [[['F0', 1, 12, 24, 4, 12], ['F1', 12, 12, 18, 4, 24], ['F2', 11, 12, 24, 1, 12], ['F3', 11, 10, 40, 12, 100]]], [['F0', 12], ['F2', 12], ['F1', 4]]], ['generated mix 27', [[['F0', 1, 12, 24, 6, 24]]], [['F0', 18]]]], [['generated mix 63', [[['F0', 10, 10, 40, 4, 24], ['F1', 1, 12, 12, 12, 12], ['F2', 0, 10, 10, 4, 24], ['F3', 0, 12, 12, 4, 12]]], [['F2', 8], ['F3', 12], ['F0', 24]]], ['generated mix 44', [[['F0', 4, 4, 4, 6, 3], ['F1', 11, 10, 10, 1, 48], ['F2', 11, 12, 24, 4, 48], ['F3', 3, 6, 9, 4, 3]]], [['F2', 12]]], ['at min triggers', [[['A', 10, 10, 34, 12, 100]]], [['A', 24]]], ['reserve partial case', [[['A', 0, 5, 30, 12, 20]]], [['A', 12]]], ['stockout no reserve', [[['B', 0, 2, 20, 6, 5]]], []], ['generated mix 20', [[['F0', 0, 12, 36, 4, 48]]], [['F0', 36]]], ['generated mix 28', [[['F0', 3, 6, 36, 6, 48], ['F1', 1, 12, 42, 12, 3]]], [['F0', 30]]], ['generated mix 36', [[['F0', 0, 6, 6, 4, 3], ['F1', 5, 6, 12, 12, 48]]], []]], [['generated mix 7', [[['F0', 0, 12, 12, 12, 100], ['F1', 0, 10, 16, 4, 48], ['F2', 4, 4, 10, 6, 100], ['F3', 1, 4, 7, 1, 100]]], [['F0', 12], ['F1', 16], ['F3', 6], ['F2', 6]]], ['generated mix 67', [[['F0', 11, 10, 10, 4, 48], ['F1', 1, 12, 12, 1, 100], ['F2', 0, 12, 36, 6, 3], ['F3', 1, 4, 10, 1, 3]]], [['F1', 11], ['F3', 3]]], ['stockout small max', [[['B', 0, 2, 5, 6, 12]]], [['B', 6]]], ['priority by ratio', [[['X', 5, 10, 40, 5, 100], ['Y', 2, 8, 40, 5, 100], ['Z', 0, 6, 40, 5, 100]]], [['Z', 40], ['Y', 35], ['X', 35]]], ['above min idle', [[['A', 11, 10, 34, 12, 100]]], []], ['generated mix 32', [[['F0', 5, 4, 34, 4, 0], ['F1', 9, 10, 40, 12, 24], ['F2', 6, 6, 9, 12, 24], ['F3', 3, 6, 9, 6, 0]]], [['F1', 24]]], ['generated mix 40', [[['F0', 7, 6, 18, 6, 48], ['F1', 13, 12, 24, 1, 0], ['F2', 7, 6, 12, 12, 24]]], []], ['generated mix 48', [[['F0', 0, 12, 12, 6, 0], ['F1', 0, 10, 22, 1, 24], ['F2', 0, 12, 15, 1, 12]]], [['F1', 22], ['F2', 12]]]], [['generated mix 50', [[['F0', 11, 12, 36, 1, 12], ['F1', 0, 10, 22, 6, 12], ['F2', 4, 4, 28, 4, 48], ['F3', 1, 4, 7, 12, 0]]], [['F1', 12], ['F0', 12], ['F2', 24]]], ['generated mix 16', [[['F0', 6, 6, 36, 1, 0], ['F1', 1, 10, 22, 1, 3], ['F2', 5, 4, 16, 6, 24], ['F3', 7, 6, 36, 6, 24]]], [['F1', 3]]], ['at min triggers', [[['A', 10, 10, 34, 12, 100]]], [['A', 24]]], ['reserve partial case', [[['A', 0, 5, 30, 12, 20]]], [['A', 12]]], ['stockout no reserve', [[['B', 0, 2, 20, 6, 5]]], []], ['generated mix 43', [[['F0', 0, 6, 18, 4, 24], ['F1', 3, 4, 34, 4, 48], ['F2', 1, 4, 10, 12, 0], ['F3', 1, 4, 34, 12, 12]]], [['F0', 16], ['F3', 12], ['F1', 28]]], ['generated mix 52', [[['F0', 11, 10, 16, 6, 3], ['F1', 10, 10, 13, 4, 24], ['F2', 0, 4, 28, 1, 100], ['F3', 12, 12, 42, 4, 0]]], [['F2', 28]]], ['generated mix 60', [[['F0', 0, 10, 40, 1, 24], ['F1', 3, 6, 30, 4, 100], ['F2', 4, 4, 4, 6, 100]]], [['F0', 24], ['F1', 24]]]]]
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 |
|---|---|---|---|
| at min triggers | [] | [['A', 24]] | Failed |
| generated mix 16 | [['F1', 3]] | [['F1', 3]] | Passed |
| above min idle | [] | [] | Passed |
| stockout small max | [['B', 6]] | [['B', 6]] | Passed |
| priority by ratio | [['Z', 40], ['Y', 35], ['X', 35]] | [['Z', 40], ['Y', 35], ['X', 35]] | Passed |
| reserve partial case | [['A', 12]] | [['A', 12]] | Passed |
| stockout no reserve | [] | [] | Passed |
| generated mix 8 | [['F1', 12]] | [['F1', 12]] | Passed |
SHA-256 / c740f5c733bc262bd5a51fb627d29d90c18a030535b73cbeba90ac9886968257
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
N = 1
observations = []
def solve(faces):
tasks = []
for loc, oh, mn, mx, cp, reserve in faces:
if oh - 1 > mn:
continue
avail = reserve // cp * cp
qty = (mx - oh) // cp * cp
qty = min(qty, avail)
if qty == 0 and oh == 0 and avail >= cp:
qty = cp
if qty == 0:
continue
tasks.append((Fraction(oh, mn), loc, qty))
tasks.sort()
return [[loc, qty] for _, loc, qty in tasks]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['at min triggers', [[['A', 10, 10, 34, 12, 100]]], [['A', 24]]], ['generated mix 16', [[['F0', 6, 6, 36, 1, 0], ['F1', 1, 10, 22, 1, 3], ['F2', 5, 4, 16, 6, 24], ['F3', 7, 6, 36, 6, 24]]], [['F1', 3]]], ['above min idle', [[['A', 11, 10, 34, 12, 100]]], []], ['stockout small max', [[['B', 0, 2, 5, 6, 12]]], [['B', 6]]], ['priority by ratio', [[['X', 5, 10, 40, 5, 100], ['Y', 2, 8, 40, 5, 100], ['Z', 0, 6, 40, 5, 100]]], [['Z', 40], ['Y', 35], ['X', 35]]], ['reserve partial case', [[['A', 0, 5, 30, 12, 20]]], [['A', 12]]], ['stockout no reserve', [[['B', 0, 2, 20, 6, 5]]], []], ['generated mix 8', [[['F0', 0, 12, 15, 6, 0], ['F1', 1, 10, 22, 6, 12]]], [['F1', 12]]]], [['generated mix 21', [[['F0', 0, 4, 16, 1, 24], ['F1', 11, 10, 22, 6, 12], ['F2', 0, 6, 18, 4, 24], ['F3', 3, 4, 34, 6, 48], ['F4', 12, 12, 24, 12, 100]]], [['F0', 16], ['F2', 16], ['F3', 30], ['F4', 12]]], ['generated mix 26', [[['F0', 7, 6, 6, 12, 48], ['F1', 0, 4, 28, 6, 12], ['F2', 0, 6, 30, 6, 0], ['F3', 1, 6, 6, 1, 3]]], [['F1', 12], ['F3', 3]]], ['stockout small max', [[['B', 0, 2, 5, 6, 12]]], [['B', 6]]], ['priority by ratio', [[['X', 5, 10, 40, 5, 100], ['Y', 2, 8, 40, 5, 100], ['Z', 0, 6, 40, 5, 100]]], [['Z', 40], ['Y', 35], ['X', 35]]], ['above min idle', [[['A', 11, 10, 34, 12, 100]]], []], ['generated mix 9', [[['F0', 6, 6, 9, 1, 100], ['F1', 1, 12, 18, 6, 0]]], [['F0', 3]]], ['generated mix 17', [[['F0', 1, 12, 24, 4, 12], ['F1', 12, 12, 18, 4, 24], ['F2', 11, 12, 24, 1, 12], ['F3', 11, 10, 40, 12, 100]]], [['F0', 12], ['F2', 12], ['F1', 4]]], ['generated mix 27', [[['F0', 1, 12, 24, 6, 24]]], [['F0', 18]]]], [['generated mix 63', [[['F0', 10, 10, 40, 4, 24], ['F1', 1, 12, 12, 12, 12], ['F2', 0, 10, 10, 4, 24], ['F3', 0, 12, 12, 4, 12]]], [['F2', 8], ['F3', 12], ['F0', 24]]], ['generated mix 44', [[['F0', 4, 4, 4, 6, 3], ['F1', 11, 10, 10, 1, 48], ['F2', 11, 12, 24, 4, 48], ['F3', 3, 6, 9, 4, 3]]], [['F2', 12]]], ['at min triggers', [[['A', 10, 10, 34, 12, 100]]], [['A', 24]]], ['reserve partial case', [[['A', 0, 5, 30, 12, 20]]], [['A', 12]]], ['stockout no reserve', [[['B', 0, 2, 20, 6, 5]]], []], ['generated mix 20', [[['F0', 0, 12, 36, 4, 48]]], [['F0', 36]]], ['generated mix 28', [[['F0', 3, 6, 36, 6, 48], ['F1', 1, 12, 42, 12, 3]]], [['F0', 30]]], ['generated mix 36', [[['F0', 0, 6, 6, 4, 3], ['F1', 5, 6, 12, 12, 48]]], []]], [['generated mix 7', [[['F0', 0, 12, 12, 12, 100], ['F1', 0, 10, 16, 4, 48], ['F2', 4, 4, 10, 6, 100], ['F3', 1, 4, 7, 1, 100]]], [['F0', 12], ['F1', 16], ['F3', 6], ['F2', 6]]], ['generated mix 67', [[['F0', 11, 10, 10, 4, 48], ['F1', 1, 12, 12, 1, 100], ['F2', 0, 12, 36, 6, 3], ['F3', 1, 4, 10, 1, 3]]], [['F1', 11], ['F3', 3]]], ['stockout small max', [[['B', 0, 2, 5, 6, 12]]], [['B', 6]]], ['priority by ratio', [[['X', 5, 10, 40, 5, 100], ['Y', 2, 8, 40, 5, 100], ['Z', 0, 6, 40, 5, 100]]], [['Z', 40], ['Y', 35], ['X', 35]]], ['above min idle', [[['A', 11, 10, 34, 12, 100]]], []], ['generated mix 32', [[['F0', 5, 4, 34, 4, 0], ['F1', 9, 10, 40, 12, 24], ['F2', 6, 6, 9, 12, 24], ['F3', 3, 6, 9, 6, 0]]], [['F1', 24]]], ['generated mix 40', [[['F0', 7, 6, 18, 6, 48], ['F1', 13, 12, 24, 1, 0], ['F2', 7, 6, 12, 12, 24]]], []], ['generated mix 48', [[['F0', 0, 12, 12, 6, 0], ['F1', 0, 10, 22, 1, 24], ['F2', 0, 12, 15, 1, 12]]], [['F1', 22], ['F2', 12]]]], [['generated mix 50', [[['F0', 11, 12, 36, 1, 12], ['F1', 0, 10, 22, 6, 12], ['F2', 4, 4, 28, 4, 48], ['F3', 1, 4, 7, 12, 0]]], [['F1', 12], ['F0', 12], ['F2', 24]]], ['generated mix 16', [[['F0', 6, 6, 36, 1, 0], ['F1', 1, 10, 22, 1, 3], ['F2', 5, 4, 16, 6, 24], ['F3', 7, 6, 36, 6, 24]]], [['F1', 3]]], ['at min triggers', [[['A', 10, 10, 34, 12, 100]]], [['A', 24]]], ['reserve partial case', [[['A', 0, 5, 30, 12, 20]]], [['A', 12]]], ['stockout no reserve', [[['B', 0, 2, 20, 6, 5]]], []], ['generated mix 43', [[['F0', 0, 6, 18, 4, 24], ['F1', 3, 4, 34, 4, 48], ['F2', 1, 4, 10, 12, 0], ['F3', 1, 4, 34, 12, 12]]], [['F0', 16], ['F3', 12], ['F1', 28]]], ['generated mix 52', [[['F0', 11, 10, 16, 6, 3], ['F1', 10, 10, 13, 4, 24], ['F2', 0, 4, 28, 1, 100], ['F3', 12, 12, 42, 4, 0]]], [['F2', 28]]], ['generated mix 60', [[['F0', 0, 10, 40, 1, 24], ['F1', 3, 6, 30, 4, 100], ['F2', 4, 4, 4, 6, 100]]], [['F0', 24], ['F1', 24]]]]]
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 |
|---|---|---|---|
| at min triggers | [['A', 24]] | [['A', 24]] | Passed |
| generated mix 16 | [['F1', 3], ['F3', 24], ['F2', 6]] | [['F1', 3]] | Failed |
| above min idle | [['A', 12]] | [] | Failed |
| stockout small max | [['B', 6]] | [['B', 6]] | Passed |
| priority by ratio | [['Z', 40], ['Y', 35], ['X', 35]] | [['Z', 40], ['Y', 35], ['X', 35]] | Passed |
| reserve partial case | [['A', 12]] | [['A', 12]] | Passed |
| stockout no reserve | [] | [] | Passed |
| generated mix 8 | [['F1', 12]] | [['F1', 12]] | Passed |
SHA-256 / ecd8032415eb85ec3d1cc67e224296c130353072a688c72d92ead1ebed5de6af
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
N = 1
observations = []
def solve(faces):
tasks = []
for loc, oh, mn, mx, cp, reserve in faces:
if oh > mn:
continue
avail = reserve // cp * cp
qty = (mx - oh) // cp * cp
qty = min(qty, avail)
if qty == 0 and oh == 0 and avail >= cp:
qty = cp
if qty == 0:
continue
tasks.append((Fraction(oh, mn), loc, qty))
tasks.sort()
return [[loc, qty] for _, loc, qty in tasks]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['at min triggers', [[['A', 10, 10, 34, 12, 100]]], [['A', 24]]], ['generated mix 16', [[['F0', 6, 6, 36, 1, 0], ['F1', 1, 10, 22, 1, 3], ['F2', 5, 4, 16, 6, 24], ['F3', 7, 6, 36, 6, 24]]], [['F1', 3]]], ['above min idle', [[['A', 11, 10, 34, 12, 100]]], []], ['stockout small max', [[['B', 0, 2, 5, 6, 12]]], [['B', 6]]], ['priority by ratio', [[['X', 5, 10, 40, 5, 100], ['Y', 2, 8, 40, 5, 100], ['Z', 0, 6, 40, 5, 100]]], [['Z', 40], ['Y', 35], ['X', 35]]], ['reserve partial case', [[['A', 0, 5, 30, 12, 20]]], [['A', 12]]], ['stockout no reserve', [[['B', 0, 2, 20, 6, 5]]], []], ['generated mix 8', [[['F0', 0, 12, 15, 6, 0], ['F1', 1, 10, 22, 6, 12]]], [['F1', 12]]]], [['generated mix 21', [[['F0', 0, 4, 16, 1, 24], ['F1', 11, 10, 22, 6, 12], ['F2', 0, 6, 18, 4, 24], ['F3', 3, 4, 34, 6, 48], ['F4', 12, 12, 24, 12, 100]]], [['F0', 16], ['F2', 16], ['F3', 30], ['F4', 12]]], ['generated mix 26', [[['F0', 7, 6, 6, 12, 48], ['F1', 0, 4, 28, 6, 12], ['F2', 0, 6, 30, 6, 0], ['F3', 1, 6, 6, 1, 3]]], [['F1', 12], ['F3', 3]]], ['stockout small max', [[['B', 0, 2, 5, 6, 12]]], [['B', 6]]], ['priority by ratio', [[['X', 5, 10, 40, 5, 100], ['Y', 2, 8, 40, 5, 100], ['Z', 0, 6, 40, 5, 100]]], [['Z', 40], ['Y', 35], ['X', 35]]], ['above min idle', [[['A', 11, 10, 34, 12, 100]]], []], ['generated mix 9', [[['F0', 6, 6, 9, 1, 100], ['F1', 1, 12, 18, 6, 0]]], [['F0', 3]]], ['generated mix 17', [[['F0', 1, 12, 24, 4, 12], ['F1', 12, 12, 18, 4, 24], ['F2', 11, 12, 24, 1, 12], ['F3', 11, 10, 40, 12, 100]]], [['F0', 12], ['F2', 12], ['F1', 4]]], ['generated mix 27', [[['F0', 1, 12, 24, 6, 24]]], [['F0', 18]]]], [['generated mix 63', [[['F0', 10, 10, 40, 4, 24], ['F1', 1, 12, 12, 12, 12], ['F2', 0, 10, 10, 4, 24], ['F3', 0, 12, 12, 4, 12]]], [['F2', 8], ['F3', 12], ['F0', 24]]], ['generated mix 44', [[['F0', 4, 4, 4, 6, 3], ['F1', 11, 10, 10, 1, 48], ['F2', 11, 12, 24, 4, 48], ['F3', 3, 6, 9, 4, 3]]], [['F2', 12]]], ['at min triggers', [[['A', 10, 10, 34, 12, 100]]], [['A', 24]]], ['reserve partial case', [[['A', 0, 5, 30, 12, 20]]], [['A', 12]]], ['stockout no reserve', [[['B', 0, 2, 20, 6, 5]]], []], ['generated mix 20', [[['F0', 0, 12, 36, 4, 48]]], [['F0', 36]]], ['generated mix 28', [[['F0', 3, 6, 36, 6, 48], ['F1', 1, 12, 42, 12, 3]]], [['F0', 30]]], ['generated mix 36', [[['F0', 0, 6, 6, 4, 3], ['F1', 5, 6, 12, 12, 48]]], []]], [['generated mix 7', [[['F0', 0, 12, 12, 12, 100], ['F1', 0, 10, 16, 4, 48], ['F2', 4, 4, 10, 6, 100], ['F3', 1, 4, 7, 1, 100]]], [['F0', 12], ['F1', 16], ['F3', 6], ['F2', 6]]], ['generated mix 67', [[['F0', 11, 10, 10, 4, 48], ['F1', 1, 12, 12, 1, 100], ['F2', 0, 12, 36, 6, 3], ['F3', 1, 4, 10, 1, 3]]], [['F1', 11], ['F3', 3]]], ['stockout small max', [[['B', 0, 2, 5, 6, 12]]], [['B', 6]]], ['priority by ratio', [[['X', 5, 10, 40, 5, 100], ['Y', 2, 8, 40, 5, 100], ['Z', 0, 6, 40, 5, 100]]], [['Z', 40], ['Y', 35], ['X', 35]]], ['above min idle', [[['A', 11, 10, 34, 12, 100]]], []], ['generated mix 32', [[['F0', 5, 4, 34, 4, 0], ['F1', 9, 10, 40, 12, 24], ['F2', 6, 6, 9, 12, 24], ['F3', 3, 6, 9, 6, 0]]], [['F1', 24]]], ['generated mix 40', [[['F0', 7, 6, 18, 6, 48], ['F1', 13, 12, 24, 1, 0], ['F2', 7, 6, 12, 12, 24]]], []], ['generated mix 48', [[['F0', 0, 12, 12, 6, 0], ['F1', 0, 10, 22, 1, 24], ['F2', 0, 12, 15, 1, 12]]], [['F1', 22], ['F2', 12]]]], [['generated mix 50', [[['F0', 11, 12, 36, 1, 12], ['F1', 0, 10, 22, 6, 12], ['F2', 4, 4, 28, 4, 48], ['F3', 1, 4, 7, 12, 0]]], [['F1', 12], ['F0', 12], ['F2', 24]]], ['generated mix 16', [[['F0', 6, 6, 36, 1, 0], ['F1', 1, 10, 22, 1, 3], ['F2', 5, 4, 16, 6, 24], ['F3', 7, 6, 36, 6, 24]]], [['F1', 3]]], ['at min triggers', [[['A', 10, 10, 34, 12, 100]]], [['A', 24]]], ['reserve partial case', [[['A', 0, 5, 30, 12, 20]]], [['A', 12]]], ['stockout no reserve', [[['B', 0, 2, 20, 6, 5]]], []], ['generated mix 43', [[['F0', 0, 6, 18, 4, 24], ['F1', 3, 4, 34, 4, 48], ['F2', 1, 4, 10, 12, 0], ['F3', 1, 4, 34, 12, 12]]], [['F0', 16], ['F3', 12], ['F1', 28]]], ['generated mix 52', [[['F0', 11, 10, 16, 6, 3], ['F1', 10, 10, 13, 4, 24], ['F2', 0, 4, 28, 1, 100], ['F3', 12, 12, 42, 4, 0]]], [['F2', 28]]], ['generated mix 60', [[['F0', 0, 10, 40, 1, 24], ['F1', 3, 6, 30, 4, 100], ['F2', 4, 4, 4, 6, 100]]], [['F0', 24], ['F1', 24]]]]]
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 |
|---|---|---|---|
| at min triggers | [['A', 24]] | [['A', 24]] | Passed |
| generated mix 16 | [['F1', 3]] | [['F1', 3]] | Passed |
| above min idle | [] | [] | Passed |
| stockout small max | [['B', 6]] | [['B', 6]] | Passed |
| priority by ratio | [['Z', 40], ['Y', 35], ['X', 35]] | [['Z', 40], ['Y', 35], ['X', 35]] | Passed |
| reserve partial case | [['A', 12]] | [['A', 12]] | Passed |
| stockout no reserve | [] | [] | Passed |
| generated mix 8 | [['F1', 12]] | [['F1', 12]] | Passed |
SHA-256 / 533a02ec12410b4bc5eca845802705b258dd01a8356463151b516e3dfeee7995
Verification & scope
Stipulated min/max policy with whole-case moves only. 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:08.647116+00:00.
Case digest / ad21c1b20cd80383551716b81dfeb7ffe7b2647261534501427ff6c354a44203