FAILURE MAP
← Case archive

FA-95006 / Warehouse slotting and bin packing / Open access

Pallet build: weight limit not applied · case 01

Dense cases are stacked to the height limit and the pallet exceeds its gross weight rating.

Verified by executionVariant 1 · 8 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The case count only considers the layer limit and never the weight bound.

VERIFIED REPAIR

Take the minimum of the height-limited and weight-limited case counts.

Unsuccessful approach: Rounding the weight bound down to full layers discards a legal partial top layer.

Case contract

case [l, w, h, kg], pallet [L, W]; cases stay upright but may rotate 90 degrees; all layers share one orientation. Pallet base adds 15 height and 25 kg tare. Cases per pallet are bounded by whole layers within max_h and by max_kg (a partial top layer is allowed). Return [per_layer, layers used, cases, height, weight].

Why this case matters

Pallet build limits govern reserve storage heights and floor loading.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(case, pallet, max_h, max_kg):
    l, w, h, kg = case
    L, W = pallet
    per_layer = max((L // l) * (W // w), (L // w) * (W // l))
    if per_layer == 0:
        return [0, 0, 0, 15, 25]
    layers = (max_h - 15) // h
    by_weight = (max_kg - 25) // kg
    cases = per_layer * layers
    if cases <= 0:
        return [per_layer, 0, 0, 15, 25]
    full = -(-cases // per_layer)
    return [per_layer, full, cases, 15 + full * h, 25 + cases * kg]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['weight bound partial layer', [[40, 30, 25, 20], [120, 100], 190, 425], [9, 3, 20, 90, 425]], ['generated mix 1', [[50, 15, 10, 12], [120, 100], 190, 1025], [16, 6, 83, 75, 1021]], ['listed orientation wins', [[30, 20, 20, 5], [120, 100], 115, 1000], [20, 5, 100, 115, 525]], ['height exact', [[40, 30, 25, 2], [120, 100], 140, 2000], [9, 5, 45, 140, 115]], ['too heavy for one', [[40, 30, 25, 500], [120, 100], 190, 425], [9, 0, 0, 15, 25]], ['rotation wins', [[50, 30, 20, 5], [120, 100], 115, 1000], [8, 5, 40, 115, 225]], ['generated mix 7', [[40, 30, 20, 5], [120, 80], 140, 1025], [8, 6, 48, 135, 265]], ['generated mix 15', [[50, 20, 30, 8], [120, 80], 115, 800], [8, 3, 24, 105, 217]]], [['generated mix 20', [[20, 20, 25, 20], [120, 100], 115, 1200], [30, 2, 58, 65, 1185]], ['weight bound partial layer', [[40, 30, 25, 20], [120, 100], 190, 425], [9, 3, 20, 90, 425]], ['too heavy for one', [[40, 30, 25, 500], [120, 100], 190, 425], [9, 0, 0, 15, 25]], ['listed orientation wins', [[30, 20, 20, 5], [120, 100], 115, 1000], [20, 5, 100, 115, 525]], ['height exact', [[40, 30, 25, 2], [120, 100], 140, 2000], [9, 5, 45, 140, 115]], ['generated mix 9', [[50, 20, 25, 12], [120, 100], 115, 1200], [12, 4, 48, 115, 601]], ['generated mix 17', [[30, 30, 30, 8], [120, 80], 165, 500], [8, 5, 40, 165, 345]], ['generated mix 26', [[25, 30, 25, 12], [120, 80], 140, 1200], [12, 5, 60, 140, 745]]], [['generated mix 34', [[25, 15, 20, 5], [120, 100], 115, 300], [32, 2, 55, 55, 300]], ['generated mix 33', [[40, 30, 10, 20], [120, 80], 165, 800], [8, 5, 38, 65, 785]], ['square', [[25, 25, 30, 5], [120, 80], 165, 900], [12, 5, 60, 165, 325]], ['rotation wins', [[50, 30, 20, 5], [120, 100], 115, 1000], [8, 5, 40, 115, 225]], ['weight bound partial layer', [[40, 30, 25, 20], [120, 100], 190, 425], [9, 3, 20, 90, 425]], ['too heavy for one', [[40, 30, 25, 500], [120, 100], 190, 425], [9, 0, 0, 15, 25]], ['generated mix 20', [[20, 20, 25, 20], [120, 100], 115, 1200], [30, 2, 58, 65, 1185]], ['generated mix 28', [[20, 30, 20, 12], [120, 80], 140, 800], [16, 4, 64, 95, 793]]], [['generated mix 42', [[40, 30, 20, 5], [120, 80], 165, 300], [8, 7, 55, 155, 300]], ['generated mix 38', [[40, 15, 10, 20], [120, 80], 115, 1200], [16, 4, 58, 55, 1185]], ['height exact', [[40, 30, 25, 2], [120, 100], 140, 2000], [9, 5, 45, 140, 115]], ['too big', [[130, 30, 25, 2], [120, 100], 190, 425], [0, 0, 0, 15, 25]], ['square', [[25, 25, 30, 5], [120, 80], 165, 900], [12, 5, 60, 165, 325]], ['rotation wins', [[50, 30, 20, 5], [120, 100], 115, 1000], [8, 5, 40, 115, 225]], ['generated mix 31', [[40, 15, 25, 5], [120, 100], 190, 1025], [18, 7, 126, 190, 655]], ['generated mix 40', [[20, 15, 30, 20], [120, 80], 190, 500], [32, 1, 23, 45, 485]]], [['generated mix 57', [[30, 15, 10, 8], [120, 80], 115, 500], [20, 3, 59, 45, 497]], ['generated mix 44', [[30, 30, 10, 5], [120, 80], 140, 500], [8, 12, 95, 135, 500]], ['too heavy for one', [[40, 30, 25, 500], [120, 100], 190, 425], [9, 0, 0, 15, 25]], ['listed orientation wins', [[30, 20, 20, 5], [120, 100], 115, 1000], [20, 5, 100, 115, 525]], ['height exact', [[40, 30, 25, 2], [120, 100], 140, 2000], [9, 5, 45, 140, 115]], ['too big', [[130, 30, 25, 2], [120, 100], 190, 425], [0, 0, 0, 15, 25]], ['generated mix 42', [[40, 30, 20, 5], [120, 80], 165, 300], [8, 7, 55, 155, 300]], ['generated mix 51', [[25, 15, 10, 8], [120, 80], 165, 500], [24, 3, 59, 45, 497]]]]
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 fixtureActualExpectedOutcome
weight bound partial layer[9, 7, 63, 190, 1285][9, 3, 20, 90, 425]Failed
generated mix 1[16, 17, 272, 185, 3289][16, 6, 83, 75, 1021]Failed
listed orientation wins[20, 5, 100, 115, 525][20, 5, 100, 115, 525]Passed
height exact[9, 5, 45, 140, 115][9, 5, 45, 140, 115]Passed
too heavy for one[9, 7, 63, 190, 31525][9, 0, 0, 15, 25]Failed
rotation wins[8, 5, 40, 115, 225][8, 5, 40, 115, 225]Passed
generated mix 7[8, 6, 48, 135, 265][8, 6, 48, 135, 265]Passed
generated mix 15[8, 3, 24, 105, 217][8, 3, 24, 105, 217]Passed

SHA-256 / 5aa2f9013467884b5528e91367fedad885fc5e62e5eff8c54b30296d6167ba88

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(case, pallet, max_h, max_kg):
    l, w, h, kg = case
    L, W = pallet
    per_layer = max((L // l) * (W // w), (L // w) * (W // l))
    if per_layer == 0:
        return [0, 0, 0, 15, 25]
    layers = (max_h - 15) // h
    by_weight = (max_kg - 25) // kg
    cases = min(per_layer * layers, by_weight // per_layer * per_layer)
    if cases <= 0:
        return [per_layer, 0, 0, 15, 25]
    full = -(-cases // per_layer)
    return [per_layer, full, cases, 15 + full * h, 25 + cases * kg]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['weight bound partial layer', [[40, 30, 25, 20], [120, 100], 190, 425], [9, 3, 20, 90, 425]], ['generated mix 1', [[50, 15, 10, 12], [120, 100], 190, 1025], [16, 6, 83, 75, 1021]], ['listed orientation wins', [[30, 20, 20, 5], [120, 100], 115, 1000], [20, 5, 100, 115, 525]], ['height exact', [[40, 30, 25, 2], [120, 100], 140, 2000], [9, 5, 45, 140, 115]], ['too heavy for one', [[40, 30, 25, 500], [120, 100], 190, 425], [9, 0, 0, 15, 25]], ['rotation wins', [[50, 30, 20, 5], [120, 100], 115, 1000], [8, 5, 40, 115, 225]], ['generated mix 7', [[40, 30, 20, 5], [120, 80], 140, 1025], [8, 6, 48, 135, 265]], ['generated mix 15', [[50, 20, 30, 8], [120, 80], 115, 800], [8, 3, 24, 105, 217]]], [['generated mix 20', [[20, 20, 25, 20], [120, 100], 115, 1200], [30, 2, 58, 65, 1185]], ['weight bound partial layer', [[40, 30, 25, 20], [120, 100], 190, 425], [9, 3, 20, 90, 425]], ['too heavy for one', [[40, 30, 25, 500], [120, 100], 190, 425], [9, 0, 0, 15, 25]], ['listed orientation wins', [[30, 20, 20, 5], [120, 100], 115, 1000], [20, 5, 100, 115, 525]], ['height exact', [[40, 30, 25, 2], [120, 100], 140, 2000], [9, 5, 45, 140, 115]], ['generated mix 9', [[50, 20, 25, 12], [120, 100], 115, 1200], [12, 4, 48, 115, 601]], ['generated mix 17', [[30, 30, 30, 8], [120, 80], 165, 500], [8, 5, 40, 165, 345]], ['generated mix 26', [[25, 30, 25, 12], [120, 80], 140, 1200], [12, 5, 60, 140, 745]]], [['generated mix 34', [[25, 15, 20, 5], [120, 100], 115, 300], [32, 2, 55, 55, 300]], ['generated mix 33', [[40, 30, 10, 20], [120, 80], 165, 800], [8, 5, 38, 65, 785]], ['square', [[25, 25, 30, 5], [120, 80], 165, 900], [12, 5, 60, 165, 325]], ['rotation wins', [[50, 30, 20, 5], [120, 100], 115, 1000], [8, 5, 40, 115, 225]], ['weight bound partial layer', [[40, 30, 25, 20], [120, 100], 190, 425], [9, 3, 20, 90, 425]], ['too heavy for one', [[40, 30, 25, 500], [120, 100], 190, 425], [9, 0, 0, 15, 25]], ['generated mix 20', [[20, 20, 25, 20], [120, 100], 115, 1200], [30, 2, 58, 65, 1185]], ['generated mix 28', [[20, 30, 20, 12], [120, 80], 140, 800], [16, 4, 64, 95, 793]]], [['generated mix 42', [[40, 30, 20, 5], [120, 80], 165, 300], [8, 7, 55, 155, 300]], ['generated mix 38', [[40, 15, 10, 20], [120, 80], 115, 1200], [16, 4, 58, 55, 1185]], ['height exact', [[40, 30, 25, 2], [120, 100], 140, 2000], [9, 5, 45, 140, 115]], ['too big', [[130, 30, 25, 2], [120, 100], 190, 425], [0, 0, 0, 15, 25]], ['square', [[25, 25, 30, 5], [120, 80], 165, 900], [12, 5, 60, 165, 325]], ['rotation wins', [[50, 30, 20, 5], [120, 100], 115, 1000], [8, 5, 40, 115, 225]], ['generated mix 31', [[40, 15, 25, 5], [120, 100], 190, 1025], [18, 7, 126, 190, 655]], ['generated mix 40', [[20, 15, 30, 20], [120, 80], 190, 500], [32, 1, 23, 45, 485]]], [['generated mix 57', [[30, 15, 10, 8], [120, 80], 115, 500], [20, 3, 59, 45, 497]], ['generated mix 44', [[30, 30, 10, 5], [120, 80], 140, 500], [8, 12, 95, 135, 500]], ['too heavy for one', [[40, 30, 25, 500], [120, 100], 190, 425], [9, 0, 0, 15, 25]], ['listed orientation wins', [[30, 20, 20, 5], [120, 100], 115, 1000], [20, 5, 100, 115, 525]], ['height exact', [[40, 30, 25, 2], [120, 100], 140, 2000], [9, 5, 45, 140, 115]], ['too big', [[130, 30, 25, 2], [120, 100], 190, 425], [0, 0, 0, 15, 25]], ['generated mix 42', [[40, 30, 20, 5], [120, 80], 165, 300], [8, 7, 55, 155, 300]], ['generated mix 51', [[25, 15, 10, 8], [120, 80], 165, 500], [24, 3, 59, 45, 497]]]]
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 fixtureActualExpectedOutcome
weight bound partial layer[9, 2, 18, 65, 385][9, 3, 20, 90, 425]Failed
generated mix 1[16, 5, 80, 65, 985][16, 6, 83, 75, 1021]Failed
listed orientation wins[20, 5, 100, 115, 525][20, 5, 100, 115, 525]Passed
height exact[9, 5, 45, 140, 115][9, 5, 45, 140, 115]Passed
too heavy for one[9, 0, 0, 15, 25][9, 0, 0, 15, 25]Passed
rotation wins[8, 5, 40, 115, 225][8, 5, 40, 115, 225]Passed
generated mix 7[8, 6, 48, 135, 265][8, 6, 48, 135, 265]Passed
generated mix 15[8, 3, 24, 105, 217][8, 3, 24, 105, 217]Passed

SHA-256 / ba5686298e66049acfca27c99227e6e48fa57e9c9263dcd3a9f3b38eb697d41e

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(case, pallet, max_h, max_kg):
    l, w, h, kg = case
    L, W = pallet
    per_layer = max((L // l) * (W // w), (L // w) * (W // l))
    if per_layer == 0:
        return [0, 0, 0, 15, 25]
    layers = (max_h - 15) // h
    by_weight = (max_kg - 25) // kg
    cases = min(per_layer * layers, by_weight)
    if cases <= 0:
        return [per_layer, 0, 0, 15, 25]
    full = -(-cases // per_layer)
    return [per_layer, full, cases, 15 + full * h, 25 + cases * kg]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['weight bound partial layer', [[40, 30, 25, 20], [120, 100], 190, 425], [9, 3, 20, 90, 425]], ['generated mix 1', [[50, 15, 10, 12], [120, 100], 190, 1025], [16, 6, 83, 75, 1021]], ['listed orientation wins', [[30, 20, 20, 5], [120, 100], 115, 1000], [20, 5, 100, 115, 525]], ['height exact', [[40, 30, 25, 2], [120, 100], 140, 2000], [9, 5, 45, 140, 115]], ['too heavy for one', [[40, 30, 25, 500], [120, 100], 190, 425], [9, 0, 0, 15, 25]], ['rotation wins', [[50, 30, 20, 5], [120, 100], 115, 1000], [8, 5, 40, 115, 225]], ['generated mix 7', [[40, 30, 20, 5], [120, 80], 140, 1025], [8, 6, 48, 135, 265]], ['generated mix 15', [[50, 20, 30, 8], [120, 80], 115, 800], [8, 3, 24, 105, 217]]], [['generated mix 20', [[20, 20, 25, 20], [120, 100], 115, 1200], [30, 2, 58, 65, 1185]], ['weight bound partial layer', [[40, 30, 25, 20], [120, 100], 190, 425], [9, 3, 20, 90, 425]], ['too heavy for one', [[40, 30, 25, 500], [120, 100], 190, 425], [9, 0, 0, 15, 25]], ['listed orientation wins', [[30, 20, 20, 5], [120, 100], 115, 1000], [20, 5, 100, 115, 525]], ['height exact', [[40, 30, 25, 2], [120, 100], 140, 2000], [9, 5, 45, 140, 115]], ['generated mix 9', [[50, 20, 25, 12], [120, 100], 115, 1200], [12, 4, 48, 115, 601]], ['generated mix 17', [[30, 30, 30, 8], [120, 80], 165, 500], [8, 5, 40, 165, 345]], ['generated mix 26', [[25, 30, 25, 12], [120, 80], 140, 1200], [12, 5, 60, 140, 745]]], [['generated mix 34', [[25, 15, 20, 5], [120, 100], 115, 300], [32, 2, 55, 55, 300]], ['generated mix 33', [[40, 30, 10, 20], [120, 80], 165, 800], [8, 5, 38, 65, 785]], ['square', [[25, 25, 30, 5], [120, 80], 165, 900], [12, 5, 60, 165, 325]], ['rotation wins', [[50, 30, 20, 5], [120, 100], 115, 1000], [8, 5, 40, 115, 225]], ['weight bound partial layer', [[40, 30, 25, 20], [120, 100], 190, 425], [9, 3, 20, 90, 425]], ['too heavy for one', [[40, 30, 25, 500], [120, 100], 190, 425], [9, 0, 0, 15, 25]], ['generated mix 20', [[20, 20, 25, 20], [120, 100], 115, 1200], [30, 2, 58, 65, 1185]], ['generated mix 28', [[20, 30, 20, 12], [120, 80], 140, 800], [16, 4, 64, 95, 793]]], [['generated mix 42', [[40, 30, 20, 5], [120, 80], 165, 300], [8, 7, 55, 155, 300]], ['generated mix 38', [[40, 15, 10, 20], [120, 80], 115, 1200], [16, 4, 58, 55, 1185]], ['height exact', [[40, 30, 25, 2], [120, 100], 140, 2000], [9, 5, 45, 140, 115]], ['too big', [[130, 30, 25, 2], [120, 100], 190, 425], [0, 0, 0, 15, 25]], ['square', [[25, 25, 30, 5], [120, 80], 165, 900], [12, 5, 60, 165, 325]], ['rotation wins', [[50, 30, 20, 5], [120, 100], 115, 1000], [8, 5, 40, 115, 225]], ['generated mix 31', [[40, 15, 25, 5], [120, 100], 190, 1025], [18, 7, 126, 190, 655]], ['generated mix 40', [[20, 15, 30, 20], [120, 80], 190, 500], [32, 1, 23, 45, 485]]], [['generated mix 57', [[30, 15, 10, 8], [120, 80], 115, 500], [20, 3, 59, 45, 497]], ['generated mix 44', [[30, 30, 10, 5], [120, 80], 140, 500], [8, 12, 95, 135, 500]], ['too heavy for one', [[40, 30, 25, 500], [120, 100], 190, 425], [9, 0, 0, 15, 25]], ['listed orientation wins', [[30, 20, 20, 5], [120, 100], 115, 1000], [20, 5, 100, 115, 525]], ['height exact', [[40, 30, 25, 2], [120, 100], 140, 2000], [9, 5, 45, 140, 115]], ['too big', [[130, 30, 25, 2], [120, 100], 190, 425], [0, 0, 0, 15, 25]], ['generated mix 42', [[40, 30, 20, 5], [120, 80], 165, 300], [8, 7, 55, 155, 300]], ['generated mix 51', [[25, 15, 10, 8], [120, 80], 165, 500], [24, 3, 59, 45, 497]]]]
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 fixtureActualExpectedOutcome
weight bound partial layer[9, 3, 20, 90, 425][9, 3, 20, 90, 425]Passed
generated mix 1[16, 6, 83, 75, 1021][16, 6, 83, 75, 1021]Passed
listed orientation wins[20, 5, 100, 115, 525][20, 5, 100, 115, 525]Passed
height exact[9, 5, 45, 140, 115][9, 5, 45, 140, 115]Passed
too heavy for one[9, 0, 0, 15, 25][9, 0, 0, 15, 25]Passed
rotation wins[8, 5, 40, 115, 225][8, 5, 40, 115, 225]Passed
generated mix 7[8, 6, 48, 135, 265][8, 6, 48, 135, 265]Passed
generated mix 15[8, 3, 24, 105, 217][8, 3, 24, 105, 217]Passed

SHA-256 / d0c4b8dfb0317f795234911bf0ea2fabfc02fbfcc022a3b08a272a679e258cca

Verification & scope

Uniform-case, single-orientation layer model; no interlocking patterns. 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:09.791086+00:00.

Case digest / d745a906f3d48279ca071da660154e4c215f5dabd0e6a9792c5a9739845a6971