FAILURE MAP
← Case archive

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

Hazmat audit: violation pairs not canonical · case 01

The same violation appears in either orientation and the report is not stably ordered.

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

ROOT CAUSE

Pairs are recorded in placement order instead of sorted SKU order.

VERIFIED REPAIR

Record each pair as (lower sku, higher sku) and sort the report.

Unsuccessful approach: Ordering the report by the second SKU first leaves the list out of lexical order.

Case contract

placements [[sku, hazard class, aisle, bay]]; rules [[class_a, class_b, min_bay_gap]] apply in either order within the same aisle. A rule class matches a hazard class equal to it or a division of it ("4" matches "4.1"). A pair violates when |bay difference| < min_gap. Different SKUs only. Return sorted unique [sku_low, sku_high] pairs.

Why this case matters

Dangerous goods storage requires separation between incompatible hazard classes.

1 / The failure

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

N = 1
observations = []
def solve(placements, rules):
    def matches(cls, rule):
        return cls == rule or cls.startswith(rule + '.')
    found = set()
    n = len(placements)
    for i in range(n):
        for j in range(i + 1, n):
            sa, ca, aa, ba = placements[i]
            sb, cb, ab, bb = placements[j]
            if sa == sb or aa != ab:
                continue
            gap = abs(ba - bb)
            for ra, rb, min_gap in rules:
                hit = (matches(ca, ra) and matches(cb, rb)) or (matches(ca, rb) and matches(cb, ra))
                if hit and gap < min_gap:
                    found.add((sa, sb))
    return [list(p) for p in sorted(found)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['division match', [[['W', '4.3', 2, 2], ['C', '8', 2, 2]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['C', 'W']]], ['two pairs', [[['A', '3', 1, 1], ['Z', '5.1', 1, 2], ['B', '3', 1, 5], ['C', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['A', 'Z'], ['B', 'C']]], ['adjacent oxidizer', [[['F', '3', 1, 4], ['O', '5.1', 1, 5]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['F', 'O']]], ['other aisle', [[['F', '3', 1, 4], ['O', '5.1', 2, 4]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['same sku twice', [[['P', '5.2', 1, 3], ['P', '5.2', 1, 3]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['gap equal ok', [[['F', '3', 1, 4], ['O', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 6', [[['H0', '2.1', 1, 4], ['H1', '9', 1, 1]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 14', [[['H0', '3', 1, 5], ['H1', '2.1', 2, 4], ['H2', '9', 2, 1], ['H3', '4.3', 1, 6], ['H0', '3', 1, 4]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []]], [['generated mix 55', [[['H0', '3', 2, 6], ['H1', '2.1', 1, 1], ['H2', '8', 1, 6], ['H3', '8', 2, 5], ['H4', '5.1', 2, 5], ['H5', '5.2', 1, 5], ['H0', '3', 2, 4]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['H0', 'H4']]], ['two pairs', [[['A', '3', 1, 1], ['Z', '5.1', 1, 2], ['B', '3', 1, 5], ['C', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['A', 'Z'], ['B', 'C']]], ['other aisle', [[['F', '3', 1, 4], ['O', '5.1', 2, 4]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['same sku twice', [[['P', '5.2', 1, 3], ['P', '5.2', 1, 3]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['adjacent oxidizer', [[['F', '3', 1, 4], ['O', '5.1', 1, 5]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['F', 'O']]], ['division match', [[['W', '4.3', 2, 2], ['C', '8', 2, 2]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['C', 'W']]], ['generated mix 9', [[['H0', '9', 1, 6], ['H1', '5.1', 1, 6], ['H2', '4.1', 1, 6], ['H3', '4.1', 1, 2], ['H4', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 17', [[['H0', '8', 1, 5], ['H1', '9', 2, 6], ['H2', '4.3', 1, 3], ['H3', '4.1', 1, 1], ['H4', '9', 1, 5]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []]], [['generated mix 16', [[['H0', '5.2', 1, 6], ['H1', '4.1', 1, 5], ['H2', '2.1', 1, 2], ['H3', '5.1', 1, 1], ['H4', '5.1', 1, 1], ['H5', '8', 2, 5], ['H0', '5.2', 1, 3]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['H0', 'H2'], ['H2', 'H3'], ['H2', 'H4']]], ['two pairs', [[['A', '3', 1, 1], ['Z', '5.1', 1, 2], ['B', '3', 1, 5], ['C', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['A', 'Z'], ['B', 'C']]], ['reverse order', [[['O', '5.1', 1, 1], ['G', '2.1', 1, 3]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['G', 'O']]], ['gap equal ok', [[['F', '3', 1, 4], ['O', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['other aisle', [[['F', '3', 1, 4], ['O', '5.1', 2, 4]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['same sku twice', [[['P', '5.2', 1, 3], ['P', '5.2', 1, 3]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 21', [[['H0', '4.1', 1, 2], ['H1', '9', 1, 1], ['H2', '8', 1, 6], ['H3', '4.1', 2, 5], ['H4', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 29', [[['H0', '2.1', 1, 3], ['H1', '8', 2, 5]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []]], [['reverse order', [[['O', '5.1', 1, 1], ['G', '2.1', 1, 3]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['G', 'O']]], ['two pairs', [[['A', '3', 1, 1], ['Z', '5.1', 1, 2], ['B', '3', 1, 5], ['C', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['A', 'Z'], ['B', 'C']]], ['other aisle', [[['F', '3', 1, 4], ['O', '5.1', 2, 4]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['same sku twice', [[['P', '5.2', 1, 3], ['P', '5.2', 1, 3]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['gap equal ok', [[['F', '3', 1, 4], ['O', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 31', [[['H0', '3', 1, 6], ['H1', '4.1', 2, 4], ['H2', '2.1', 2, 5]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 39', [[['H0', '8', 1, 2], ['H1', '8', 2, 5], ['H2', '3', 1, 1], ['H3', '4.3', 2, 3], ['H0', '8', 1, 2]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 47', [[['H0', '5.2', 2, 2], ['H1', '3', 1, 2], ['H2', '4.1', 1, 3], ['H3', '5.2', 1, 5], ['H0', '5.2', 2, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []]], [['division match', [[['W', '4.3', 2, 2], ['C', '8', 2, 2]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['C', 'W']]], ['two pairs', [[['A', '3', 1, 1], ['Z', '5.1', 1, 2], ['B', '3', 1, 5], ['C', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['A', 'Z'], ['B', 'C']]], ['adjacent oxidizer', [[['F', '3', 1, 4], ['O', '5.1', 1, 5]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['F', 'O']]], ['other aisle', [[['F', '3', 1, 4], ['O', '5.1', 2, 4]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['same sku twice', [[['P', '5.2', 1, 3], ['P', '5.2', 1, 3]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 42', [[['H0', '8', 2, 1], ['H1', '3', 2, 6], ['H2', '3', 1, 5], ['H3', '5.2', 2, 5]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 50', [[['H0', '8', 1, 2], ['H1', '2.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 58', [[['H0', '8', 1, 2], ['H1', '2.1', 1, 5]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []]]]
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
division match[['W', 'C']][['C', 'W']]Failed
two pairs[['A', 'Z'], ['B', 'C']][['A', 'Z'], ['B', 'C']]Passed
adjacent oxidizer[['F', 'O']][['F', 'O']]Passed
other aisle[][]Passed
same sku twice[][]Passed
gap equal ok[][]Passed
generated mix 6[][]Passed
generated mix 14[][]Passed

SHA-256 / deea2186f77c49d1db8d4fb9f772536eead77c75a4bb79194c4ac9115bc2f318

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(placements, rules):
    def matches(cls, rule):
        return cls == rule or cls.startswith(rule + '.')
    found = set()
    n = len(placements)
    for i in range(n):
        for j in range(i + 1, n):
            sa, ca, aa, ba = placements[i]
            sb, cb, ab, bb = placements[j]
            if sa == sb or aa != ab:
                continue
            gap = abs(ba - bb)
            for ra, rb, min_gap in rules:
                hit = (matches(ca, ra) and matches(cb, rb)) or (matches(ca, rb) and matches(cb, ra))
                if hit and gap < min_gap:
                    found.add(tuple(sorted([sa, sb])))
    return [list(p) for p in sorted(found, key=lambda p: (p[1], p[0]))]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['division match', [[['W', '4.3', 2, 2], ['C', '8', 2, 2]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['C', 'W']]], ['two pairs', [[['A', '3', 1, 1], ['Z', '5.1', 1, 2], ['B', '3', 1, 5], ['C', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['A', 'Z'], ['B', 'C']]], ['adjacent oxidizer', [[['F', '3', 1, 4], ['O', '5.1', 1, 5]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['F', 'O']]], ['other aisle', [[['F', '3', 1, 4], ['O', '5.1', 2, 4]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['same sku twice', [[['P', '5.2', 1, 3], ['P', '5.2', 1, 3]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['gap equal ok', [[['F', '3', 1, 4], ['O', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 6', [[['H0', '2.1', 1, 4], ['H1', '9', 1, 1]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 14', [[['H0', '3', 1, 5], ['H1', '2.1', 2, 4], ['H2', '9', 2, 1], ['H3', '4.3', 1, 6], ['H0', '3', 1, 4]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []]], [['generated mix 55', [[['H0', '3', 2, 6], ['H1', '2.1', 1, 1], ['H2', '8', 1, 6], ['H3', '8', 2, 5], ['H4', '5.1', 2, 5], ['H5', '5.2', 1, 5], ['H0', '3', 2, 4]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['H0', 'H4']]], ['two pairs', [[['A', '3', 1, 1], ['Z', '5.1', 1, 2], ['B', '3', 1, 5], ['C', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['A', 'Z'], ['B', 'C']]], ['other aisle', [[['F', '3', 1, 4], ['O', '5.1', 2, 4]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['same sku twice', [[['P', '5.2', 1, 3], ['P', '5.2', 1, 3]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['adjacent oxidizer', [[['F', '3', 1, 4], ['O', '5.1', 1, 5]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['F', 'O']]], ['division match', [[['W', '4.3', 2, 2], ['C', '8', 2, 2]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['C', 'W']]], ['generated mix 9', [[['H0', '9', 1, 6], ['H1', '5.1', 1, 6], ['H2', '4.1', 1, 6], ['H3', '4.1', 1, 2], ['H4', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 17', [[['H0', '8', 1, 5], ['H1', '9', 2, 6], ['H2', '4.3', 1, 3], ['H3', '4.1', 1, 1], ['H4', '9', 1, 5]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []]], [['generated mix 16', [[['H0', '5.2', 1, 6], ['H1', '4.1', 1, 5], ['H2', '2.1', 1, 2], ['H3', '5.1', 1, 1], ['H4', '5.1', 1, 1], ['H5', '8', 2, 5], ['H0', '5.2', 1, 3]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['H0', 'H2'], ['H2', 'H3'], ['H2', 'H4']]], ['two pairs', [[['A', '3', 1, 1], ['Z', '5.1', 1, 2], ['B', '3', 1, 5], ['C', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['A', 'Z'], ['B', 'C']]], ['reverse order', [[['O', '5.1', 1, 1], ['G', '2.1', 1, 3]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['G', 'O']]], ['gap equal ok', [[['F', '3', 1, 4], ['O', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['other aisle', [[['F', '3', 1, 4], ['O', '5.1', 2, 4]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['same sku twice', [[['P', '5.2', 1, 3], ['P', '5.2', 1, 3]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 21', [[['H0', '4.1', 1, 2], ['H1', '9', 1, 1], ['H2', '8', 1, 6], ['H3', '4.1', 2, 5], ['H4', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 29', [[['H0', '2.1', 1, 3], ['H1', '8', 2, 5]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []]], [['reverse order', [[['O', '5.1', 1, 1], ['G', '2.1', 1, 3]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['G', 'O']]], ['two pairs', [[['A', '3', 1, 1], ['Z', '5.1', 1, 2], ['B', '3', 1, 5], ['C', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['A', 'Z'], ['B', 'C']]], ['other aisle', [[['F', '3', 1, 4], ['O', '5.1', 2, 4]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['same sku twice', [[['P', '5.2', 1, 3], ['P', '5.2', 1, 3]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['gap equal ok', [[['F', '3', 1, 4], ['O', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 31', [[['H0', '3', 1, 6], ['H1', '4.1', 2, 4], ['H2', '2.1', 2, 5]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 39', [[['H0', '8', 1, 2], ['H1', '8', 2, 5], ['H2', '3', 1, 1], ['H3', '4.3', 2, 3], ['H0', '8', 1, 2]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 47', [[['H0', '5.2', 2, 2], ['H1', '3', 1, 2], ['H2', '4.1', 1, 3], ['H3', '5.2', 1, 5], ['H0', '5.2', 2, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []]], [['division match', [[['W', '4.3', 2, 2], ['C', '8', 2, 2]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['C', 'W']]], ['two pairs', [[['A', '3', 1, 1], ['Z', '5.1', 1, 2], ['B', '3', 1, 5], ['C', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['A', 'Z'], ['B', 'C']]], ['adjacent oxidizer', [[['F', '3', 1, 4], ['O', '5.1', 1, 5]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['F', 'O']]], ['other aisle', [[['F', '3', 1, 4], ['O', '5.1', 2, 4]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['same sku twice', [[['P', '5.2', 1, 3], ['P', '5.2', 1, 3]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 42', [[['H0', '8', 2, 1], ['H1', '3', 2, 6], ['H2', '3', 1, 5], ['H3', '5.2', 2, 5]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 50', [[['H0', '8', 1, 2], ['H1', '2.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 58', [[['H0', '8', 1, 2], ['H1', '2.1', 1, 5]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []]]]
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
division match[['C', 'W']][['C', 'W']]Passed
two pairs[['B', 'C'], ['A', 'Z']][['A', 'Z'], ['B', 'C']]Failed
adjacent oxidizer[['F', 'O']][['F', 'O']]Passed
other aisle[][]Passed
same sku twice[][]Passed
gap equal ok[][]Passed
generated mix 6[][]Passed
generated mix 14[][]Passed

SHA-256 / 9d1d654232a33967ffbf105844689b647e06f1b8512bc0121ece7861ca321bdc

3 / The verified repair

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

N = 1
observations = []
def solve(placements, rules):
    def matches(cls, rule):
        return cls == rule or cls.startswith(rule + '.')
    found = set()
    n = len(placements)
    for i in range(n):
        for j in range(i + 1, n):
            sa, ca, aa, ba = placements[i]
            sb, cb, ab, bb = placements[j]
            if sa == sb or aa != ab:
                continue
            gap = abs(ba - bb)
            for ra, rb, min_gap in rules:
                hit = (matches(ca, ra) and matches(cb, rb)) or (matches(ca, rb) and matches(cb, ra))
                if hit and gap < min_gap:
                    found.add(tuple(sorted([sa, sb])))
    return [list(p) for p in sorted(found)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['division match', [[['W', '4.3', 2, 2], ['C', '8', 2, 2]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['C', 'W']]], ['two pairs', [[['A', '3', 1, 1], ['Z', '5.1', 1, 2], ['B', '3', 1, 5], ['C', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['A', 'Z'], ['B', 'C']]], ['adjacent oxidizer', [[['F', '3', 1, 4], ['O', '5.1', 1, 5]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['F', 'O']]], ['other aisle', [[['F', '3', 1, 4], ['O', '5.1', 2, 4]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['same sku twice', [[['P', '5.2', 1, 3], ['P', '5.2', 1, 3]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['gap equal ok', [[['F', '3', 1, 4], ['O', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 6', [[['H0', '2.1', 1, 4], ['H1', '9', 1, 1]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 14', [[['H0', '3', 1, 5], ['H1', '2.1', 2, 4], ['H2', '9', 2, 1], ['H3', '4.3', 1, 6], ['H0', '3', 1, 4]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []]], [['generated mix 55', [[['H0', '3', 2, 6], ['H1', '2.1', 1, 1], ['H2', '8', 1, 6], ['H3', '8', 2, 5], ['H4', '5.1', 2, 5], ['H5', '5.2', 1, 5], ['H0', '3', 2, 4]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['H0', 'H4']]], ['two pairs', [[['A', '3', 1, 1], ['Z', '5.1', 1, 2], ['B', '3', 1, 5], ['C', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['A', 'Z'], ['B', 'C']]], ['other aisle', [[['F', '3', 1, 4], ['O', '5.1', 2, 4]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['same sku twice', [[['P', '5.2', 1, 3], ['P', '5.2', 1, 3]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['adjacent oxidizer', [[['F', '3', 1, 4], ['O', '5.1', 1, 5]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['F', 'O']]], ['division match', [[['W', '4.3', 2, 2], ['C', '8', 2, 2]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['C', 'W']]], ['generated mix 9', [[['H0', '9', 1, 6], ['H1', '5.1', 1, 6], ['H2', '4.1', 1, 6], ['H3', '4.1', 1, 2], ['H4', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 17', [[['H0', '8', 1, 5], ['H1', '9', 2, 6], ['H2', '4.3', 1, 3], ['H3', '4.1', 1, 1], ['H4', '9', 1, 5]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []]], [['generated mix 16', [[['H0', '5.2', 1, 6], ['H1', '4.1', 1, 5], ['H2', '2.1', 1, 2], ['H3', '5.1', 1, 1], ['H4', '5.1', 1, 1], ['H5', '8', 2, 5], ['H0', '5.2', 1, 3]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['H0', 'H2'], ['H2', 'H3'], ['H2', 'H4']]], ['two pairs', [[['A', '3', 1, 1], ['Z', '5.1', 1, 2], ['B', '3', 1, 5], ['C', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['A', 'Z'], ['B', 'C']]], ['reverse order', [[['O', '5.1', 1, 1], ['G', '2.1', 1, 3]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['G', 'O']]], ['gap equal ok', [[['F', '3', 1, 4], ['O', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['other aisle', [[['F', '3', 1, 4], ['O', '5.1', 2, 4]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['same sku twice', [[['P', '5.2', 1, 3], ['P', '5.2', 1, 3]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 21', [[['H0', '4.1', 1, 2], ['H1', '9', 1, 1], ['H2', '8', 1, 6], ['H3', '4.1', 2, 5], ['H4', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 29', [[['H0', '2.1', 1, 3], ['H1', '8', 2, 5]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []]], [['reverse order', [[['O', '5.1', 1, 1], ['G', '2.1', 1, 3]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['G', 'O']]], ['two pairs', [[['A', '3', 1, 1], ['Z', '5.1', 1, 2], ['B', '3', 1, 5], ['C', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['A', 'Z'], ['B', 'C']]], ['other aisle', [[['F', '3', 1, 4], ['O', '5.1', 2, 4]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['same sku twice', [[['P', '5.2', 1, 3], ['P', '5.2', 1, 3]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['gap equal ok', [[['F', '3', 1, 4], ['O', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 31', [[['H0', '3', 1, 6], ['H1', '4.1', 2, 4], ['H2', '2.1', 2, 5]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 39', [[['H0', '8', 1, 2], ['H1', '8', 2, 5], ['H2', '3', 1, 1], ['H3', '4.3', 2, 3], ['H0', '8', 1, 2]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 47', [[['H0', '5.2', 2, 2], ['H1', '3', 1, 2], ['H2', '4.1', 1, 3], ['H3', '5.2', 1, 5], ['H0', '5.2', 2, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []]], [['division match', [[['W', '4.3', 2, 2], ['C', '8', 2, 2]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['C', 'W']]], ['two pairs', [[['A', '3', 1, 1], ['Z', '5.1', 1, 2], ['B', '3', 1, 5], ['C', '5.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['A', 'Z'], ['B', 'C']]], ['adjacent oxidizer', [[['F', '3', 1, 4], ['O', '5.1', 1, 5]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], [['F', 'O']]], ['other aisle', [[['F', '3', 1, 4], ['O', '5.1', 2, 4]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['same sku twice', [[['P', '5.2', 1, 3], ['P', '5.2', 1, 3]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 42', [[['H0', '8', 2, 1], ['H1', '3', 2, 6], ['H2', '3', 1, 5], ['H3', '5.2', 2, 5]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 50', [[['H0', '8', 1, 2], ['H1', '2.1', 1, 6]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []], ['generated mix 58', [[['H0', '8', 1, 2], ['H1', '2.1', 1, 5]], [['3', '5.1', 2], ['4', '8', 1], ['5.2', '5.2', 1], ['2.1', '5', 3]]], []]]]
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
division match[['C', 'W']][['C', 'W']]Passed
two pairs[['A', 'Z'], ['B', 'C']][['A', 'Z'], ['B', 'C']]Passed
adjacent oxidizer[['F', 'O']][['F', 'O']]Passed
other aisle[][]Passed
same sku twice[][]Passed
gap equal ok[][]Passed
generated mix 6[][]Passed
generated mix 14[][]Passed

SHA-256 / 4e5806eb8e97de05050ecac30be084dfcd20989d5c495fa0fce505b1cd18abd7

Verification & scope

Stipulated bay-gap rule table; not a regulatory segregation chart. 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.975104+00:00.

Case digest / 63af527556f00e15f153cda40c000b8b5ca6858ad35e37db76cdc38801a58ac5