FA-95151 / Warehouse slotting and bin packing / Open access
Nested bin fill: first unit counted at nest increment · case 01
Nested stacks are credited far less volume than they occupy, overfilling bins.
ROOT CAUSE
Every nested unit is sized at the nest increment, dropping the full volume of the base unit.
VERIFIED REPAIR
Size a nested stack as one full unit plus (qty - 1) increments.
Unsuccessful approach: Adding qty increments on top of the base unit double counts the base.
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 += qty * 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]], ['capacity equal', [[['CUP', 11, 10, 2]], 30, 1], [30, 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]], ['zero line', [[['CUP', 1, 10, 2], ['BOX', 0, 40, 0]], 30, 1], [10, 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 3', [[['CUP', 5, 10, 2], ['TRY', 0, 25, 5], ['LID', 0, 4, 0]], 100, 3], [18, True]], ['generated mix 2', [[['BWL', 2, 30, 6], ['LID', 0, 4, 0], ['BWL', 1, 30, 6]], 120, 3], [42, 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 11', [[['BWL', 1, 30, 6], ['LID', 2, 4, 0], ['LID', 0, 4, 0], ['LID', 5, 4, 0], ['BOX', 5, 40, 0]], 120, 3], [258, False]], ['generated mix 19', [[['BOX', 2, 40, 0], ['TRY', 0, 25, 5]], 80, 3], [80, True]], ['generated mix 27', [[['CUP', 2, 10, 2]], 100, 1], [12, True]]], [['generated mix 11', [[['BWL', 1, 30, 6], ['LID', 2, 4, 0], ['LID', 0, 4, 0], ['LID', 5, 4, 0], ['BOX', 5, 40, 0]], 120, 3], [258, False]], ['generated mix 7', [[['TRY', 2, 25, 5]], 120, 2], [30, 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 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]], ['generated mix 38', [[['BWL', 1, 30, 6], ['BOX', 2, 40, 0], ['LID', 5, 4, 0]], 120, 1], [130, False]]], [['generated mix 23', [[['TRY', 2, 25, 5], ['CUP', 10, 10, 2], ['TRY', 0, 25, 5]], 150, 2], [58, True]], ['generated mix 15', [[['CUP', 2, 10, 2], ['BWL', 1, 30, 6], ['BOX', 2, 40, 0], ['BWL', 1, 30, 6]], 150, 3], [128, 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 33', [[['LID', 5, 4, 0], ['CUP', 1, 10, 2], ['TRY', 0, 25, 5], ['BWL', 10, 30, 6]], 50, 3], [114, False]], ['generated mix 41', [[['BOX', 2, 40, 0]], 120, 2], [80, True]], ['generated mix 49', [[['BWL', 0, 30, 6], ['LID', 1, 4, 0], ['LID', 10, 4, 0], ['BWL', 10, 30, 6]], 120, 1], [128, False]]], [['generated mix 34', [[['BWL', 10, 30, 6], ['BOX', 1, 40, 0], ['TRY', 2, 25, 5], ['LID', 10, 4, 0], ['BOX', 10, 40, 0]], 100, 1], [594, False]], ['generated mix 23', [[['TRY', 2, 25, 5], ['CUP', 10, 10, 2], ['TRY', 0, 25, 5]], 150, 2], [58, 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 44', [[['CUP', 10, 10, 2]], 150, 1], [28, True]], ['generated mix 52', [[['CUP', 1, 10, 2]], 120, 3], [10, True]], ['generated mix 60', [[['LID', 1, 4, 0], ['BWL', 10, 30, 6]], 120, 2], [88, True]]]]
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 | [20, True] | [28, True] | Failed |
| capacity equal | [22, True] | [30, True] | Failed |
| merged lines nest together | [20, True] | [28, True] | Failed |
| non nesting | [80, True] | [80, True] | Passed |
| zero line | [2, True] | [10, True] | Failed |
| generated mix 7 | [10, True] | [30, True] | Failed |
| generated mix 15 | [96, True] | [128, True] | Failed |
| generated mix 23 | [30, True] | [58, True] | Failed |
SHA-256 / 40bda4df5484e8f15cbb9382eaf0cb5be54eb7129ca54800f8f018edbf1608df
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 * 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]], ['capacity equal', [[['CUP', 11, 10, 2]], 30, 1], [30, 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]], ['zero line', [[['CUP', 1, 10, 2], ['BOX', 0, 40, 0]], 30, 1], [10, 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 3', [[['CUP', 5, 10, 2], ['TRY', 0, 25, 5], ['LID', 0, 4, 0]], 100, 3], [18, True]], ['generated mix 2', [[['BWL', 2, 30, 6], ['LID', 0, 4, 0], ['BWL', 1, 30, 6]], 120, 3], [42, 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 11', [[['BWL', 1, 30, 6], ['LID', 2, 4, 0], ['LID', 0, 4, 0], ['LID', 5, 4, 0], ['BOX', 5, 40, 0]], 120, 3], [258, False]], ['generated mix 19', [[['BOX', 2, 40, 0], ['TRY', 0, 25, 5]], 80, 3], [80, True]], ['generated mix 27', [[['CUP', 2, 10, 2]], 100, 1], [12, True]]], [['generated mix 11', [[['BWL', 1, 30, 6], ['LID', 2, 4, 0], ['LID', 0, 4, 0], ['LID', 5, 4, 0], ['BOX', 5, 40, 0]], 120, 3], [258, False]], ['generated mix 7', [[['TRY', 2, 25, 5]], 120, 2], [30, 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 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]], ['generated mix 38', [[['BWL', 1, 30, 6], ['BOX', 2, 40, 0], ['LID', 5, 4, 0]], 120, 1], [130, False]]], [['generated mix 23', [[['TRY', 2, 25, 5], ['CUP', 10, 10, 2], ['TRY', 0, 25, 5]], 150, 2], [58, True]], ['generated mix 15', [[['CUP', 2, 10, 2], ['BWL', 1, 30, 6], ['BOX', 2, 40, 0], ['BWL', 1, 30, 6]], 150, 3], [128, 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 33', [[['LID', 5, 4, 0], ['CUP', 1, 10, 2], ['TRY', 0, 25, 5], ['BWL', 10, 30, 6]], 50, 3], [114, False]], ['generated mix 41', [[['BOX', 2, 40, 0]], 120, 2], [80, True]], ['generated mix 49', [[['BWL', 0, 30, 6], ['LID', 1, 4, 0], ['LID', 10, 4, 0], ['BWL', 10, 30, 6]], 120, 1], [128, False]]], [['generated mix 34', [[['BWL', 10, 30, 6], ['BOX', 1, 40, 0], ['TRY', 2, 25, 5], ['LID', 10, 4, 0], ['BOX', 10, 40, 0]], 100, 1], [594, False]], ['generated mix 23', [[['TRY', 2, 25, 5], ['CUP', 10, 10, 2], ['TRY', 0, 25, 5]], 150, 2], [58, 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 44', [[['CUP', 10, 10, 2]], 150, 1], [28, True]], ['generated mix 52', [[['CUP', 1, 10, 2]], 120, 3], [10, True]], ['generated mix 60', [[['LID', 1, 4, 0], ['BWL', 10, 30, 6]], 120, 2], [88, True]]]]
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 | [30, True] | [28, True] | Failed |
| capacity equal | [32, False] | [30, True] | Failed |
| merged lines nest together | [30, True] | [28, True] | Failed |
| non nesting | [80, True] | [80, True] | Passed |
| zero line | [12, True] | [10, True] | Failed |
| generated mix 7 | [35, True] | [30, True] | Failed |
| generated mix 15 | [136, True] | [128, True] | Failed |
| generated mix 23 | [65, True] | [58, True] | Failed |
SHA-256 / 8b9f4bc035aa13e50c720930b6a7f3cf2d4040ebad71ab5057a579827f181af2
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]], ['capacity equal', [[['CUP', 11, 10, 2]], 30, 1], [30, 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]], ['zero line', [[['CUP', 1, 10, 2], ['BOX', 0, 40, 0]], 30, 1], [10, 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 3', [[['CUP', 5, 10, 2], ['TRY', 0, 25, 5], ['LID', 0, 4, 0]], 100, 3], [18, True]], ['generated mix 2', [[['BWL', 2, 30, 6], ['LID', 0, 4, 0], ['BWL', 1, 30, 6]], 120, 3], [42, 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 11', [[['BWL', 1, 30, 6], ['LID', 2, 4, 0], ['LID', 0, 4, 0], ['LID', 5, 4, 0], ['BOX', 5, 40, 0]], 120, 3], [258, False]], ['generated mix 19', [[['BOX', 2, 40, 0], ['TRY', 0, 25, 5]], 80, 3], [80, True]], ['generated mix 27', [[['CUP', 2, 10, 2]], 100, 1], [12, True]]], [['generated mix 11', [[['BWL', 1, 30, 6], ['LID', 2, 4, 0], ['LID', 0, 4, 0], ['LID', 5, 4, 0], ['BOX', 5, 40, 0]], 120, 3], [258, False]], ['generated mix 7', [[['TRY', 2, 25, 5]], 120, 2], [30, 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 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]], ['generated mix 38', [[['BWL', 1, 30, 6], ['BOX', 2, 40, 0], ['LID', 5, 4, 0]], 120, 1], [130, False]]], [['generated mix 23', [[['TRY', 2, 25, 5], ['CUP', 10, 10, 2], ['TRY', 0, 25, 5]], 150, 2], [58, True]], ['generated mix 15', [[['CUP', 2, 10, 2], ['BWL', 1, 30, 6], ['BOX', 2, 40, 0], ['BWL', 1, 30, 6]], 150, 3], [128, 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 33', [[['LID', 5, 4, 0], ['CUP', 1, 10, 2], ['TRY', 0, 25, 5], ['BWL', 10, 30, 6]], 50, 3], [114, False]], ['generated mix 41', [[['BOX', 2, 40, 0]], 120, 2], [80, True]], ['generated mix 49', [[['BWL', 0, 30, 6], ['LID', 1, 4, 0], ['LID', 10, 4, 0], ['BWL', 10, 30, 6]], 120, 1], [128, False]]], [['generated mix 34', [[['BWL', 10, 30, 6], ['BOX', 1, 40, 0], ['TRY', 2, 25, 5], ['LID', 10, 4, 0], ['BOX', 10, 40, 0]], 100, 1], [594, False]], ['generated mix 23', [[['TRY', 2, 25, 5], ['CUP', 10, 10, 2], ['TRY', 0, 25, 5]], 150, 2], [58, 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 44', [[['CUP', 10, 10, 2]], 150, 1], [28, True]], ['generated mix 52', [[['CUP', 1, 10, 2]], 120, 3], [10, True]], ['generated mix 60', [[['LID', 1, 4, 0], ['BWL', 10, 30, 6]], 120, 2], [88, True]]]]
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 |
| capacity equal | [30, True] | [30, True] | Passed |
| merged lines nest together | [28, True] | [28, True] | Passed |
| non nesting | [80, True] | [80, True] | Passed |
| zero line | [10, True] | [10, 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 / ca198e9d586b0622c926aabbf12bf6f20977f1aefa66a6142ace6bf2d2899fd6
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.077831+00:00.
Case digest / abde21fdba06f7366423bd5630f7b576fd935cc3fc8a9e1918fa0ea55a404948