FA-95171 / Warehouse slotting and bin packing / Open access
Nested bin fill: SKU limit off by one · case 01
A bin holding exactly the maximum number of SKUs is rejected.
ROOT CAUSE
The distinct SKU limit is compared strictly.
VERIFIED REPAIR
Allow up to and including max_skus distinct stocked SKUs.
Unsuccessful approach: Counting input lines instead of distinct stocked SKUs penalises duplicate and empty lines.
Case contract
lines [[sku, qty, unit_volume, nest_increment]]. Lines for the same SKU are merged. A nesting SKU (increment > 0) occupies unit_volume + (qty-1)*increment; others qty*unit_volume; qty 0 contributes nothing and is not counted. Bin fits when total <= bin_vol and distinct stocked SKUs <= max_skus. Return [total, fits].
Why this case matters
Nesting products such as cups and trays occupy far less space than unit cube suggests.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(lines, bin_vol, max_skus):
merged = {}
for sku, qty, uv, nv in lines:
if sku in merged:
merged[sku][0] += qty
else:
merged[sku] = [qty, uv, nv]
total = 0
count = 0
for sku, (qty, uv, nv) in merged.items():
if qty <= 0:
continue
count += 1
if nv > 0:
total += uv + (qty - 1) * nv
else:
total += qty * uv
return [total, total <= bin_vol and count < max_skus]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['nesting', [[['CUP', 10, 10, 2]], 30, 1], [28, True]], ['zero line', [[['CUP', 1, 10, 2], ['BOX', 0, 40, 0]], 30, 1], [10, True]], ['capacity equal', [[['CUP', 11, 10, 2]], 30, 1], [30, True]], ['non nesting', [[['BOX', 2, 40, 0]], 80, 1], [80, True]], ['merged lines nest together', [[['CUP', 5, 10, 2], ['CUP', 5, 10, 2]], 30, 1], [28, True]], ['generated mix 7', [[['TRY', 2, 25, 5]], 120, 2], [30, True]], ['generated mix 15', [[['CUP', 2, 10, 2], ['BWL', 1, 30, 6], ['BOX', 2, 40, 0], ['BWL', 1, 30, 6]], 150, 3], [128, True]], ['generated mix 23', [[['TRY', 2, 25, 5], ['CUP', 10, 10, 2], ['TRY', 0, 25, 5]], 150, 2], [58, True]]], [['generated mix 16', [[['TRY', 1, 25, 5], ['BWL', 2, 30, 6], ['LID', 1, 4, 0]], 120, 3], [65, True]], ['generated mix 42', [[['LID', 5, 4, 0], ['BWL', 1, 30, 6], ['BWL', 1, 30, 6]], 100, 2], [56, True]], ['zero line', [[['CUP', 1, 10, 2], ['BOX', 0, 40, 0]], 30, 1], [10, True]], ['sku limit', [[['CUP', 1, 10, 2], ['LID', 1, 4, 0]], 100, 1], [14, False]], ['capacity equal', [[['CUP', 11, 10, 2]], 30, 1], [30, True]], ['generated mix 9', [[['CUP', 10, 10, 2], ['TRY', 10, 25, 5], ['BOX', 5, 40, 0], ['LID', 10, 4, 0], ['BWL', 2, 30, 6]], 80, 1], [374, False]], ['generated mix 18', [[['CUP', 10, 10, 2]], 150, 2], [28, True]], ['generated mix 26', [[['CUP', 5, 10, 2], ['BOX', 1, 40, 0], ['BOX', 2, 40, 0]], 50, 3], [138, False]]], [['generated mix 47', [[['TRY', 10, 25, 5]], 80, 1], [70, True]], ['merged lines nest together', [[['CUP', 5, 10, 2], ['CUP', 5, 10, 2]], 30, 1], [28, True]], ['capacity equal', [[['CUP', 11, 10, 2]], 30, 1], [30, True]], ['non nesting', [[['BOX', 2, 40, 0]], 80, 1], [80, True]], ['nesting', [[['CUP', 10, 10, 2]], 30, 1], [28, True]], ['zero line', [[['CUP', 1, 10, 2], ['BOX', 0, 40, 0]], 30, 1], [10, True]], ['generated mix 22', [[['BOX', 2, 40, 0], ['BOX', 10, 40, 0], ['BOX', 0, 40, 0], ['BOX', 2, 40, 0], ['LID', 1, 4, 0]], 50, 2], [564, False]], ['generated mix 30', [[['BOX', 1, 40, 0], ['TRY', 2, 25, 5]], 120, 1], [70, False]]], [['nesting', [[['CUP', 10, 10, 2]], 30, 1], [28, True]], ['generated mix 35', [[['CUP', 0, 10, 2], ['TRY', 0, 25, 5], ['BOX', 0, 40, 0], ['LID', 1, 4, 0]], 80, 2], [4, True]], ['sku limit', [[['CUP', 1, 10, 2], ['LID', 1, 4, 0]], 100, 1], [14, False]], ['merged lines nest together', [[['CUP', 5, 10, 2], ['CUP', 5, 10, 2]], 30, 1], [28, True]], ['non nesting', [[['BOX', 2, 40, 0]], 80, 1], [80, True]], ['capacity equal', [[['CUP', 11, 10, 2]], 30, 1], [30, True]], ['generated mix 33', [[['LID', 5, 4, 0], ['CUP', 1, 10, 2], ['TRY', 0, 25, 5], ['BWL', 10, 30, 6]], 50, 3], [114, False]], ['generated mix 42', [[['LID', 5, 4, 0], ['BWL', 1, 30, 6], ['BWL', 1, 30, 6]], 100, 2], [56, True]]], [['generated mix 16', [[['TRY', 1, 25, 5], ['BWL', 2, 30, 6], ['LID', 1, 4, 0]], 120, 3], [65, True]], ['generated mix 61', [[['TRY', 1, 25, 5], ['TRY', 5, 25, 5], ['TRY', 2, 25, 5]], 100, 1], [60, True]], ['nesting', [[['CUP', 10, 10, 2]], 30, 1], [28, True]], ['merged lines nest together', [[['CUP', 5, 10, 2], ['CUP', 5, 10, 2]], 30, 1], [28, True]], ['non nesting', [[['BOX', 2, 40, 0]], 80, 1], [80, True]], ['generated mix 43', [[['LID', 2, 4, 0], ['TRY', 5, 25, 5]], 100, 2], [53, True]], ['generated mix 51', [[['LID', 10, 4, 0], ['TRY', 0, 25, 5], ['BWL', 10, 30, 6]], 150, 2], [124, True]], ['generated mix 59', [[['LID', 0, 4, 0], ['BOX', 2, 40, 0], ['LID', 10, 4, 0], ['BWL', 5, 30, 6]], 50, 3], [174, False]]]]
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 |
|---|---|---|---|
| nesting | [28, False] | [28, True] | Failed |
| zero line | [10, False] | [10, True] | Failed |
| capacity equal | [30, False] | [30, True] | Failed |
| non nesting | [80, False] | [80, True] | Failed |
| merged lines nest together | [28, False] | [28, True] | Failed |
| generated mix 7 | [30, True] | [30, True] | Passed |
| generated mix 15 | [128, False] | [128, True] | Failed |
| generated mix 23 | [58, False] | [58, True] | Failed |
SHA-256 / dae2f4b9a4ba06d031cca32d1dfefa5aaa23524ecfc2f6bf48f04ac9fb167515
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(lines, bin_vol, max_skus):
merged = {}
for sku, qty, uv, nv in lines:
if sku in merged:
merged[sku][0] += qty
else:
merged[sku] = [qty, uv, nv]
total = 0
count = 0
for sku, (qty, uv, nv) in merged.items():
if qty <= 0:
continue
count += 1
if nv > 0:
total += uv + (qty - 1) * nv
else:
total += qty * uv
return [total, total <= bin_vol and len(lines) <= max_skus]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['nesting', [[['CUP', 10, 10, 2]], 30, 1], [28, True]], ['zero line', [[['CUP', 1, 10, 2], ['BOX', 0, 40, 0]], 30, 1], [10, True]], ['capacity equal', [[['CUP', 11, 10, 2]], 30, 1], [30, True]], ['non nesting', [[['BOX', 2, 40, 0]], 80, 1], [80, True]], ['merged lines nest together', [[['CUP', 5, 10, 2], ['CUP', 5, 10, 2]], 30, 1], [28, True]], ['generated mix 7', [[['TRY', 2, 25, 5]], 120, 2], [30, True]], ['generated mix 15', [[['CUP', 2, 10, 2], ['BWL', 1, 30, 6], ['BOX', 2, 40, 0], ['BWL', 1, 30, 6]], 150, 3], [128, True]], ['generated mix 23', [[['TRY', 2, 25, 5], ['CUP', 10, 10, 2], ['TRY', 0, 25, 5]], 150, 2], [58, True]]], [['generated mix 16', [[['TRY', 1, 25, 5], ['BWL', 2, 30, 6], ['LID', 1, 4, 0]], 120, 3], [65, True]], ['generated mix 42', [[['LID', 5, 4, 0], ['BWL', 1, 30, 6], ['BWL', 1, 30, 6]], 100, 2], [56, True]], ['zero line', [[['CUP', 1, 10, 2], ['BOX', 0, 40, 0]], 30, 1], [10, True]], ['sku limit', [[['CUP', 1, 10, 2], ['LID', 1, 4, 0]], 100, 1], [14, False]], ['capacity equal', [[['CUP', 11, 10, 2]], 30, 1], [30, True]], ['generated mix 9', [[['CUP', 10, 10, 2], ['TRY', 10, 25, 5], ['BOX', 5, 40, 0], ['LID', 10, 4, 0], ['BWL', 2, 30, 6]], 80, 1], [374, False]], ['generated mix 18', [[['CUP', 10, 10, 2]], 150, 2], [28, True]], ['generated mix 26', [[['CUP', 5, 10, 2], ['BOX', 1, 40, 0], ['BOX', 2, 40, 0]], 50, 3], [138, False]]], [['generated mix 47', [[['TRY', 10, 25, 5]], 80, 1], [70, True]], ['merged lines nest together', [[['CUP', 5, 10, 2], ['CUP', 5, 10, 2]], 30, 1], [28, True]], ['capacity equal', [[['CUP', 11, 10, 2]], 30, 1], [30, True]], ['non nesting', [[['BOX', 2, 40, 0]], 80, 1], [80, True]], ['nesting', [[['CUP', 10, 10, 2]], 30, 1], [28, True]], ['zero line', [[['CUP', 1, 10, 2], ['BOX', 0, 40, 0]], 30, 1], [10, True]], ['generated mix 22', [[['BOX', 2, 40, 0], ['BOX', 10, 40, 0], ['BOX', 0, 40, 0], ['BOX', 2, 40, 0], ['LID', 1, 4, 0]], 50, 2], [564, False]], ['generated mix 30', [[['BOX', 1, 40, 0], ['TRY', 2, 25, 5]], 120, 1], [70, False]]], [['nesting', [[['CUP', 10, 10, 2]], 30, 1], [28, True]], ['generated mix 35', [[['CUP', 0, 10, 2], ['TRY', 0, 25, 5], ['BOX', 0, 40, 0], ['LID', 1, 4, 0]], 80, 2], [4, True]], ['sku limit', [[['CUP', 1, 10, 2], ['LID', 1, 4, 0]], 100, 1], [14, False]], ['merged lines nest together', [[['CUP', 5, 10, 2], ['CUP', 5, 10, 2]], 30, 1], [28, True]], ['non nesting', [[['BOX', 2, 40, 0]], 80, 1], [80, True]], ['capacity equal', [[['CUP', 11, 10, 2]], 30, 1], [30, True]], ['generated mix 33', [[['LID', 5, 4, 0], ['CUP', 1, 10, 2], ['TRY', 0, 25, 5], ['BWL', 10, 30, 6]], 50, 3], [114, False]], ['generated mix 42', [[['LID', 5, 4, 0], ['BWL', 1, 30, 6], ['BWL', 1, 30, 6]], 100, 2], [56, True]]], [['generated mix 16', [[['TRY', 1, 25, 5], ['BWL', 2, 30, 6], ['LID', 1, 4, 0]], 120, 3], [65, True]], ['generated mix 61', [[['TRY', 1, 25, 5], ['TRY', 5, 25, 5], ['TRY', 2, 25, 5]], 100, 1], [60, True]], ['nesting', [[['CUP', 10, 10, 2]], 30, 1], [28, True]], ['merged lines nest together', [[['CUP', 5, 10, 2], ['CUP', 5, 10, 2]], 30, 1], [28, True]], ['non nesting', [[['BOX', 2, 40, 0]], 80, 1], [80, True]], ['generated mix 43', [[['LID', 2, 4, 0], ['TRY', 5, 25, 5]], 100, 2], [53, True]], ['generated mix 51', [[['LID', 10, 4, 0], ['TRY', 0, 25, 5], ['BWL', 10, 30, 6]], 150, 2], [124, True]], ['generated mix 59', [[['LID', 0, 4, 0], ['BOX', 2, 40, 0], ['LID', 10, 4, 0], ['BWL', 5, 30, 6]], 50, 3], [174, False]]]]
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 |
|---|---|---|---|
| nesting | [28, True] | [28, True] | Passed |
| zero line | [10, False] | [10, True] | Failed |
| capacity equal | [30, True] | [30, True] | Passed |
| non nesting | [80, True] | [80, True] | Passed |
| merged lines nest together | [28, False] | [28, True] | Failed |
| generated mix 7 | [30, True] | [30, True] | Passed |
| generated mix 15 | [128, False] | [128, True] | Failed |
| generated mix 23 | [58, False] | [58, True] | Failed |
SHA-256 / c413db454ce9ac547d73cd072eaef2be7b13333a33971a82cb687f8a1e4d1e07
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(lines, bin_vol, max_skus):
merged = {}
for sku, qty, uv, nv in lines:
if sku in merged:
merged[sku][0] += qty
else:
merged[sku] = [qty, uv, nv]
total = 0
count = 0
for sku, (qty, uv, nv) in merged.items():
if qty <= 0:
continue
count += 1
if nv > 0:
total += uv + (qty - 1) * nv
else:
total += qty * uv
return [total, total <= bin_vol and count <= max_skus]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['nesting', [[['CUP', 10, 10, 2]], 30, 1], [28, True]], ['zero line', [[['CUP', 1, 10, 2], ['BOX', 0, 40, 0]], 30, 1], [10, True]], ['capacity equal', [[['CUP', 11, 10, 2]], 30, 1], [30, True]], ['non nesting', [[['BOX', 2, 40, 0]], 80, 1], [80, True]], ['merged lines nest together', [[['CUP', 5, 10, 2], ['CUP', 5, 10, 2]], 30, 1], [28, True]], ['generated mix 7', [[['TRY', 2, 25, 5]], 120, 2], [30, True]], ['generated mix 15', [[['CUP', 2, 10, 2], ['BWL', 1, 30, 6], ['BOX', 2, 40, 0], ['BWL', 1, 30, 6]], 150, 3], [128, True]], ['generated mix 23', [[['TRY', 2, 25, 5], ['CUP', 10, 10, 2], ['TRY', 0, 25, 5]], 150, 2], [58, True]]], [['generated mix 16', [[['TRY', 1, 25, 5], ['BWL', 2, 30, 6], ['LID', 1, 4, 0]], 120, 3], [65, True]], ['generated mix 42', [[['LID', 5, 4, 0], ['BWL', 1, 30, 6], ['BWL', 1, 30, 6]], 100, 2], [56, True]], ['zero line', [[['CUP', 1, 10, 2], ['BOX', 0, 40, 0]], 30, 1], [10, True]], ['sku limit', [[['CUP', 1, 10, 2], ['LID', 1, 4, 0]], 100, 1], [14, False]], ['capacity equal', [[['CUP', 11, 10, 2]], 30, 1], [30, True]], ['generated mix 9', [[['CUP', 10, 10, 2], ['TRY', 10, 25, 5], ['BOX', 5, 40, 0], ['LID', 10, 4, 0], ['BWL', 2, 30, 6]], 80, 1], [374, False]], ['generated mix 18', [[['CUP', 10, 10, 2]], 150, 2], [28, True]], ['generated mix 26', [[['CUP', 5, 10, 2], ['BOX', 1, 40, 0], ['BOX', 2, 40, 0]], 50, 3], [138, False]]], [['generated mix 47', [[['TRY', 10, 25, 5]], 80, 1], [70, True]], ['merged lines nest together', [[['CUP', 5, 10, 2], ['CUP', 5, 10, 2]], 30, 1], [28, True]], ['capacity equal', [[['CUP', 11, 10, 2]], 30, 1], [30, True]], ['non nesting', [[['BOX', 2, 40, 0]], 80, 1], [80, True]], ['nesting', [[['CUP', 10, 10, 2]], 30, 1], [28, True]], ['zero line', [[['CUP', 1, 10, 2], ['BOX', 0, 40, 0]], 30, 1], [10, True]], ['generated mix 22', [[['BOX', 2, 40, 0], ['BOX', 10, 40, 0], ['BOX', 0, 40, 0], ['BOX', 2, 40, 0], ['LID', 1, 4, 0]], 50, 2], [564, False]], ['generated mix 30', [[['BOX', 1, 40, 0], ['TRY', 2, 25, 5]], 120, 1], [70, False]]], [['nesting', [[['CUP', 10, 10, 2]], 30, 1], [28, True]], ['generated mix 35', [[['CUP', 0, 10, 2], ['TRY', 0, 25, 5], ['BOX', 0, 40, 0], ['LID', 1, 4, 0]], 80, 2], [4, True]], ['sku limit', [[['CUP', 1, 10, 2], ['LID', 1, 4, 0]], 100, 1], [14, False]], ['merged lines nest together', [[['CUP', 5, 10, 2], ['CUP', 5, 10, 2]], 30, 1], [28, True]], ['non nesting', [[['BOX', 2, 40, 0]], 80, 1], [80, True]], ['capacity equal', [[['CUP', 11, 10, 2]], 30, 1], [30, True]], ['generated mix 33', [[['LID', 5, 4, 0], ['CUP', 1, 10, 2], ['TRY', 0, 25, 5], ['BWL', 10, 30, 6]], 50, 3], [114, False]], ['generated mix 42', [[['LID', 5, 4, 0], ['BWL', 1, 30, 6], ['BWL', 1, 30, 6]], 100, 2], [56, True]]], [['generated mix 16', [[['TRY', 1, 25, 5], ['BWL', 2, 30, 6], ['LID', 1, 4, 0]], 120, 3], [65, True]], ['generated mix 61', [[['TRY', 1, 25, 5], ['TRY', 5, 25, 5], ['TRY', 2, 25, 5]], 100, 1], [60, True]], ['nesting', [[['CUP', 10, 10, 2]], 30, 1], [28, True]], ['merged lines nest together', [[['CUP', 5, 10, 2], ['CUP', 5, 10, 2]], 30, 1], [28, True]], ['non nesting', [[['BOX', 2, 40, 0]], 80, 1], [80, True]], ['generated mix 43', [[['LID', 2, 4, 0], ['TRY', 5, 25, 5]], 100, 2], [53, True]], ['generated mix 51', [[['LID', 10, 4, 0], ['TRY', 0, 25, 5], ['BWL', 10, 30, 6]], 150, 2], [124, True]], ['generated mix 59', [[['LID', 0, 4, 0], ['BOX', 2, 40, 0], ['LID', 10, 4, 0], ['BWL', 5, 30, 6]], 50, 3], [174, False]]]]
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 |
|---|---|---|---|
| nesting | [28, True] | [28, True] | Passed |
| zero line | [10, True] | [10, True] | Passed |
| capacity equal | [30, True] | [30, True] | Passed |
| non nesting | [80, True] | [80, True] | Passed |
| merged lines nest together | [28, True] | [28, True] | Passed |
| generated mix 7 | [30, True] | [30, True] | Passed |
| generated mix 15 | [128, True] | [128, True] | Passed |
| generated mix 23 | [58, True] | [58, True] | Passed |
SHA-256 / 1529563aa0804848fecad510332362b331e955e6648398e5bb516eaa5dd361d4
Verification & scope
Stipulated linear nesting model; no orientation or partial stacks. 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:11.211038+00:00.
Case digest / 9f4a542d6f1d759fb93df4ba613d6aaaf9e4e8439f01f53ecdcb49ed4d5a9e40