FA-95336 / Warehouse slotting and bin packing / Open access
Honeycombing: negative net quantity sized · case 01
A SKU whose adjustments net below zero produces phantom loss.
ROOT CAUSE
SKUs with non-positive net pallets are not skipped.
VERIFIED REPAIR
Skip SKUs whose net pallets are zero or negative.
Unsuccessful approach: Skipping only exactly zero still sizes negative nets.
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():
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 = [[['generated mix 1', [[['D', 1], ['A', 3], ['A', 1], ['A', -3], ['C', -3]], 4, 8], [2, 6, 2500, 'OK']], ['generated mix 3', [[['D', 9], ['D', 1], ['B', 5], ['A', -1], ['D', 2]], 2, 8], [9, 1, 9444, 'OVER']], ['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']], ['floor util', [[['A', 2]], 3, 1], [1, 1, 6666, 'OK']], ['lanes equal available', [[['A', 8]], 4, 2], [2, 0, 10000, 'OK']], ['generated mix 8', [[['C', 2], ['A', 8]], 3, 2], [4, 2, 8333, 'OVER']]], [['generated mix 26', [[['A', 9], ['C', 2], ['D', 2], ['B', -3], ['D', 5]], 5, 3], [5, 7, 7200, 'OVER']], ['generated mix 24', [[['A', 1], ['D', -3], ['B', 9]], 3, 8], [4, 2, 8333, '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 17', [[['C', 5], ['D', 1], ['B', 1]], 5, 4], [3, 8, 4666, 'OK']]], [['generated mix 41', [[['A', 8], ['B', -3], ['A', 9], ['C', 9], ['B', -3]], 3, 2], [9, 1, 9629, 'OVER']], ['generated mix 34', [[['B', 3], ['A', -3]], 3, 8], [1, 0, 10000, '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 28', [[['C', 9], ['A', -1], ['A', 1]], 5, 3], [2, 1, 9000, 'OK']]], [['generated mix 67', [[['D', -3]], 4, 8], [0, 0, 0, 'OK']], ['generated mix 48', [[['A', 8], ['C', -3]], 3, 8], [3, 1, 8888, '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 31', [[['C', 2], ['A', -3], ['D', 4]], 2, 4], [3, 0, 10000, 'OK']], ['generated mix 39', [[['D', 1], ['D', 1], ['B', 5]], 5, 2], [2, 3, 7000, 'OK']]], [['generated mix 1', [[['D', 1], ['A', 3], ['A', 1], ['A', -3], ['C', -3]], 4, 8], [2, 6, 2500, 'OK']], ['generated mix 67', [[['D', -3]], 4, 8], [0, 0, 0, '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 43', [[['B', -3]], 3, 6], [0, 0, 0, 'OK']], ['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 |
|---|---|---|---|
| generated mix 1 | [2, 9, -1250, 'OK'] | [2, 6, 2500, 'OK'] | Failed |
| generated mix 3 | [9, 2, 8888, 'OVER'] | [9, 1, 9444, 'OVER'] | Failed |
| mixed | [4, 3, 8125, 'OK'] | [4, 3, 8125, 'OK'] | Passed |
| merge lines | [2, 3, 6250, 'OK'] | [2, 3, 6250, 'OK'] | Passed |
| over | [3, 3, 7500, 'OVER'] | [3, 3, 7500, 'OVER'] | Passed |
| floor util | [1, 1, 6666, 'OK'] | [1, 1, 6666, 'OK'] | Passed |
| lanes equal available | [2, 0, 10000, 'OK'] | [2, 0, 10000, 'OK'] | Passed |
| generated mix 8 | [4, 2, 8333, 'OVER'] | [4, 2, 8333, 'OVER'] | Passed |
SHA-256 / 42eb04379b9e4b612516b03b2856ad43b073534edc410d54e7077349aff4e197
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 lanes > available else 'OK']
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['generated mix 1', [[['D', 1], ['A', 3], ['A', 1], ['A', -3], ['C', -3]], 4, 8], [2, 6, 2500, 'OK']], ['generated mix 3', [[['D', 9], ['D', 1], ['B', 5], ['A', -1], ['D', 2]], 2, 8], [9, 1, 9444, 'OVER']], ['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']], ['floor util', [[['A', 2]], 3, 1], [1, 1, 6666, 'OK']], ['lanes equal available', [[['A', 8]], 4, 2], [2, 0, 10000, 'OK']], ['generated mix 8', [[['C', 2], ['A', 8]], 3, 2], [4, 2, 8333, 'OVER']]], [['generated mix 26', [[['A', 9], ['C', 2], ['D', 2], ['B', -3], ['D', 5]], 5, 3], [5, 7, 7200, 'OVER']], ['generated mix 24', [[['A', 1], ['D', -3], ['B', 9]], 3, 8], [4, 2, 8333, '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 17', [[['C', 5], ['D', 1], ['B', 1]], 5, 4], [3, 8, 4666, 'OK']]], [['generated mix 41', [[['A', 8], ['B', -3], ['A', 9], ['C', 9], ['B', -3]], 3, 2], [9, 1, 9629, 'OVER']], ['generated mix 34', [[['B', 3], ['A', -3]], 3, 8], [1, 0, 10000, '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 28', [[['C', 9], ['A', -1], ['A', 1]], 5, 3], [2, 1, 9000, 'OK']]], [['generated mix 67', [[['D', -3]], 4, 8], [0, 0, 0, 'OK']], ['generated mix 48', [[['A', 8], ['C', -3]], 3, 8], [3, 1, 8888, '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 31', [[['C', 2], ['A', -3], ['D', 4]], 2, 4], [3, 0, 10000, 'OK']], ['generated mix 39', [[['D', 1], ['D', 1], ['B', 5]], 5, 2], [2, 3, 7000, 'OK']]], [['generated mix 1', [[['D', 1], ['A', 3], ['A', 1], ['A', -3], ['C', -3]], 4, 8], [2, 6, 2500, 'OK']], ['generated mix 67', [[['D', -3]], 4, 8], [0, 0, 0, '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 43', [[['B', -3]], 3, 6], [0, 0, 0, 'OK']], ['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 |
|---|---|---|---|
| generated mix 1 | [2, 9, -1250, 'OK'] | [2, 6, 2500, 'OK'] | Failed |
| generated mix 3 | [9, 2, 8888, 'OVER'] | [9, 1, 9444, 'OVER'] | Failed |
| mixed | [4, 3, 8125, 'OK'] | [4, 3, 8125, 'OK'] | Passed |
| merge lines | [2, 3, 6250, 'OK'] | [2, 3, 6250, 'OK'] | Passed |
| over | [3, 3, 7500, 'OVER'] | [3, 3, 7500, 'OVER'] | Passed |
| floor util | [1, 1, 6666, 'OK'] | [1, 1, 6666, 'OK'] | Passed |
| lanes equal available | [2, 0, 10000, 'OK'] | [2, 0, 10000, 'OK'] | Passed |
| generated mix 8 | [4, 2, 8333, 'OVER'] | [4, 2, 8333, 'OVER'] | Passed |
SHA-256 / 6857cc8636e6b37fa099adf20dae3e97037a9358ac7cfe8ad34790d19d1b2d93
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 = [[['generated mix 1', [[['D', 1], ['A', 3], ['A', 1], ['A', -3], ['C', -3]], 4, 8], [2, 6, 2500, 'OK']], ['generated mix 3', [[['D', 9], ['D', 1], ['B', 5], ['A', -1], ['D', 2]], 2, 8], [9, 1, 9444, 'OVER']], ['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']], ['floor util', [[['A', 2]], 3, 1], [1, 1, 6666, 'OK']], ['lanes equal available', [[['A', 8]], 4, 2], [2, 0, 10000, 'OK']], ['generated mix 8', [[['C', 2], ['A', 8]], 3, 2], [4, 2, 8333, 'OVER']]], [['generated mix 26', [[['A', 9], ['C', 2], ['D', 2], ['B', -3], ['D', 5]], 5, 3], [5, 7, 7200, 'OVER']], ['generated mix 24', [[['A', 1], ['D', -3], ['B', 9]], 3, 8], [4, 2, 8333, '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 17', [[['C', 5], ['D', 1], ['B', 1]], 5, 4], [3, 8, 4666, 'OK']]], [['generated mix 41', [[['A', 8], ['B', -3], ['A', 9], ['C', 9], ['B', -3]], 3, 2], [9, 1, 9629, 'OVER']], ['generated mix 34', [[['B', 3], ['A', -3]], 3, 8], [1, 0, 10000, '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 28', [[['C', 9], ['A', -1], ['A', 1]], 5, 3], [2, 1, 9000, 'OK']]], [['generated mix 67', [[['D', -3]], 4, 8], [0, 0, 0, 'OK']], ['generated mix 48', [[['A', 8], ['C', -3]], 3, 8], [3, 1, 8888, '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 31', [[['C', 2], ['A', -3], ['D', 4]], 2, 4], [3, 0, 10000, 'OK']], ['generated mix 39', [[['D', 1], ['D', 1], ['B', 5]], 5, 2], [2, 3, 7000, 'OK']]], [['generated mix 1', [[['D', 1], ['A', 3], ['A', 1], ['A', -3], ['C', -3]], 4, 8], [2, 6, 2500, 'OK']], ['generated mix 67', [[['D', -3]], 4, 8], [0, 0, 0, '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 43', [[['B', -3]], 3, 6], [0, 0, 0, 'OK']], ['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 |
|---|---|---|---|
| generated mix 1 | [2, 6, 2500, 'OK'] | [2, 6, 2500, 'OK'] | Passed |
| generated mix 3 | [9, 1, 9444, 'OVER'] | [9, 1, 9444, 'OVER'] | Passed |
| mixed | [4, 3, 8125, 'OK'] | [4, 3, 8125, 'OK'] | Passed |
| merge lines | [2, 3, 6250, 'OK'] | [2, 3, 6250, 'OK'] | Passed |
| over | [3, 3, 7500, 'OVER'] | [3, 3, 7500, 'OVER'] | Passed |
| floor util | [1, 1, 6666, 'OK'] | [1, 1, 6666, 'OK'] | Passed |
| lanes equal available | [2, 0, 10000, 'OK'] | [2, 0, 10000, 'OK'] | Passed |
| generated mix 8 | [4, 2, 8333, 'OVER'] | [4, 2, 8333, 'OVER'] | Passed |
SHA-256 / 49549d047bef9b6523441ac6d0befeb6e30d914d69beba3b7182bace7a3da90c
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.693110+00:00.
Case digest / 701eec1491d66709edd7d486f36c79f7963757ee5bc6480dd83dd1cac8fed45a