FA-95326 / Warehouse slotting and bin packing / Open access
Honeycombing: full use of lanes flagged over · case 01
Using exactly the available lanes is reported as over capacity.
ROOT CAUSE
The status check is inclusive at the available lane count.
VERIFIED REPAIR
Flag OVER only when lanes exceed availability.
Unsuccessful approach: Comparing pallet positions with the lane count mixes units.
Case contract
skus [[sku, pallets]] where lines may be adjustments (negative) and are netted per SKU. Each SKU with net pallets > 0 needs ceil(pallets/depth) single-SKU lanes. Honeycomb loss = lanes*depth - pallets. Utilization bp = floor((positions-loss)*10000/positions), 0 with no positions. Status OVER when lanes > available. Return [lanes, loss, util_bp, status].
Why this case matters
Deep-lane storage loses positions when lanes cannot be mixed across SKUs.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(skus, depth, available):
merged = {}
for sku, pallets in skus:
merged[sku] = merged.get(sku, 0) + pallets
lanes = 0
loss = 0
for sku, pallets in merged.items():
if pallets <= 0:
continue
n = -(-pallets // depth)
lanes += n
loss += n * depth - pallets
positions = lanes * depth
util = (positions - loss) * 10000 // positions if positions else 0
return [lanes, loss, util, 'OVER' if lanes >= available else 'OK']
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['lanes equal available', [[['A', 8]], 4, 2], [2, 0, 10000, 'OK']], ['mixed', [[['A', 5], ['B', 8]], 4, 10], [4, 3, 8125, 'OK']], ['adjustment nets out', [[['A', 3], ['A', -3], ['B', 1]], 4, 1], [1, 3, 2500, 'OK']], ['empty', [[], 4, 1], [0, 0, 0, 'OK']], ['merge lines', [[['A', 3], ['A', 2]], 4, 5], [2, 3, 6250, 'OK']], ['generated mix 6', [[['B', 8]], 4, 1], [2, 0, 10000, 'OVER']], ['generated mix 14', [[['C', 1], ['D', 8], ['C', 3]], 2, 1], [6, 0, 10000, 'OVER']], ['generated mix 22', [[['A', -1], ['B', 1], ['A', 9]], 4, 2], [3, 3, 7500, 'OVER']]], [['generated mix 51', [[['C', 4]], 4, 1], [1, 0, 10000, 'OK']], ['generated mix 10', [[['D', 8], ['A', 3], ['A', 1], ['A', 3]], 2, 8], [8, 1, 9375, 'OK']], ['adjustment nets out', [[['A', 3], ['A', -3], ['B', 1]], 4, 1], [1, 3, 2500, 'OK']], ['empty', [[], 4, 1], [0, 0, 0, 'OK']], ['mixed', [[['A', 5], ['B', 8]], 4, 10], [4, 3, 8125, 'OK']], ['merge lines', [[['A', 3], ['A', 2]], 4, 5], [2, 3, 6250, 'OK']], ['generated mix 9', [[['D', 8], ['D', -3], ['C', 1], ['A', 3], ['C', 8]], 3, 8], [6, 1, 9444, 'OK']], ['generated mix 18', [[['D', 4], ['C', 9], ['C', 9], ['B', 2], ['D', 1]], 3, 8], [9, 2, 9259, 'OVER']]], [['generated mix 75', [[['C', -1], ['B', 1], ['D', 5]], 5, 2], [2, 4, 6000, 'OK']], ['generated mix 25', [[['D', 3], ['A', 8], ['C', 5]], 5, 8], [4, 4, 8000, 'OK']], ['floor util', [[['A', 2]], 3, 1], [1, 1, 6666, 'OK']], ['lanes equal available', [[['A', 8]], 4, 2], [2, 0, 10000, 'OK']], ['adjustment nets out', [[['A', 3], ['A', -3], ['B', 1]], 4, 1], [1, 3, 2500, 'OK']], ['empty', [[], 4, 1], [0, 0, 0, 'OK']], ['generated mix 20', [[['A', 2], ['D', -1], ['C', 8], ['D', 2], ['B', 1]], 2, 2], [7, 2, 8571, 'OVER']], ['generated mix 29', [[['C', -1], ['C', -3], ['D', 1], ['D', -1], ['B', 5]], 3, 1], [2, 1, 8333, 'OVER']]], [['generated mix 30', [[['D', 8]], 5, 2], [2, 2, 8000, 'OK']], ['generated mix 33', [[['B', -1], ['C', 4]], 5, 4], [1, 1, 8000, 'OK']], ['merge lines', [[['A', 3], ['A', 2]], 4, 5], [2, 3, 6250, 'OK']], ['over', [[['A', 9]], 4, 2], [3, 3, 7500, 'OVER']], ['floor util', [[['A', 2]], 3, 1], [1, 1, 6666, 'OK']], ['lanes equal available', [[['A', 8]], 4, 2], [2, 0, 10000, 'OK']], ['generated mix 32', [[['B', 1], ['D', 9], ['D', 4], ['D', 2], ['D', 8]], 4, 3], [7, 4, 8571, 'OVER']], ['generated mix 41', [[['A', 8], ['B', -3], ['A', 9], ['C', 9], ['B', -3]], 3, 2], [9, 1, 9629, 'OVER']]], [['generated mix 70', [[['D', 3], ['A', -1], ['C', -3], ['A', 8]], 4, 3], [3, 2, 8333, 'OK']], ['generated mix 50', [[['D', 1], ['D', 3]], 4, 2], [1, 0, 10000, 'OK']], ['empty', [[], 4, 1], [0, 0, 0, 'OK']], ['mixed', [[['A', 5], ['B', 8]], 4, 10], [4, 3, 8125, 'OK']], ['merge lines', [[['A', 3], ['A', 2]], 4, 5], [2, 3, 6250, 'OK']], ['over', [[['A', 9]], 4, 2], [3, 3, 7500, 'OVER']], ['generated mix 42', [[['B', 4], ['D', 1], ['A', 9], ['D', 1], ['B', -3]], 4, 4], [5, 8, 6000, 'OVER']], ['generated mix 51', [[['C', 4]], 4, 1], [1, 0, 10000, 'OK']]]]
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 |
|---|---|---|---|
| lanes equal available | [2, 0, 10000, 'OVER'] | [2, 0, 10000, 'OK'] | Failed |
| mixed | [4, 3, 8125, 'OK'] | [4, 3, 8125, 'OK'] | Passed |
| adjustment nets out | [1, 3, 2500, 'OVER'] | [1, 3, 2500, 'OK'] | Failed |
| empty | [0, 0, 0, 'OK'] | [0, 0, 0, 'OK'] | Passed |
| merge lines | [2, 3, 6250, 'OK'] | [2, 3, 6250, 'OK'] | Passed |
| generated mix 6 | [2, 0, 10000, 'OVER'] | [2, 0, 10000, 'OVER'] | Passed |
| generated mix 14 | [6, 0, 10000, 'OVER'] | [6, 0, 10000, 'OVER'] | Passed |
| generated mix 22 | [3, 3, 7500, 'OVER'] | [3, 3, 7500, 'OVER'] | Passed |
SHA-256 / 7d08460bd78ed29dcfb29c7cface9d7e57f7fcdb77afce7a5d63becabe72b6b6
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(skus, depth, available):
merged = {}
for sku, pallets in skus:
merged[sku] = merged.get(sku, 0) + pallets
lanes = 0
loss = 0
for sku, pallets in merged.items():
if pallets <= 0:
continue
n = -(-pallets // depth)
lanes += n
loss += n * depth - pallets
positions = lanes * depth
util = (positions - loss) * 10000 // positions if positions else 0
return [lanes, loss, util, 'OVER' if positions > available else 'OK']
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['lanes equal available', [[['A', 8]], 4, 2], [2, 0, 10000, 'OK']], ['mixed', [[['A', 5], ['B', 8]], 4, 10], [4, 3, 8125, 'OK']], ['adjustment nets out', [[['A', 3], ['A', -3], ['B', 1]], 4, 1], [1, 3, 2500, 'OK']], ['empty', [[], 4, 1], [0, 0, 0, 'OK']], ['merge lines', [[['A', 3], ['A', 2]], 4, 5], [2, 3, 6250, 'OK']], ['generated mix 6', [[['B', 8]], 4, 1], [2, 0, 10000, 'OVER']], ['generated mix 14', [[['C', 1], ['D', 8], ['C', 3]], 2, 1], [6, 0, 10000, 'OVER']], ['generated mix 22', [[['A', -1], ['B', 1], ['A', 9]], 4, 2], [3, 3, 7500, 'OVER']]], [['generated mix 51', [[['C', 4]], 4, 1], [1, 0, 10000, 'OK']], ['generated mix 10', [[['D', 8], ['A', 3], ['A', 1], ['A', 3]], 2, 8], [8, 1, 9375, 'OK']], ['adjustment nets out', [[['A', 3], ['A', -3], ['B', 1]], 4, 1], [1, 3, 2500, 'OK']], ['empty', [[], 4, 1], [0, 0, 0, 'OK']], ['mixed', [[['A', 5], ['B', 8]], 4, 10], [4, 3, 8125, 'OK']], ['merge lines', [[['A', 3], ['A', 2]], 4, 5], [2, 3, 6250, 'OK']], ['generated mix 9', [[['D', 8], ['D', -3], ['C', 1], ['A', 3], ['C', 8]], 3, 8], [6, 1, 9444, 'OK']], ['generated mix 18', [[['D', 4], ['C', 9], ['C', 9], ['B', 2], ['D', 1]], 3, 8], [9, 2, 9259, 'OVER']]], [['generated mix 75', [[['C', -1], ['B', 1], ['D', 5]], 5, 2], [2, 4, 6000, 'OK']], ['generated mix 25', [[['D', 3], ['A', 8], ['C', 5]], 5, 8], [4, 4, 8000, 'OK']], ['floor util', [[['A', 2]], 3, 1], [1, 1, 6666, 'OK']], ['lanes equal available', [[['A', 8]], 4, 2], [2, 0, 10000, 'OK']], ['adjustment nets out', [[['A', 3], ['A', -3], ['B', 1]], 4, 1], [1, 3, 2500, 'OK']], ['empty', [[], 4, 1], [0, 0, 0, 'OK']], ['generated mix 20', [[['A', 2], ['D', -1], ['C', 8], ['D', 2], ['B', 1]], 2, 2], [7, 2, 8571, 'OVER']], ['generated mix 29', [[['C', -1], ['C', -3], ['D', 1], ['D', -1], ['B', 5]], 3, 1], [2, 1, 8333, 'OVER']]], [['generated mix 30', [[['D', 8]], 5, 2], [2, 2, 8000, 'OK']], ['generated mix 33', [[['B', -1], ['C', 4]], 5, 4], [1, 1, 8000, 'OK']], ['merge lines', [[['A', 3], ['A', 2]], 4, 5], [2, 3, 6250, 'OK']], ['over', [[['A', 9]], 4, 2], [3, 3, 7500, 'OVER']], ['floor util', [[['A', 2]], 3, 1], [1, 1, 6666, 'OK']], ['lanes equal available', [[['A', 8]], 4, 2], [2, 0, 10000, 'OK']], ['generated mix 32', [[['B', 1], ['D', 9], ['D', 4], ['D', 2], ['D', 8]], 4, 3], [7, 4, 8571, 'OVER']], ['generated mix 41', [[['A', 8], ['B', -3], ['A', 9], ['C', 9], ['B', -3]], 3, 2], [9, 1, 9629, 'OVER']]], [['generated mix 70', [[['D', 3], ['A', -1], ['C', -3], ['A', 8]], 4, 3], [3, 2, 8333, 'OK']], ['generated mix 50', [[['D', 1], ['D', 3]], 4, 2], [1, 0, 10000, 'OK']], ['empty', [[], 4, 1], [0, 0, 0, 'OK']], ['mixed', [[['A', 5], ['B', 8]], 4, 10], [4, 3, 8125, 'OK']], ['merge lines', [[['A', 3], ['A', 2]], 4, 5], [2, 3, 6250, 'OK']], ['over', [[['A', 9]], 4, 2], [3, 3, 7500, 'OVER']], ['generated mix 42', [[['B', 4], ['D', 1], ['A', 9], ['D', 1], ['B', -3]], 4, 4], [5, 8, 6000, 'OVER']], ['generated mix 51', [[['C', 4]], 4, 1], [1, 0, 10000, 'OK']]]]
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 |
|---|---|---|---|
| lanes equal available | [2, 0, 10000, 'OVER'] | [2, 0, 10000, 'OK'] | Failed |
| mixed | [4, 3, 8125, 'OVER'] | [4, 3, 8125, 'OK'] | Failed |
| adjustment nets out | [1, 3, 2500, 'OVER'] | [1, 3, 2500, 'OK'] | Failed |
| empty | [0, 0, 0, 'OK'] | [0, 0, 0, 'OK'] | Passed |
| merge lines | [2, 3, 6250, 'OVER'] | [2, 3, 6250, 'OK'] | Failed |
| generated mix 6 | [2, 0, 10000, 'OVER'] | [2, 0, 10000, 'OVER'] | Passed |
| generated mix 14 | [6, 0, 10000, 'OVER'] | [6, 0, 10000, 'OVER'] | Passed |
| generated mix 22 | [3, 3, 7500, 'OVER'] | [3, 3, 7500, 'OVER'] | Passed |
SHA-256 / 7160657f7aab4a0209e4fc3c8ea9ebae4bf22f9fb0521a84f22cd895bbccb94c
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(skus, depth, available):
merged = {}
for sku, pallets in skus:
merged[sku] = merged.get(sku, 0) + pallets
lanes = 0
loss = 0
for sku, pallets in merged.items():
if pallets <= 0:
continue
n = -(-pallets // depth)
lanes += n
loss += n * depth - pallets
positions = lanes * depth
util = (positions - loss) * 10000 // positions if positions else 0
return [lanes, loss, util, 'OVER' if lanes > available else 'OK']
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['lanes equal available', [[['A', 8]], 4, 2], [2, 0, 10000, 'OK']], ['mixed', [[['A', 5], ['B', 8]], 4, 10], [4, 3, 8125, 'OK']], ['adjustment nets out', [[['A', 3], ['A', -3], ['B', 1]], 4, 1], [1, 3, 2500, 'OK']], ['empty', [[], 4, 1], [0, 0, 0, 'OK']], ['merge lines', [[['A', 3], ['A', 2]], 4, 5], [2, 3, 6250, 'OK']], ['generated mix 6', [[['B', 8]], 4, 1], [2, 0, 10000, 'OVER']], ['generated mix 14', [[['C', 1], ['D', 8], ['C', 3]], 2, 1], [6, 0, 10000, 'OVER']], ['generated mix 22', [[['A', -1], ['B', 1], ['A', 9]], 4, 2], [3, 3, 7500, 'OVER']]], [['generated mix 51', [[['C', 4]], 4, 1], [1, 0, 10000, 'OK']], ['generated mix 10', [[['D', 8], ['A', 3], ['A', 1], ['A', 3]], 2, 8], [8, 1, 9375, 'OK']], ['adjustment nets out', [[['A', 3], ['A', -3], ['B', 1]], 4, 1], [1, 3, 2500, 'OK']], ['empty', [[], 4, 1], [0, 0, 0, 'OK']], ['mixed', [[['A', 5], ['B', 8]], 4, 10], [4, 3, 8125, 'OK']], ['merge lines', [[['A', 3], ['A', 2]], 4, 5], [2, 3, 6250, 'OK']], ['generated mix 9', [[['D', 8], ['D', -3], ['C', 1], ['A', 3], ['C', 8]], 3, 8], [6, 1, 9444, 'OK']], ['generated mix 18', [[['D', 4], ['C', 9], ['C', 9], ['B', 2], ['D', 1]], 3, 8], [9, 2, 9259, 'OVER']]], [['generated mix 75', [[['C', -1], ['B', 1], ['D', 5]], 5, 2], [2, 4, 6000, 'OK']], ['generated mix 25', [[['D', 3], ['A', 8], ['C', 5]], 5, 8], [4, 4, 8000, 'OK']], ['floor util', [[['A', 2]], 3, 1], [1, 1, 6666, 'OK']], ['lanes equal available', [[['A', 8]], 4, 2], [2, 0, 10000, 'OK']], ['adjustment nets out', [[['A', 3], ['A', -3], ['B', 1]], 4, 1], [1, 3, 2500, 'OK']], ['empty', [[], 4, 1], [0, 0, 0, 'OK']], ['generated mix 20', [[['A', 2], ['D', -1], ['C', 8], ['D', 2], ['B', 1]], 2, 2], [7, 2, 8571, 'OVER']], ['generated mix 29', [[['C', -1], ['C', -3], ['D', 1], ['D', -1], ['B', 5]], 3, 1], [2, 1, 8333, 'OVER']]], [['generated mix 30', [[['D', 8]], 5, 2], [2, 2, 8000, 'OK']], ['generated mix 33', [[['B', -1], ['C', 4]], 5, 4], [1, 1, 8000, 'OK']], ['merge lines', [[['A', 3], ['A', 2]], 4, 5], [2, 3, 6250, 'OK']], ['over', [[['A', 9]], 4, 2], [3, 3, 7500, 'OVER']], ['floor util', [[['A', 2]], 3, 1], [1, 1, 6666, 'OK']], ['lanes equal available', [[['A', 8]], 4, 2], [2, 0, 10000, 'OK']], ['generated mix 32', [[['B', 1], ['D', 9], ['D', 4], ['D', 2], ['D', 8]], 4, 3], [7, 4, 8571, 'OVER']], ['generated mix 41', [[['A', 8], ['B', -3], ['A', 9], ['C', 9], ['B', -3]], 3, 2], [9, 1, 9629, 'OVER']]], [['generated mix 70', [[['D', 3], ['A', -1], ['C', -3], ['A', 8]], 4, 3], [3, 2, 8333, 'OK']], ['generated mix 50', [[['D', 1], ['D', 3]], 4, 2], [1, 0, 10000, 'OK']], ['empty', [[], 4, 1], [0, 0, 0, 'OK']], ['mixed', [[['A', 5], ['B', 8]], 4, 10], [4, 3, 8125, 'OK']], ['merge lines', [[['A', 3], ['A', 2]], 4, 5], [2, 3, 6250, 'OK']], ['over', [[['A', 9]], 4, 2], [3, 3, 7500, 'OVER']], ['generated mix 42', [[['B', 4], ['D', 1], ['A', 9], ['D', 1], ['B', -3]], 4, 4], [5, 8, 6000, 'OVER']], ['generated mix 51', [[['C', 4]], 4, 1], [1, 0, 10000, 'OK']]]]
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 |
|---|---|---|---|
| lanes equal available | [2, 0, 10000, 'OK'] | [2, 0, 10000, 'OK'] | Passed |
| mixed | [4, 3, 8125, 'OK'] | [4, 3, 8125, 'OK'] | Passed |
| adjustment nets out | [1, 3, 2500, 'OK'] | [1, 3, 2500, 'OK'] | Passed |
| empty | [0, 0, 0, 'OK'] | [0, 0, 0, 'OK'] | Passed |
| merge lines | [2, 3, 6250, 'OK'] | [2, 3, 6250, 'OK'] | Passed |
| generated mix 6 | [2, 0, 10000, 'OVER'] | [2, 0, 10000, 'OVER'] | Passed |
| generated mix 14 | [6, 0, 10000, 'OVER'] | [6, 0, 10000, 'OVER'] | Passed |
| generated mix 22 | [3, 3, 7500, 'OVER'] | [3, 3, 7500, 'OVER'] | Passed |
SHA-256 / 0de6428f2a555ef0a00a0f840163361cd977a449c5c0dc912ce55af7b9dda166
Verification & scope
Stipulated single-SKU lane policy. 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:12.651011+00:00.
Case digest / cdb653e38c9e8507e91e8ca803c074d63e2072447a2b659ad1d7897043232858