FAILURE MAP
← Case archive

FA-97581 / Knitting and sewing pattern grading / Open access

Cutting layout fabric length: row overflow test · case 01

Pieces that exactly fill the width are pushed to a new row.

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

ROOT CAUSE

An exact fit is treated as overflow.

VERIFIED REPAIR

Open a new row only when the piece would exceed the width.

Unsuccessful approach: Checking the row before adding the piece lets rows overflow.

Case contract

Pieces [w, h, qty] (cm; w across the fabric). A piece wider than the fabric is rotated if the fabric is not directional and its height fits, else "error: piece too wide". Expand qty, sort by (height, width) descending, then shelf-pack: start a new row when the row width plus the piece would exceed the fabric width; each row is as tall as its tallest piece. Return [length_cm, eighths_of_a_yard] with eighths = ceiling(length/91.44*8).

Why this case matters

Pattern envelopes and cutting planners estimate yardage from piece layouts and nap direction.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(pieces, width, directional):
    items = []
    for w, h, qty in pieces:
        for _ in range(qty):
            if w > width:
                if directional or h > width:
                    return 'error: piece too wide'
                w, h = h, w
            items.append((h, w))
    items.sort(reverse=True)
    length = 0
    row_w = 0
    row_h = 0
    for h, w in items:
        if row_w + w >= width:
            length += row_h
            row_w, row_h = 0, 0
        row_w += w
        row_h = max(row_h, h)
    length += row_h
    return [length, math.ceil(Fraction(length) / Fraction(9144, 100) * 8)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['two pieces one row', [[[70, 60, 2]], 140, False], [60, 6]],
  ['rotate wide piece', [[[150, 60, 1]], 140, False], [150, 14]],
  ['directional wide piece', [[[150, 60, 1]], 140, True], 'error: piece too wide'],
  ['regression: row overflow test', [[[40, 60, 2], [20, 80, 3]], 140, True], [80, 7]],
  ['repair check: row overflow test', [[[70, 60, 1], [40, 45, 1], [20, 45, 2], [70, 60, 1]], 110, True],
   [165, 15]],
  ['generated control 1', [[[110, 30, 3]], 140, True], [90, 8]],
  ['generated control 2', [[[70, 30, 3], [150, 80, 1]], 140, True], 'error: piece too wide'],
  ['generated control 3', [[[70, 45, 2], [110, 30, 1]], 110, False], [120, 11]]],
 [['rotate wide piece', [[[150, 60, 1]], 140, False], [150, 14]],
  ['directional wide piece', [[[150, 60, 1]], 140, True], 'error: piece too wide'],
  ['exact fit row', [[[55, 80, 2], [40, 45, 1]], 150, False], [80, 7]],
  ['regression: row overflow test', [[[55, 100, 2], [70, 30, 1], [20, 100, 1], [35, 100, 1]], 110, True],
   [230, 21]],
  ['repair check: row overflow test', [[[20, 45, 1], [40, 60, 1], [70, 45, 2], [70, 30, 1]], 140, True],
   [135, 12]],
  ['generated control 1', [[[35, 80, 1]], 140, False], [80, 7]],
  ['generated control 2', [[[35, 45, 1]], 140, False], [45, 4]],
  ['generated control 3', [[[55, 100, 2]], 150, False], [100, 9]]],
 [['directional wide piece', [[[150, 60, 1]], 140, True], 'error: piece too wide'],
  ['exact fit row', [[[55, 80, 2], [40, 45, 1]], 150, False], [80, 7]],
  ['two pieces one row', [[[70, 60, 2]], 140, False], [60, 6]],
  ['regression: row overflow test', [[[70, 60, 2], [35, 45, 3], [35, 30, 2]], 140, False], [135, 12]],
  ['repair check: row overflow test', [[[70, 30, 1], [40, 80, 2], [150, 100, 1], [150, 45, 1]], 140, False],
   [330, 29]],
  ['generated control 1', [[[20, 80, 1], [35, 60, 1]], 150, False], [80, 7]],
  ['generated control 2', [[[110, 100, 1], [110, 60, 1], [150, 30, 1], [55, 100, 2]], 150, False], [290, 26]],
  ['generated control 3', [[[35, 60, 2]], 150, False], [60, 6]]],
 [['exact fit row', [[[55, 80, 2], [40, 45, 1]], 150, False], [80, 7]],
  ['two pieces one row', [[[70, 60, 2]], 140, False], [60, 6]],
  ['rotate wide piece', [[[150, 60, 1]], 140, False], [150, 14]],
  ['regression: row overflow test', [[[70, 45, 2], [150, 45, 3]], 140, False], [195, 18]],
  ['repair check: row overflow test', [[[150, 100, 1], [70, 100, 1], [110, 30, 1], [70, 80, 3]], 150, False],
   [310, 28]],
  ['generated control 1', [[[40, 100, 3], [150, 60, 1], [40, 80, 1], [70, 60, 1]], 150, True], [300, 27]],
  ['generated control 2', [[[70, 45, 1], [55, 45, 2]], 140, True], [90, 8]],
  ['generated control 3', [[[35, 30, 2]], 150, False], [30, 3]]],
 [['two pieces one row', [[[70, 60, 2]], 140, False], [60, 6]],
  ['rotate wide piece', [[[150, 60, 1]], 140, False], [150, 14]],
  ['directional wide piece', [[[150, 60, 1]], 140, True], 'error: piece too wide'],
  ['regression: row overflow test', [[[70, 45, 1], [40, 100, 1]], 110, False], [100, 9]],
  ['repair check: row overflow test', [[[110, 45, 2], [40, 60, 2], [35, 100, 3], [150, 45, 3]], 150, False],
   [385, 34]],
  ['generated control 1', [[[150, 30, 1]], 140, True], 'error: piece too wide'],
  ['generated control 2', [[[35, 45, 2]], 110, False], [45, 4]],
  ['generated control 3', [[[35, 80, 1]], 150, False], [80, 7]]]]
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
two pieces one row[120, 11][60, 6]Failed
rotate wide piece[150, 14][150, 14]Passed
directional wide pieceerror: piece too wideerror: piece too widePassed
regression: row overflow test[140, 13][80, 7]Failed
repair check: row overflow test[165, 15][165, 15]Passed
generated control 1[90, 8][90, 8]Passed
generated control 2error: piece too wideerror: piece too widePassed
generated control 3[120, 11][120, 11]Passed

SHA-256 / 83dfb2234eeb901031775e208d185e3a96bc9ea0ddea6c4375d12b54c07a92ad

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(pieces, width, directional):
    items = []
    for w, h, qty in pieces:
        for _ in range(qty):
            if w > width:
                if directional or h > width:
                    return 'error: piece too wide'
                w, h = h, w
            items.append((h, w))
    items.sort(reverse=True)
    length = 0
    row_w = 0
    row_h = 0
    for h, w in items:
        if row_w > width:
            length += row_h
            row_w, row_h = 0, 0
        row_w += w
        row_h = max(row_h, h)
    length += row_h
    return [length, math.ceil(Fraction(length) / Fraction(9144, 100) * 8)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['two pieces one row', [[[70, 60, 2]], 140, False], [60, 6]],
  ['rotate wide piece', [[[150, 60, 1]], 140, False], [150, 14]],
  ['directional wide piece', [[[150, 60, 1]], 140, True], 'error: piece too wide'],
  ['regression: row overflow test', [[[40, 60, 2], [20, 80, 3]], 140, True], [80, 7]],
  ['repair check: row overflow test', [[[70, 60, 1], [40, 45, 1], [20, 45, 2], [70, 60, 1]], 110, True],
   [165, 15]],
  ['generated control 1', [[[110, 30, 3]], 140, True], [90, 8]],
  ['generated control 2', [[[70, 30, 3], [150, 80, 1]], 140, True], 'error: piece too wide'],
  ['generated control 3', [[[70, 45, 2], [110, 30, 1]], 110, False], [120, 11]]],
 [['rotate wide piece', [[[150, 60, 1]], 140, False], [150, 14]],
  ['directional wide piece', [[[150, 60, 1]], 140, True], 'error: piece too wide'],
  ['exact fit row', [[[55, 80, 2], [40, 45, 1]], 150, False], [80, 7]],
  ['regression: row overflow test', [[[55, 100, 2], [70, 30, 1], [20, 100, 1], [35, 100, 1]], 110, True],
   [230, 21]],
  ['repair check: row overflow test', [[[20, 45, 1], [40, 60, 1], [70, 45, 2], [70, 30, 1]], 140, True],
   [135, 12]],
  ['generated control 1', [[[35, 80, 1]], 140, False], [80, 7]],
  ['generated control 2', [[[35, 45, 1]], 140, False], [45, 4]],
  ['generated control 3', [[[55, 100, 2]], 150, False], [100, 9]]],
 [['directional wide piece', [[[150, 60, 1]], 140, True], 'error: piece too wide'],
  ['exact fit row', [[[55, 80, 2], [40, 45, 1]], 150, False], [80, 7]],
  ['two pieces one row', [[[70, 60, 2]], 140, False], [60, 6]],
  ['regression: row overflow test', [[[70, 60, 2], [35, 45, 3], [35, 30, 2]], 140, False], [135, 12]],
  ['repair check: row overflow test', [[[70, 30, 1], [40, 80, 2], [150, 100, 1], [150, 45, 1]], 140, False],
   [330, 29]],
  ['generated control 1', [[[20, 80, 1], [35, 60, 1]], 150, False], [80, 7]],
  ['generated control 2', [[[110, 100, 1], [110, 60, 1], [150, 30, 1], [55, 100, 2]], 150, False], [290, 26]],
  ['generated control 3', [[[35, 60, 2]], 150, False], [60, 6]]],
 [['exact fit row', [[[55, 80, 2], [40, 45, 1]], 150, False], [80, 7]],
  ['two pieces one row', [[[70, 60, 2]], 140, False], [60, 6]],
  ['rotate wide piece', [[[150, 60, 1]], 140, False], [150, 14]],
  ['regression: row overflow test', [[[70, 45, 2], [150, 45, 3]], 140, False], [195, 18]],
  ['repair check: row overflow test', [[[150, 100, 1], [70, 100, 1], [110, 30, 1], [70, 80, 3]], 150, False],
   [310, 28]],
  ['generated control 1', [[[40, 100, 3], [150, 60, 1], [40, 80, 1], [70, 60, 1]], 150, True], [300, 27]],
  ['generated control 2', [[[70, 45, 1], [55, 45, 2]], 140, True], [90, 8]],
  ['generated control 3', [[[35, 30, 2]], 150, False], [30, 3]]],
 [['two pieces one row', [[[70, 60, 2]], 140, False], [60, 6]],
  ['rotate wide piece', [[[150, 60, 1]], 140, False], [150, 14]],
  ['directional wide piece', [[[150, 60, 1]], 140, True], 'error: piece too wide'],
  ['regression: row overflow test', [[[70, 45, 1], [40, 100, 1]], 110, False], [100, 9]],
  ['repair check: row overflow test', [[[110, 45, 2], [40, 60, 2], [35, 100, 3], [150, 45, 3]], 150, False],
   [385, 34]],
  ['generated control 1', [[[150, 30, 1]], 140, True], 'error: piece too wide'],
  ['generated control 2', [[[35, 45, 2]], 110, False], [45, 4]],
  ['generated control 3', [[[35, 80, 1]], 150, False], [80, 7]]]]
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
two pieces one row[60, 6][60, 6]Passed
rotate wide piece[150, 14][150, 14]Passed
directional wide pieceerror: piece too wideerror: piece too widePassed
regression: row overflow test[80, 7][80, 7]Passed
repair check: row overflow test[105, 10][165, 15]Failed
generated control 1[60, 6][90, 8]Failed
generated control 2error: piece too wideerror: piece too widePassed
generated control 3[75, 7][120, 11]Failed

SHA-256 / faadeeeeb095b461aaa91e05e69f18a2b821fc3ac21c51e5eda38cc4d2b76e8e

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(pieces, width, directional):
    items = []
    for w, h, qty in pieces:
        for _ in range(qty):
            if w > width:
                if directional or h > width:
                    return 'error: piece too wide'
                w, h = h, w
            items.append((h, w))
    items.sort(reverse=True)
    length = 0
    row_w = 0
    row_h = 0
    for h, w in items:
        if row_w + w > width:
            length += row_h
            row_w, row_h = 0, 0
        row_w += w
        row_h = max(row_h, h)
    length += row_h
    return [length, math.ceil(Fraction(length) / Fraction(9144, 100) * 8)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['two pieces one row', [[[70, 60, 2]], 140, False], [60, 6]],
  ['rotate wide piece', [[[150, 60, 1]], 140, False], [150, 14]],
  ['directional wide piece', [[[150, 60, 1]], 140, True], 'error: piece too wide'],
  ['regression: row overflow test', [[[40, 60, 2], [20, 80, 3]], 140, True], [80, 7]],
  ['repair check: row overflow test', [[[70, 60, 1], [40, 45, 1], [20, 45, 2], [70, 60, 1]], 110, True],
   [165, 15]],
  ['generated control 1', [[[110, 30, 3]], 140, True], [90, 8]],
  ['generated control 2', [[[70, 30, 3], [150, 80, 1]], 140, True], 'error: piece too wide'],
  ['generated control 3', [[[70, 45, 2], [110, 30, 1]], 110, False], [120, 11]]],
 [['rotate wide piece', [[[150, 60, 1]], 140, False], [150, 14]],
  ['directional wide piece', [[[150, 60, 1]], 140, True], 'error: piece too wide'],
  ['exact fit row', [[[55, 80, 2], [40, 45, 1]], 150, False], [80, 7]],
  ['regression: row overflow test', [[[55, 100, 2], [70, 30, 1], [20, 100, 1], [35, 100, 1]], 110, True],
   [230, 21]],
  ['repair check: row overflow test', [[[20, 45, 1], [40, 60, 1], [70, 45, 2], [70, 30, 1]], 140, True],
   [135, 12]],
  ['generated control 1', [[[35, 80, 1]], 140, False], [80, 7]],
  ['generated control 2', [[[35, 45, 1]], 140, False], [45, 4]],
  ['generated control 3', [[[55, 100, 2]], 150, False], [100, 9]]],
 [['directional wide piece', [[[150, 60, 1]], 140, True], 'error: piece too wide'],
  ['exact fit row', [[[55, 80, 2], [40, 45, 1]], 150, False], [80, 7]],
  ['two pieces one row', [[[70, 60, 2]], 140, False], [60, 6]],
  ['regression: row overflow test', [[[70, 60, 2], [35, 45, 3], [35, 30, 2]], 140, False], [135, 12]],
  ['repair check: row overflow test', [[[70, 30, 1], [40, 80, 2], [150, 100, 1], [150, 45, 1]], 140, False],
   [330, 29]],
  ['generated control 1', [[[20, 80, 1], [35, 60, 1]], 150, False], [80, 7]],
  ['generated control 2', [[[110, 100, 1], [110, 60, 1], [150, 30, 1], [55, 100, 2]], 150, False], [290, 26]],
  ['generated control 3', [[[35, 60, 2]], 150, False], [60, 6]]],
 [['exact fit row', [[[55, 80, 2], [40, 45, 1]], 150, False], [80, 7]],
  ['two pieces one row', [[[70, 60, 2]], 140, False], [60, 6]],
  ['rotate wide piece', [[[150, 60, 1]], 140, False], [150, 14]],
  ['regression: row overflow test', [[[70, 45, 2], [150, 45, 3]], 140, False], [195, 18]],
  ['repair check: row overflow test', [[[150, 100, 1], [70, 100, 1], [110, 30, 1], [70, 80, 3]], 150, False],
   [310, 28]],
  ['generated control 1', [[[40, 100, 3], [150, 60, 1], [40, 80, 1], [70, 60, 1]], 150, True], [300, 27]],
  ['generated control 2', [[[70, 45, 1], [55, 45, 2]], 140, True], [90, 8]],
  ['generated control 3', [[[35, 30, 2]], 150, False], [30, 3]]],
 [['two pieces one row', [[[70, 60, 2]], 140, False], [60, 6]],
  ['rotate wide piece', [[[150, 60, 1]], 140, False], [150, 14]],
  ['directional wide piece', [[[150, 60, 1]], 140, True], 'error: piece too wide'],
  ['regression: row overflow test', [[[70, 45, 1], [40, 100, 1]], 110, False], [100, 9]],
  ['repair check: row overflow test', [[[110, 45, 2], [40, 60, 2], [35, 100, 3], [150, 45, 3]], 150, False],
   [385, 34]],
  ['generated control 1', [[[150, 30, 1]], 140, True], 'error: piece too wide'],
  ['generated control 2', [[[35, 45, 2]], 110, False], [45, 4]],
  ['generated control 3', [[[35, 80, 1]], 150, False], [80, 7]]]]
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
two pieces one row[60, 6][60, 6]Passed
rotate wide piece[150, 14][150, 14]Passed
directional wide pieceerror: piece too wideerror: piece too widePassed
regression: row overflow test[80, 7][80, 7]Passed
repair check: row overflow test[165, 15][165, 15]Passed
generated control 1[90, 8][90, 8]Passed
generated control 2error: piece too wideerror: piece too widePassed
generated control 3[120, 11][120, 11]Passed

SHA-256 / 06dd84690b2d5092aee99b013d6a3d2aa4d46394b37e223555aae312c0e2cc96

Verification & scope

A deterministic toy contract stated in full here; it is a bounded teaching model, not an authoritative reference or standards implementation. 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:33.618868+00:00.

Case digest / 0172f09b7079c1ebe11d07443e792f535110cfeb1a5bfd968dce259cc1194ae2