FAILURE MAP
← Case archive

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

Flat crochet circle planner: last round count · case 01

A double crochet circle claims only 6 increases per round.

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

ROOT CAUSE

Increases per round assume the single crochet rate for every stitch type.

VERIFIED REPAIR

Last round has base*rounds stitches.

Unsuccessful approach: Counting one extra round overstates the final round.

Case contract

Base stitches per round: sc 6, hdc 8, dc 12 (others -> "error: stitch"). Each round adds one round height to the radius. rounds = ceiling(diameter/(2*height)). Round k has base*k stitches. Return [rounds, stitches in last round, total stitches base*rounds*(rounds+1)/2].

Why this case matters

Amigurumi and rug patterns size flat circles by rounds of evenly spaced increases.

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(stitch, diameter, round_height):
    BASE = {'sc': 6, 'hdc': 8, 'dc': 12}
    if stitch not in BASE:
        return 'error: stitch'
    h = Fraction(round_height)
    rounds = math.ceil(Fraction(diameter) / (2 * h))
    b = BASE[stitch]
    return [rounds, b + 6 * (rounds - 1), b * rounds * (rounds + 1) // 2]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['coaster', ['sc', 10, '0.5'], [10, 60, 330]], ['dc mat', ['dc', 30, '1.5'], [10, 120, 660]],
  ['treble unknown', ['tr', 10, '1'], 'error: stitch'],
  ['regression: last round count', ['dc', 10, '1.5'], [4, 48, 120]],
  ['repair check: last round count', ['sc', 10, '1.5'], [4, 24, 60]],
  ['generated control 1', ['dc', 15, '0.75'], [10, 120, 660]],
  ['generated control 2', ['tr', 30, '1.5'], 'error: stitch'],
  ['generated control 3', ['dc', 12, '0.5'], [12, 144, 936]]],
 [['dc mat', ['dc', 30, '1.5'], [10, 120, 660]], ['treble unknown', ['tr', 10, '1'], 'error: stitch'],
  ['coaster', ['sc', 10, '0.5'], [10, 60, 330]],
  ['repair check: last round count', ['hdc', 5, '0.75'], [4, 32, 80]],
  ['generated control 1', ['tr', 15, '0.75'], 'error: stitch'],
  ['generated control 2', ['tr', 10, '2'], 'error: stitch'],
  ['generated control 3', ['tr', 15, '1'], 'error: stitch'],
  ['generated control 4', ['sc', 5, '0.75'], [4, 24, 60]]],
 [['treble unknown', ['tr', 10, '1'], 'error: stitch'], ['coaster', ['sc', 10, '0.5'], [10, 60, 330]],
  ['dc mat', ['dc', 30, '1.5'], [10, 120, 660]],
  ['regression: last round count', ['dc', 12, '0.75'], [8, 96, 432]],
  ['repair check: last round count', ['hdc', 20, '0.5'], [20, 160, 1680]],
  ['generated control 1', ['tr', 10, '0.5'], 'error: stitch'],
  ['generated control 2', ['tr', 15, '1.5'], 'error: stitch'],
  ['generated control 3', ['dc', 5, '1.5'], [2, 24, 36]]],
 [['coaster', ['sc', 10, '0.5'], [10, 60, 330]], ['dc mat', ['dc', 30, '1.5'], [10, 120, 660]],
  ['treble unknown', ['tr', 10, '1'], 'error: stitch'],
  ['regression: last round count', ['hdc', 5, '1.5'], [2, 16, 24]],
  ['repair check: last round count', ['sc', 30, '1.5'], [10, 60, 330]],
  ['generated control 1', ['sc', 15, '1'], [8, 48, 216]],
  ['generated control 2', ['tr', 5, '0.5'], 'error: stitch'],
  ['generated control 3', ['tr', 20, '1.5'], 'error: stitch']],
 [['dc mat', ['dc', 30, '1.5'], [10, 120, 660]], ['treble unknown', ['tr', 10, '1'], 'error: stitch'],
  ['coaster', ['sc', 10, '0.5'], [10, 60, 330]],
  ['regression: last round count', ['hdc', 12, '1.5'], [4, 32, 80]],
  ['repair check: last round count', ['sc', 10, '1'], [5, 30, 90]],
  ['generated control 1', ['dc', 30, '2'], [8, 96, 432]],
  ['generated control 2', ['tr', 30, '1.5'], 'error: stitch'],
  ['generated control 3', ['dc', 15, '0.75'], [10, 120, 660]]]]
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
coaster[10, 60, 330][10, 60, 330]Passed
dc mat[10, 66, 660][10, 120, 660]Failed
treble unknownerror: stitcherror: stitchPassed
regression: last round count[4, 30, 120][4, 48, 120]Failed
repair check: last round count[4, 24, 60][4, 24, 60]Passed
generated control 1[10, 66, 660][10, 120, 660]Failed
generated control 2error: stitcherror: stitchPassed
generated control 3[12, 78, 936][12, 144, 936]Failed

SHA-256 / d5ca42dff3b1ad0a3ac086e86301a6599f9fe095c173dea824c8e046f9bf93e0

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(stitch, diameter, round_height):
    BASE = {'sc': 6, 'hdc': 8, 'dc': 12}
    if stitch not in BASE:
        return 'error: stitch'
    h = Fraction(round_height)
    rounds = math.ceil(Fraction(diameter) / (2 * h))
    b = BASE[stitch]
    return [rounds, b * (rounds + 1), b * rounds * (rounds + 1) // 2]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['coaster', ['sc', 10, '0.5'], [10, 60, 330]], ['dc mat', ['dc', 30, '1.5'], [10, 120, 660]],
  ['treble unknown', ['tr', 10, '1'], 'error: stitch'],
  ['regression: last round count', ['dc', 10, '1.5'], [4, 48, 120]],
  ['repair check: last round count', ['sc', 10, '1.5'], [4, 24, 60]],
  ['generated control 1', ['dc', 15, '0.75'], [10, 120, 660]],
  ['generated control 2', ['tr', 30, '1.5'], 'error: stitch'],
  ['generated control 3', ['dc', 12, '0.5'], [12, 144, 936]]],
 [['dc mat', ['dc', 30, '1.5'], [10, 120, 660]], ['treble unknown', ['tr', 10, '1'], 'error: stitch'],
  ['coaster', ['sc', 10, '0.5'], [10, 60, 330]],
  ['repair check: last round count', ['hdc', 5, '0.75'], [4, 32, 80]],
  ['generated control 1', ['tr', 15, '0.75'], 'error: stitch'],
  ['generated control 2', ['tr', 10, '2'], 'error: stitch'],
  ['generated control 3', ['tr', 15, '1'], 'error: stitch'],
  ['generated control 4', ['sc', 5, '0.75'], [4, 24, 60]]],
 [['treble unknown', ['tr', 10, '1'], 'error: stitch'], ['coaster', ['sc', 10, '0.5'], [10, 60, 330]],
  ['dc mat', ['dc', 30, '1.5'], [10, 120, 660]],
  ['regression: last round count', ['dc', 12, '0.75'], [8, 96, 432]],
  ['repair check: last round count', ['hdc', 20, '0.5'], [20, 160, 1680]],
  ['generated control 1', ['tr', 10, '0.5'], 'error: stitch'],
  ['generated control 2', ['tr', 15, '1.5'], 'error: stitch'],
  ['generated control 3', ['dc', 5, '1.5'], [2, 24, 36]]],
 [['coaster', ['sc', 10, '0.5'], [10, 60, 330]], ['dc mat', ['dc', 30, '1.5'], [10, 120, 660]],
  ['treble unknown', ['tr', 10, '1'], 'error: stitch'],
  ['regression: last round count', ['hdc', 5, '1.5'], [2, 16, 24]],
  ['repair check: last round count', ['sc', 30, '1.5'], [10, 60, 330]],
  ['generated control 1', ['sc', 15, '1'], [8, 48, 216]],
  ['generated control 2', ['tr', 5, '0.5'], 'error: stitch'],
  ['generated control 3', ['tr', 20, '1.5'], 'error: stitch']],
 [['dc mat', ['dc', 30, '1.5'], [10, 120, 660]], ['treble unknown', ['tr', 10, '1'], 'error: stitch'],
  ['coaster', ['sc', 10, '0.5'], [10, 60, 330]],
  ['regression: last round count', ['hdc', 12, '1.5'], [4, 32, 80]],
  ['repair check: last round count', ['sc', 10, '1'], [5, 30, 90]],
  ['generated control 1', ['dc', 30, '2'], [8, 96, 432]],
  ['generated control 2', ['tr', 30, '1.5'], 'error: stitch'],
  ['generated control 3', ['dc', 15, '0.75'], [10, 120, 660]]]]
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
coaster[10, 66, 330][10, 60, 330]Failed
dc mat[10, 132, 660][10, 120, 660]Failed
treble unknownerror: stitcherror: stitchPassed
regression: last round count[4, 60, 120][4, 48, 120]Failed
repair check: last round count[4, 30, 60][4, 24, 60]Failed
generated control 1[10, 132, 660][10, 120, 660]Failed
generated control 2error: stitcherror: stitchPassed
generated control 3[12, 156, 936][12, 144, 936]Failed

SHA-256 / a633e23709ddfcdfbda202db3b3de6b501e422b80c4851f7fa9f4d186e6f6f8c

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(stitch, diameter, round_height):
    BASE = {'sc': 6, 'hdc': 8, 'dc': 12}
    if stitch not in BASE:
        return 'error: stitch'
    h = Fraction(round_height)
    rounds = math.ceil(Fraction(diameter) / (2 * h))
    b = BASE[stitch]
    return [rounds, b * rounds, b * rounds * (rounds + 1) // 2]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['coaster', ['sc', 10, '0.5'], [10, 60, 330]], ['dc mat', ['dc', 30, '1.5'], [10, 120, 660]],
  ['treble unknown', ['tr', 10, '1'], 'error: stitch'],
  ['regression: last round count', ['dc', 10, '1.5'], [4, 48, 120]],
  ['repair check: last round count', ['sc', 10, '1.5'], [4, 24, 60]],
  ['generated control 1', ['dc', 15, '0.75'], [10, 120, 660]],
  ['generated control 2', ['tr', 30, '1.5'], 'error: stitch'],
  ['generated control 3', ['dc', 12, '0.5'], [12, 144, 936]]],
 [['dc mat', ['dc', 30, '1.5'], [10, 120, 660]], ['treble unknown', ['tr', 10, '1'], 'error: stitch'],
  ['coaster', ['sc', 10, '0.5'], [10, 60, 330]],
  ['repair check: last round count', ['hdc', 5, '0.75'], [4, 32, 80]],
  ['generated control 1', ['tr', 15, '0.75'], 'error: stitch'],
  ['generated control 2', ['tr', 10, '2'], 'error: stitch'],
  ['generated control 3', ['tr', 15, '1'], 'error: stitch'],
  ['generated control 4', ['sc', 5, '0.75'], [4, 24, 60]]],
 [['treble unknown', ['tr', 10, '1'], 'error: stitch'], ['coaster', ['sc', 10, '0.5'], [10, 60, 330]],
  ['dc mat', ['dc', 30, '1.5'], [10, 120, 660]],
  ['regression: last round count', ['dc', 12, '0.75'], [8, 96, 432]],
  ['repair check: last round count', ['hdc', 20, '0.5'], [20, 160, 1680]],
  ['generated control 1', ['tr', 10, '0.5'], 'error: stitch'],
  ['generated control 2', ['tr', 15, '1.5'], 'error: stitch'],
  ['generated control 3', ['dc', 5, '1.5'], [2, 24, 36]]],
 [['coaster', ['sc', 10, '0.5'], [10, 60, 330]], ['dc mat', ['dc', 30, '1.5'], [10, 120, 660]],
  ['treble unknown', ['tr', 10, '1'], 'error: stitch'],
  ['regression: last round count', ['hdc', 5, '1.5'], [2, 16, 24]],
  ['repair check: last round count', ['sc', 30, '1.5'], [10, 60, 330]],
  ['generated control 1', ['sc', 15, '1'], [8, 48, 216]],
  ['generated control 2', ['tr', 5, '0.5'], 'error: stitch'],
  ['generated control 3', ['tr', 20, '1.5'], 'error: stitch']],
 [['dc mat', ['dc', 30, '1.5'], [10, 120, 660]], ['treble unknown', ['tr', 10, '1'], 'error: stitch'],
  ['coaster', ['sc', 10, '0.5'], [10, 60, 330]],
  ['regression: last round count', ['hdc', 12, '1.5'], [4, 32, 80]],
  ['repair check: last round count', ['sc', 10, '1'], [5, 30, 90]],
  ['generated control 1', ['dc', 30, '2'], [8, 96, 432]],
  ['generated control 2', ['tr', 30, '1.5'], 'error: stitch'],
  ['generated control 3', ['dc', 15, '0.75'], [10, 120, 660]]]]
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
coaster[10, 60, 330][10, 60, 330]Passed
dc mat[10, 120, 660][10, 120, 660]Passed
treble unknownerror: stitcherror: stitchPassed
regression: last round count[4, 48, 120][4, 48, 120]Passed
repair check: last round count[4, 24, 60][4, 24, 60]Passed
generated control 1[10, 120, 660][10, 120, 660]Passed
generated control 2error: stitcherror: stitchPassed
generated control 3[12, 144, 936][12, 144, 936]Passed

SHA-256 / 9f9fba4ec548fc7612aa39c32a7c6f888ceb542a4d444948ac219a234d796e11

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:34.180168+00:00.

Case digest / 9cd47144ad4e39de7dc521b4088f37b9ef1c5da6293207b4f67d8d60ffffd73a