FAILURE MAP
← Case archive

FA-37006 / Table interactions / Open access

Merged cell rendering: column span end · case 01

The table column span end result violates the stipulated merged cell rendering contract.

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

ROOT CAUSE

The column span end decision uses "a['cs']" instead of "a['c']+a['cs']".

VERIFIED REPAIR

Apply the complete column span end rule: a['c']+a['cs'].

Unsuccessful approach: The attempted repair "a['c']+a['cs']+1" still loses a required part of the table contract.

Case contract

Merged rectangles are expressed in source coordinates, clipped to source bounds and visible rows/columns, rebased to the first visible cell, and accepted in declaration order only if disjoint; plain cells omit every accepted merged cell.

Why this case matters

An offline table UI model isolates merged cell rendering, including adversarial row/column relationships.

1 / The failure

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

N = 1
observations = []
def solve(rows, cols, anchors, hidden_rows, hidden_cols):
    vr=[r for r in rows if r not in hidden_rows]
    vc=[c for c in cols if c not in hidden_cols]
    result=[]
    covered=set()
    for a in anchors:
        rr=[r for r in rows[a['r']:a['r']+a['rs']] if r in vr]
        cc=[c for c in cols[a['c']:a['cs']] if c in vc]
        if not rr or not cc: continue
        cells={(r,c) for r in rr for c in cc}
        if cells & covered: continue
        covered |= cells
        result.append({'anchor':[rr[0],cc[0]],'rowspan':len(rr),'colspan':len(cc),'value':a['value'],'covered':sorted(cells-{(rr[0],cc[0])})})
    return {'merges':result,'plain':[(r,c) for r in vr for c in vc if (r,c) not in covered]}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
if N == 1:
    check('nonzero origin', solve(['r0','r1','r2','r3'], ['a','b','c','d'], [{'r':1,'c':1,'rs':2,'cs':2,'value':1}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 2, 'colspan': 2, 'value': 1, 'covered': [('r1', 'c'), ('r2', 'b'), ('r2', 'c')]}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r0', 'c'), ('r0', 'd'), ('r1', 'a'), ('r1', 'd'), ('r2', 'a'), ('r2', 'd'), ('r3', 'a'), ('r3', 'b'), ('r3', 'c'), ('r3', 'd')]})
    check('hidden anchor', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':3,'cs':3,'value':'x'}], ['r0','r1'], ['a','b']), {'merges': [{'anchor': ['r2', 'c'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': []})
    check('partial overlap', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':2,'cs':2,'value':'x'},{'r':1,'c':1,'rs':2,'cs':2,'value':'y'}], [], []), {'merges': [{'anchor': ['r0', 'a'], 'rowspan': 2, 'colspan': 2, 'value': 'x', 'covered': [('r0', 'b'), ('r1', 'a'), ('r1', 'b')]}], 'plain': [('r0', 'c'), ('r1', 'c'), ('r2', 'a'), ('r2', 'b'), ('r2', 'c')]})
    check('hidden merge', solve(['r0'], ['a'], [{'r':0,'c':0,'rs':1,'cs':1,'value':'x'}], ['r0'], []), {'merges': [], 'plain': []})
    check('clamped span', solve(['r0','r1'], ['a','b'], [{'r':1,'c':1,'rs':4,'cs':4,'value':'x'}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a')]})
    check('unmerged grid', solve(['r0','r1'], ['a','b'], [], [], []), {'merges': [], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a'), ('r1', 'b')]})

if N == 2:
    check('nonzero origin', solve(['r0','r1','r2','r3'], ['a','b','c','d'], [{'r':1,'c':1,'rs':2,'cs':2,'value':2}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 2, 'colspan': 2, 'value': 2, 'covered': [('r1', 'c'), ('r2', 'b'), ('r2', 'c')]}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r0', 'c'), ('r0', 'd'), ('r1', 'a'), ('r1', 'd'), ('r2', 'a'), ('r2', 'd'), ('r3', 'a'), ('r3', 'b'), ('r3', 'c'), ('r3', 'd')]})
    check('hidden anchor', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':3,'cs':3,'value':'x'}], ['r0','r1'], ['a','b']), {'merges': [{'anchor': ['r2', 'c'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': []})
    check('partial overlap', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':2,'cs':2,'value':'x'},{'r':1,'c':1,'rs':2,'cs':2,'value':'y'}], [], []), {'merges': [{'anchor': ['r0', 'a'], 'rowspan': 2, 'colspan': 2, 'value': 'x', 'covered': [('r0', 'b'), ('r1', 'a'), ('r1', 'b')]}], 'plain': [('r0', 'c'), ('r1', 'c'), ('r2', 'a'), ('r2', 'b'), ('r2', 'c')]})
    check('hidden merge', solve(['r0'], ['a'], [{'r':0,'c':0,'rs':1,'cs':1,'value':'x'}], ['r0'], []), {'merges': [], 'plain': []})
    check('clamped span', solve(['r0','r1'], ['a','b'], [{'r':1,'c':1,'rs':4,'cs':4,'value':'x'}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a')]})
    check('unmerged grid', solve(['r0','r1'], ['a','b'], [], [], []), {'merges': [], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a'), ('r1', 'b')]})

if N == 3:
    check('nonzero origin', solve(['r0','r1','r2','r3'], ['a','b','c','d'], [{'r':1,'c':1,'rs':2,'cs':2,'value':3}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 2, 'colspan': 2, 'value': 3, 'covered': [('r1', 'c'), ('r2', 'b'), ('r2', 'c')]}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r0', 'c'), ('r0', 'd'), ('r1', 'a'), ('r1', 'd'), ('r2', 'a'), ('r2', 'd'), ('r3', 'a'), ('r3', 'b'), ('r3', 'c'), ('r3', 'd')]})
    check('hidden anchor', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':3,'cs':3,'value':'x'}], ['r0','r1'], ['a','b']), {'merges': [{'anchor': ['r2', 'c'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': []})
    check('partial overlap', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':2,'cs':2,'value':'x'},{'r':1,'c':1,'rs':2,'cs':2,'value':'y'}], [], []), {'merges': [{'anchor': ['r0', 'a'], 'rowspan': 2, 'colspan': 2, 'value': 'x', 'covered': [('r0', 'b'), ('r1', 'a'), ('r1', 'b')]}], 'plain': [('r0', 'c'), ('r1', 'c'), ('r2', 'a'), ('r2', 'b'), ('r2', 'c')]})
    check('hidden merge', solve(['r0'], ['a'], [{'r':0,'c':0,'rs':1,'cs':1,'value':'x'}], ['r0'], []), {'merges': [], 'plain': []})
    check('clamped span', solve(['r0','r1'], ['a','b'], [{'r':1,'c':1,'rs':4,'cs':4,'value':'x'}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a')]})
    check('unmerged grid', solve(['r0','r1'], ['a','b'], [], [], []), {'merges': [], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a'), ('r1', 'b')]})

if N == 4:
    check('nonzero origin', solve(['r0','r1','r2','r3'], ['a','b','c','d'], [{'r':1,'c':1,'rs':2,'cs':2,'value':4}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 2, 'colspan': 2, 'value': 4, 'covered': [('r1', 'c'), ('r2', 'b'), ('r2', 'c')]}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r0', 'c'), ('r0', 'd'), ('r1', 'a'), ('r1', 'd'), ('r2', 'a'), ('r2', 'd'), ('r3', 'a'), ('r3', 'b'), ('r3', 'c'), ('r3', 'd')]})
    check('hidden anchor', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':3,'cs':3,'value':'x'}], ['r0','r1'], ['a','b']), {'merges': [{'anchor': ['r2', 'c'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': []})
    check('partial overlap', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':2,'cs':2,'value':'x'},{'r':1,'c':1,'rs':2,'cs':2,'value':'y'}], [], []), {'merges': [{'anchor': ['r0', 'a'], 'rowspan': 2, 'colspan': 2, 'value': 'x', 'covered': [('r0', 'b'), ('r1', 'a'), ('r1', 'b')]}], 'plain': [('r0', 'c'), ('r1', 'c'), ('r2', 'a'), ('r2', 'b'), ('r2', 'c')]})
    check('hidden merge', solve(['r0'], ['a'], [{'r':0,'c':0,'rs':1,'cs':1,'value':'x'}], ['r0'], []), {'merges': [], 'plain': []})
    check('clamped span', solve(['r0','r1'], ['a','b'], [{'r':1,'c':1,'rs':4,'cs':4,'value':'x'}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a')]})
    check('unmerged grid', solve(['r0','r1'], ['a','b'], [], [], []), {'merges': [], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a'), ('r1', 'b')]})

if N == 5:
    check('nonzero origin', solve(['r0','r1','r2','r3'], ['a','b','c','d'], [{'r':1,'c':1,'rs':2,'cs':2,'value':5}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 2, 'colspan': 2, 'value': 5, 'covered': [('r1', 'c'), ('r2', 'b'), ('r2', 'c')]}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r0', 'c'), ('r0', 'd'), ('r1', 'a'), ('r1', 'd'), ('r2', 'a'), ('r2', 'd'), ('r3', 'a'), ('r3', 'b'), ('r3', 'c'), ('r3', 'd')]})
    check('hidden anchor', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':3,'cs':3,'value':'x'}], ['r0','r1'], ['a','b']), {'merges': [{'anchor': ['r2', 'c'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': []})
    check('partial overlap', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':2,'cs':2,'value':'x'},{'r':1,'c':1,'rs':2,'cs':2,'value':'y'}], [], []), {'merges': [{'anchor': ['r0', 'a'], 'rowspan': 2, 'colspan': 2, 'value': 'x', 'covered': [('r0', 'b'), ('r1', 'a'), ('r1', 'b')]}], 'plain': [('r0', 'c'), ('r1', 'c'), ('r2', 'a'), ('r2', 'b'), ('r2', 'c')]})
    check('hidden merge', solve(['r0'], ['a'], [{'r':0,'c':0,'rs':1,'cs':1,'value':'x'}], ['r0'], []), {'merges': [], 'plain': []})
    check('clamped span', solve(['r0','r1'], ['a','b'], [{'r':1,'c':1,'rs':4,'cs':4,'value':'x'}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a')]})
    check('unmerged grid', solve(['r0','r1'], ['a','b'], [], [], []), {'merges': [], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a'), ('r1', 'b')]})

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
nonzero origin{'merges': [{'anchor': ['r1', 'b'], 'colspan': 1, 'covered': [['r2', 'b']], 'rowspan': 2, 'value': 1}], 'plain': [['r0', 'a'], ['r0', 'b'], ['r0', 'c'], ['r0', 'd'], ['r1', 'a'], ['r1', 'c'], ['r1', 'd'], ['r2', 'a'], ['r2', 'c'], ['r2', 'd'], ['r3', 'a'], ['r3', 'b'], ['r3', 'c'], ['r3', 'd']]}{'merges': [{'anchor': ['r1', 'b'], 'colspan': 2, 'covered': [['r1', 'c'], ['r2', 'b'], ['r2', 'c']], 'rowspan': 2, 'value': 1}], 'plain': [['r0', 'a'], ['r0', 'b'], ['r0', 'c'], ['r0', 'd'], ['r1', 'a'], ['r1', 'd'], ['r2', 'a'], ['r2', 'd'], ['r3', 'a'], ['r3', 'b'], ['r3', 'c'], ['r3', 'd']]}Failed
hidden anchor{'merges': [{'anchor': ['r2', 'c'], 'colspan': 1, 'covered': [], 'rowspan': 1, 'value': 'x'}], 'plain': []}{'merges': [{'anchor': ['r2', 'c'], 'colspan': 1, 'covered': [], 'rowspan': 1, 'value': 'x'}], 'plain': []}Passed
partial overlap{'merges': [{'anchor': ['r0', 'a'], 'colspan': 2, 'covered': [['r0', 'b'], ['r1', 'a'], ['r1', 'b']], 'rowspan': 2, 'value': 'x'}], 'plain': [['r0', 'c'], ['r1', 'c'], ['r2', 'a'], ['r2', 'b'], ['r2', 'c']]}{'merges': [{'anchor': ['r0', 'a'], 'colspan': 2, 'covered': [['r0', 'b'], ['r1', 'a'], ['r1', 'b']], 'rowspan': 2, 'value': 'x'}], 'plain': [['r0', 'c'], ['r1', 'c'], ['r2', 'a'], ['r2', 'b'], ['r2', 'c']]}Passed
hidden merge{'merges': [], 'plain': []}{'merges': [], 'plain': []}Passed
clamped span{'merges': [{'anchor': ['r1', 'b'], 'colspan': 1, 'covered': [], 'rowspan': 1, 'value': 'x'}], 'plain': [['r0', 'a'], ['r0', 'b'], ['r1', 'a']]}{'merges': [{'anchor': ['r1', 'b'], 'colspan': 1, 'covered': [], 'rowspan': 1, 'value': 'x'}], 'plain': [['r0', 'a'], ['r0', 'b'], ['r1', 'a']]}Passed
unmerged grid{'merges': [], 'plain': [['r0', 'a'], ['r0', 'b'], ['r1', 'a'], ['r1', 'b']]}{'merges': [], 'plain': [['r0', 'a'], ['r0', 'b'], ['r1', 'a'], ['r1', 'b']]}Passed

SHA-256 / 5b9bca258c15112901ddc09f4a3abe2802720aeebbad617d6fc77f730e040e78

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(rows, cols, anchors, hidden_rows, hidden_cols):
    vr=[r for r in rows if r not in hidden_rows]
    vc=[c for c in cols if c not in hidden_cols]
    result=[]
    covered=set()
    for a in anchors:
        rr=[r for r in rows[a['r']:a['r']+a['rs']] if r in vr]
        cc=[c for c in cols[a['c']:a['c']+a['cs']+1] if c in vc]
        if not rr or not cc: continue
        cells={(r,c) for r in rr for c in cc}
        if cells & covered: continue
        covered |= cells
        result.append({'anchor':[rr[0],cc[0]],'rowspan':len(rr),'colspan':len(cc),'value':a['value'],'covered':sorted(cells-{(rr[0],cc[0])})})
    return {'merges':result,'plain':[(r,c) for r in vr for c in vc if (r,c) not in covered]}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
if N == 1:
    check('nonzero origin', solve(['r0','r1','r2','r3'], ['a','b','c','d'], [{'r':1,'c':1,'rs':2,'cs':2,'value':1}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 2, 'colspan': 2, 'value': 1, 'covered': [('r1', 'c'), ('r2', 'b'), ('r2', 'c')]}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r0', 'c'), ('r0', 'd'), ('r1', 'a'), ('r1', 'd'), ('r2', 'a'), ('r2', 'd'), ('r3', 'a'), ('r3', 'b'), ('r3', 'c'), ('r3', 'd')]})
    check('hidden anchor', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':3,'cs':3,'value':'x'}], ['r0','r1'], ['a','b']), {'merges': [{'anchor': ['r2', 'c'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': []})
    check('partial overlap', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':2,'cs':2,'value':'x'},{'r':1,'c':1,'rs':2,'cs':2,'value':'y'}], [], []), {'merges': [{'anchor': ['r0', 'a'], 'rowspan': 2, 'colspan': 2, 'value': 'x', 'covered': [('r0', 'b'), ('r1', 'a'), ('r1', 'b')]}], 'plain': [('r0', 'c'), ('r1', 'c'), ('r2', 'a'), ('r2', 'b'), ('r2', 'c')]})
    check('hidden merge', solve(['r0'], ['a'], [{'r':0,'c':0,'rs':1,'cs':1,'value':'x'}], ['r0'], []), {'merges': [], 'plain': []})
    check('clamped span', solve(['r0','r1'], ['a','b'], [{'r':1,'c':1,'rs':4,'cs':4,'value':'x'}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a')]})
    check('unmerged grid', solve(['r0','r1'], ['a','b'], [], [], []), {'merges': [], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a'), ('r1', 'b')]})

if N == 2:
    check('nonzero origin', solve(['r0','r1','r2','r3'], ['a','b','c','d'], [{'r':1,'c':1,'rs':2,'cs':2,'value':2}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 2, 'colspan': 2, 'value': 2, 'covered': [('r1', 'c'), ('r2', 'b'), ('r2', 'c')]}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r0', 'c'), ('r0', 'd'), ('r1', 'a'), ('r1', 'd'), ('r2', 'a'), ('r2', 'd'), ('r3', 'a'), ('r3', 'b'), ('r3', 'c'), ('r3', 'd')]})
    check('hidden anchor', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':3,'cs':3,'value':'x'}], ['r0','r1'], ['a','b']), {'merges': [{'anchor': ['r2', 'c'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': []})
    check('partial overlap', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':2,'cs':2,'value':'x'},{'r':1,'c':1,'rs':2,'cs':2,'value':'y'}], [], []), {'merges': [{'anchor': ['r0', 'a'], 'rowspan': 2, 'colspan': 2, 'value': 'x', 'covered': [('r0', 'b'), ('r1', 'a'), ('r1', 'b')]}], 'plain': [('r0', 'c'), ('r1', 'c'), ('r2', 'a'), ('r2', 'b'), ('r2', 'c')]})
    check('hidden merge', solve(['r0'], ['a'], [{'r':0,'c':0,'rs':1,'cs':1,'value':'x'}], ['r0'], []), {'merges': [], 'plain': []})
    check('clamped span', solve(['r0','r1'], ['a','b'], [{'r':1,'c':1,'rs':4,'cs':4,'value':'x'}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a')]})
    check('unmerged grid', solve(['r0','r1'], ['a','b'], [], [], []), {'merges': [], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a'), ('r1', 'b')]})

if N == 3:
    check('nonzero origin', solve(['r0','r1','r2','r3'], ['a','b','c','d'], [{'r':1,'c':1,'rs':2,'cs':2,'value':3}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 2, 'colspan': 2, 'value': 3, 'covered': [('r1', 'c'), ('r2', 'b'), ('r2', 'c')]}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r0', 'c'), ('r0', 'd'), ('r1', 'a'), ('r1', 'd'), ('r2', 'a'), ('r2', 'd'), ('r3', 'a'), ('r3', 'b'), ('r3', 'c'), ('r3', 'd')]})
    check('hidden anchor', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':3,'cs':3,'value':'x'}], ['r0','r1'], ['a','b']), {'merges': [{'anchor': ['r2', 'c'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': []})
    check('partial overlap', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':2,'cs':2,'value':'x'},{'r':1,'c':1,'rs':2,'cs':2,'value':'y'}], [], []), {'merges': [{'anchor': ['r0', 'a'], 'rowspan': 2, 'colspan': 2, 'value': 'x', 'covered': [('r0', 'b'), ('r1', 'a'), ('r1', 'b')]}], 'plain': [('r0', 'c'), ('r1', 'c'), ('r2', 'a'), ('r2', 'b'), ('r2', 'c')]})
    check('hidden merge', solve(['r0'], ['a'], [{'r':0,'c':0,'rs':1,'cs':1,'value':'x'}], ['r0'], []), {'merges': [], 'plain': []})
    check('clamped span', solve(['r0','r1'], ['a','b'], [{'r':1,'c':1,'rs':4,'cs':4,'value':'x'}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a')]})
    check('unmerged grid', solve(['r0','r1'], ['a','b'], [], [], []), {'merges': [], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a'), ('r1', 'b')]})

if N == 4:
    check('nonzero origin', solve(['r0','r1','r2','r3'], ['a','b','c','d'], [{'r':1,'c':1,'rs':2,'cs':2,'value':4}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 2, 'colspan': 2, 'value': 4, 'covered': [('r1', 'c'), ('r2', 'b'), ('r2', 'c')]}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r0', 'c'), ('r0', 'd'), ('r1', 'a'), ('r1', 'd'), ('r2', 'a'), ('r2', 'd'), ('r3', 'a'), ('r3', 'b'), ('r3', 'c'), ('r3', 'd')]})
    check('hidden anchor', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':3,'cs':3,'value':'x'}], ['r0','r1'], ['a','b']), {'merges': [{'anchor': ['r2', 'c'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': []})
    check('partial overlap', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':2,'cs':2,'value':'x'},{'r':1,'c':1,'rs':2,'cs':2,'value':'y'}], [], []), {'merges': [{'anchor': ['r0', 'a'], 'rowspan': 2, 'colspan': 2, 'value': 'x', 'covered': [('r0', 'b'), ('r1', 'a'), ('r1', 'b')]}], 'plain': [('r0', 'c'), ('r1', 'c'), ('r2', 'a'), ('r2', 'b'), ('r2', 'c')]})
    check('hidden merge', solve(['r0'], ['a'], [{'r':0,'c':0,'rs':1,'cs':1,'value':'x'}], ['r0'], []), {'merges': [], 'plain': []})
    check('clamped span', solve(['r0','r1'], ['a','b'], [{'r':1,'c':1,'rs':4,'cs':4,'value':'x'}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a')]})
    check('unmerged grid', solve(['r0','r1'], ['a','b'], [], [], []), {'merges': [], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a'), ('r1', 'b')]})

if N == 5:
    check('nonzero origin', solve(['r0','r1','r2','r3'], ['a','b','c','d'], [{'r':1,'c':1,'rs':2,'cs':2,'value':5}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 2, 'colspan': 2, 'value': 5, 'covered': [('r1', 'c'), ('r2', 'b'), ('r2', 'c')]}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r0', 'c'), ('r0', 'd'), ('r1', 'a'), ('r1', 'd'), ('r2', 'a'), ('r2', 'd'), ('r3', 'a'), ('r3', 'b'), ('r3', 'c'), ('r3', 'd')]})
    check('hidden anchor', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':3,'cs':3,'value':'x'}], ['r0','r1'], ['a','b']), {'merges': [{'anchor': ['r2', 'c'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': []})
    check('partial overlap', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':2,'cs':2,'value':'x'},{'r':1,'c':1,'rs':2,'cs':2,'value':'y'}], [], []), {'merges': [{'anchor': ['r0', 'a'], 'rowspan': 2, 'colspan': 2, 'value': 'x', 'covered': [('r0', 'b'), ('r1', 'a'), ('r1', 'b')]}], 'plain': [('r0', 'c'), ('r1', 'c'), ('r2', 'a'), ('r2', 'b'), ('r2', 'c')]})
    check('hidden merge', solve(['r0'], ['a'], [{'r':0,'c':0,'rs':1,'cs':1,'value':'x'}], ['r0'], []), {'merges': [], 'plain': []})
    check('clamped span', solve(['r0','r1'], ['a','b'], [{'r':1,'c':1,'rs':4,'cs':4,'value':'x'}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a')]})
    check('unmerged grid', solve(['r0','r1'], ['a','b'], [], [], []), {'merges': [], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a'), ('r1', 'b')]})

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
nonzero origin{'merges': [{'anchor': ['r1', 'b'], 'colspan': 3, 'covered': [['r1', 'c'], ['r1', 'd'], ['r2', 'b'], ['r2', 'c'], ['r2', 'd']], 'rowspan': 2, 'value': 1}], 'plain': [['r0', 'a'], ['r0', 'b'], ['r0', 'c'], ['r0', 'd'], ['r1', 'a'], ['r2', 'a'], ['r3', 'a'], ['r3', 'b'], ['r3', 'c'], ['r3', 'd']]}{'merges': [{'anchor': ['r1', 'b'], 'colspan': 2, 'covered': [['r1', 'c'], ['r2', 'b'], ['r2', 'c']], 'rowspan': 2, 'value': 1}], 'plain': [['r0', 'a'], ['r0', 'b'], ['r0', 'c'], ['r0', 'd'], ['r1', 'a'], ['r1', 'd'], ['r2', 'a'], ['r2', 'd'], ['r3', 'a'], ['r3', 'b'], ['r3', 'c'], ['r3', 'd']]}Failed
hidden anchor{'merges': [{'anchor': ['r2', 'c'], 'colspan': 1, 'covered': [], 'rowspan': 1, 'value': 'x'}], 'plain': []}{'merges': [{'anchor': ['r2', 'c'], 'colspan': 1, 'covered': [], 'rowspan': 1, 'value': 'x'}], 'plain': []}Passed
partial overlap{'merges': [{'anchor': ['r0', 'a'], 'colspan': 3, 'covered': [['r0', 'b'], ['r0', 'c'], ['r1', 'a'], ['r1', 'b'], ['r1', 'c']], 'rowspan': 2, 'value': 'x'}], 'plain': [['r2', 'a'], ['r2', 'b'], ['r2', 'c']]}{'merges': [{'anchor': ['r0', 'a'], 'colspan': 2, 'covered': [['r0', 'b'], ['r1', 'a'], ['r1', 'b']], 'rowspan': 2, 'value': 'x'}], 'plain': [['r0', 'c'], ['r1', 'c'], ['r2', 'a'], ['r2', 'b'], ['r2', 'c']]}Failed
hidden merge{'merges': [], 'plain': []}{'merges': [], 'plain': []}Passed
clamped span{'merges': [{'anchor': ['r1', 'b'], 'colspan': 1, 'covered': [], 'rowspan': 1, 'value': 'x'}], 'plain': [['r0', 'a'], ['r0', 'b'], ['r1', 'a']]}{'merges': [{'anchor': ['r1', 'b'], 'colspan': 1, 'covered': [], 'rowspan': 1, 'value': 'x'}], 'plain': [['r0', 'a'], ['r0', 'b'], ['r1', 'a']]}Passed
unmerged grid{'merges': [], 'plain': [['r0', 'a'], ['r0', 'b'], ['r1', 'a'], ['r1', 'b']]}{'merges': [], 'plain': [['r0', 'a'], ['r0', 'b'], ['r1', 'a'], ['r1', 'b']]}Passed

SHA-256 / ff910eb67224ee75d5efc3332160f610ca9d0f335b8ef9f0977ee8ccdf2302a8

3 / The verified repair

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

N = 1
observations = []
def solve(rows, cols, anchors, hidden_rows, hidden_cols):
    vr=[r for r in rows if r not in hidden_rows]
    vc=[c for c in cols if c not in hidden_cols]
    result=[]
    covered=set()
    for a in anchors:
        rr=[r for r in rows[a['r']:a['r']+a['rs']] if r in vr]
        cc=[c for c in cols[a['c']:a['c']+a['cs']] if c in vc]
        if not rr or not cc: continue
        cells={(r,c) for r in rr for c in cc}
        if cells & covered: continue
        covered |= cells
        result.append({'anchor':[rr[0],cc[0]],'rowspan':len(rr),'colspan':len(cc),'value':a['value'],'covered':sorted(cells-{(rr[0],cc[0])})})
    return {'merges':result,'plain':[(r,c) for r in vr for c in vc if (r,c) not in covered]}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
if N == 1:
    check('nonzero origin', solve(['r0','r1','r2','r3'], ['a','b','c','d'], [{'r':1,'c':1,'rs':2,'cs':2,'value':1}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 2, 'colspan': 2, 'value': 1, 'covered': [('r1', 'c'), ('r2', 'b'), ('r2', 'c')]}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r0', 'c'), ('r0', 'd'), ('r1', 'a'), ('r1', 'd'), ('r2', 'a'), ('r2', 'd'), ('r3', 'a'), ('r3', 'b'), ('r3', 'c'), ('r3', 'd')]})
    check('hidden anchor', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':3,'cs':3,'value':'x'}], ['r0','r1'], ['a','b']), {'merges': [{'anchor': ['r2', 'c'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': []})
    check('partial overlap', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':2,'cs':2,'value':'x'},{'r':1,'c':1,'rs':2,'cs':2,'value':'y'}], [], []), {'merges': [{'anchor': ['r0', 'a'], 'rowspan': 2, 'colspan': 2, 'value': 'x', 'covered': [('r0', 'b'), ('r1', 'a'), ('r1', 'b')]}], 'plain': [('r0', 'c'), ('r1', 'c'), ('r2', 'a'), ('r2', 'b'), ('r2', 'c')]})
    check('hidden merge', solve(['r0'], ['a'], [{'r':0,'c':0,'rs':1,'cs':1,'value':'x'}], ['r0'], []), {'merges': [], 'plain': []})
    check('clamped span', solve(['r0','r1'], ['a','b'], [{'r':1,'c':1,'rs':4,'cs':4,'value':'x'}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a')]})
    check('unmerged grid', solve(['r0','r1'], ['a','b'], [], [], []), {'merges': [], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a'), ('r1', 'b')]})

if N == 2:
    check('nonzero origin', solve(['r0','r1','r2','r3'], ['a','b','c','d'], [{'r':1,'c':1,'rs':2,'cs':2,'value':2}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 2, 'colspan': 2, 'value': 2, 'covered': [('r1', 'c'), ('r2', 'b'), ('r2', 'c')]}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r0', 'c'), ('r0', 'd'), ('r1', 'a'), ('r1', 'd'), ('r2', 'a'), ('r2', 'd'), ('r3', 'a'), ('r3', 'b'), ('r3', 'c'), ('r3', 'd')]})
    check('hidden anchor', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':3,'cs':3,'value':'x'}], ['r0','r1'], ['a','b']), {'merges': [{'anchor': ['r2', 'c'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': []})
    check('partial overlap', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':2,'cs':2,'value':'x'},{'r':1,'c':1,'rs':2,'cs':2,'value':'y'}], [], []), {'merges': [{'anchor': ['r0', 'a'], 'rowspan': 2, 'colspan': 2, 'value': 'x', 'covered': [('r0', 'b'), ('r1', 'a'), ('r1', 'b')]}], 'plain': [('r0', 'c'), ('r1', 'c'), ('r2', 'a'), ('r2', 'b'), ('r2', 'c')]})
    check('hidden merge', solve(['r0'], ['a'], [{'r':0,'c':0,'rs':1,'cs':1,'value':'x'}], ['r0'], []), {'merges': [], 'plain': []})
    check('clamped span', solve(['r0','r1'], ['a','b'], [{'r':1,'c':1,'rs':4,'cs':4,'value':'x'}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a')]})
    check('unmerged grid', solve(['r0','r1'], ['a','b'], [], [], []), {'merges': [], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a'), ('r1', 'b')]})

if N == 3:
    check('nonzero origin', solve(['r0','r1','r2','r3'], ['a','b','c','d'], [{'r':1,'c':1,'rs':2,'cs':2,'value':3}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 2, 'colspan': 2, 'value': 3, 'covered': [('r1', 'c'), ('r2', 'b'), ('r2', 'c')]}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r0', 'c'), ('r0', 'd'), ('r1', 'a'), ('r1', 'd'), ('r2', 'a'), ('r2', 'd'), ('r3', 'a'), ('r3', 'b'), ('r3', 'c'), ('r3', 'd')]})
    check('hidden anchor', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':3,'cs':3,'value':'x'}], ['r0','r1'], ['a','b']), {'merges': [{'anchor': ['r2', 'c'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': []})
    check('partial overlap', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':2,'cs':2,'value':'x'},{'r':1,'c':1,'rs':2,'cs':2,'value':'y'}], [], []), {'merges': [{'anchor': ['r0', 'a'], 'rowspan': 2, 'colspan': 2, 'value': 'x', 'covered': [('r0', 'b'), ('r1', 'a'), ('r1', 'b')]}], 'plain': [('r0', 'c'), ('r1', 'c'), ('r2', 'a'), ('r2', 'b'), ('r2', 'c')]})
    check('hidden merge', solve(['r0'], ['a'], [{'r':0,'c':0,'rs':1,'cs':1,'value':'x'}], ['r0'], []), {'merges': [], 'plain': []})
    check('clamped span', solve(['r0','r1'], ['a','b'], [{'r':1,'c':1,'rs':4,'cs':4,'value':'x'}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a')]})
    check('unmerged grid', solve(['r0','r1'], ['a','b'], [], [], []), {'merges': [], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a'), ('r1', 'b')]})

if N == 4:
    check('nonzero origin', solve(['r0','r1','r2','r3'], ['a','b','c','d'], [{'r':1,'c':1,'rs':2,'cs':2,'value':4}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 2, 'colspan': 2, 'value': 4, 'covered': [('r1', 'c'), ('r2', 'b'), ('r2', 'c')]}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r0', 'c'), ('r0', 'd'), ('r1', 'a'), ('r1', 'd'), ('r2', 'a'), ('r2', 'd'), ('r3', 'a'), ('r3', 'b'), ('r3', 'c'), ('r3', 'd')]})
    check('hidden anchor', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':3,'cs':3,'value':'x'}], ['r0','r1'], ['a','b']), {'merges': [{'anchor': ['r2', 'c'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': []})
    check('partial overlap', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':2,'cs':2,'value':'x'},{'r':1,'c':1,'rs':2,'cs':2,'value':'y'}], [], []), {'merges': [{'anchor': ['r0', 'a'], 'rowspan': 2, 'colspan': 2, 'value': 'x', 'covered': [('r0', 'b'), ('r1', 'a'), ('r1', 'b')]}], 'plain': [('r0', 'c'), ('r1', 'c'), ('r2', 'a'), ('r2', 'b'), ('r2', 'c')]})
    check('hidden merge', solve(['r0'], ['a'], [{'r':0,'c':0,'rs':1,'cs':1,'value':'x'}], ['r0'], []), {'merges': [], 'plain': []})
    check('clamped span', solve(['r0','r1'], ['a','b'], [{'r':1,'c':1,'rs':4,'cs':4,'value':'x'}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a')]})
    check('unmerged grid', solve(['r0','r1'], ['a','b'], [], [], []), {'merges': [], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a'), ('r1', 'b')]})

if N == 5:
    check('nonzero origin', solve(['r0','r1','r2','r3'], ['a','b','c','d'], [{'r':1,'c':1,'rs':2,'cs':2,'value':5}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 2, 'colspan': 2, 'value': 5, 'covered': [('r1', 'c'), ('r2', 'b'), ('r2', 'c')]}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r0', 'c'), ('r0', 'd'), ('r1', 'a'), ('r1', 'd'), ('r2', 'a'), ('r2', 'd'), ('r3', 'a'), ('r3', 'b'), ('r3', 'c'), ('r3', 'd')]})
    check('hidden anchor', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':3,'cs':3,'value':'x'}], ['r0','r1'], ['a','b']), {'merges': [{'anchor': ['r2', 'c'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': []})
    check('partial overlap', solve(['r0','r1','r2'], ['a','b','c'], [{'r':0,'c':0,'rs':2,'cs':2,'value':'x'},{'r':1,'c':1,'rs':2,'cs':2,'value':'y'}], [], []), {'merges': [{'anchor': ['r0', 'a'], 'rowspan': 2, 'colspan': 2, 'value': 'x', 'covered': [('r0', 'b'), ('r1', 'a'), ('r1', 'b')]}], 'plain': [('r0', 'c'), ('r1', 'c'), ('r2', 'a'), ('r2', 'b'), ('r2', 'c')]})
    check('hidden merge', solve(['r0'], ['a'], [{'r':0,'c':0,'rs':1,'cs':1,'value':'x'}], ['r0'], []), {'merges': [], 'plain': []})
    check('clamped span', solve(['r0','r1'], ['a','b'], [{'r':1,'c':1,'rs':4,'cs':4,'value':'x'}], [], []), {'merges': [{'anchor': ['r1', 'b'], 'rowspan': 1, 'colspan': 1, 'value': 'x', 'covered': []}], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a')]})
    check('unmerged grid', solve(['r0','r1'], ['a','b'], [], [], []), {'merges': [], 'plain': [('r0', 'a'), ('r0', 'b'), ('r1', 'a'), ('r1', 'b')]})

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
nonzero origin{'merges': [{'anchor': ['r1', 'b'], 'colspan': 2, 'covered': [['r1', 'c'], ['r2', 'b'], ['r2', 'c']], 'rowspan': 2, 'value': 1}], 'plain': [['r0', 'a'], ['r0', 'b'], ['r0', 'c'], ['r0', 'd'], ['r1', 'a'], ['r1', 'd'], ['r2', 'a'], ['r2', 'd'], ['r3', 'a'], ['r3', 'b'], ['r3', 'c'], ['r3', 'd']]}{'merges': [{'anchor': ['r1', 'b'], 'colspan': 2, 'covered': [['r1', 'c'], ['r2', 'b'], ['r2', 'c']], 'rowspan': 2, 'value': 1}], 'plain': [['r0', 'a'], ['r0', 'b'], ['r0', 'c'], ['r0', 'd'], ['r1', 'a'], ['r1', 'd'], ['r2', 'a'], ['r2', 'd'], ['r3', 'a'], ['r3', 'b'], ['r3', 'c'], ['r3', 'd']]}Passed
hidden anchor{'merges': [{'anchor': ['r2', 'c'], 'colspan': 1, 'covered': [], 'rowspan': 1, 'value': 'x'}], 'plain': []}{'merges': [{'anchor': ['r2', 'c'], 'colspan': 1, 'covered': [], 'rowspan': 1, 'value': 'x'}], 'plain': []}Passed
partial overlap{'merges': [{'anchor': ['r0', 'a'], 'colspan': 2, 'covered': [['r0', 'b'], ['r1', 'a'], ['r1', 'b']], 'rowspan': 2, 'value': 'x'}], 'plain': [['r0', 'c'], ['r1', 'c'], ['r2', 'a'], ['r2', 'b'], ['r2', 'c']]}{'merges': [{'anchor': ['r0', 'a'], 'colspan': 2, 'covered': [['r0', 'b'], ['r1', 'a'], ['r1', 'b']], 'rowspan': 2, 'value': 'x'}], 'plain': [['r0', 'c'], ['r1', 'c'], ['r2', 'a'], ['r2', 'b'], ['r2', 'c']]}Passed
hidden merge{'merges': [], 'plain': []}{'merges': [], 'plain': []}Passed
clamped span{'merges': [{'anchor': ['r1', 'b'], 'colspan': 1, 'covered': [], 'rowspan': 1, 'value': 'x'}], 'plain': [['r0', 'a'], ['r0', 'b'], ['r1', 'a']]}{'merges': [{'anchor': ['r1', 'b'], 'colspan': 1, 'covered': [], 'rowspan': 1, 'value': 'x'}], 'plain': [['r0', 'a'], ['r0', 'b'], ['r1', 'a']]}Passed
unmerged grid{'merges': [], 'plain': [['r0', 'a'], ['r0', 'b'], ['r1', 'a'], ['r1', 'b']]}{'merges': [], 'plain': [['r0', 'a'], ['r0', 'b'], ['r1', 'a'], ['r1', 'b']]}Passed

SHA-256 / 513f2c9a9c3a7ad3daec07864c3318145a8c6c8920526982202f2d1a99aaec6f

Verification & scope

Source axes have unique IDs; anchor origins are valid source indices and spans are positive integers. Deterministic offline table UI model; no browser, DOM, framework, or standards conformance is claimed. 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:42:56.951339+00:00.

Case digest / 46e2ff66f786060e621d848be6b882337af77297caaf6d50e2a893bec1ba5f11