FA-79521 / Barcode symbology encoding / Open access
ITF pads odd-length data with a trailing zero · case 01
A five-digit value 12345 scans as 123450, changing its magnitude.
ROOT CAUSE
The pad digit is appended instead of prepended.
VERIFIED REPAIR
Prepend a zero so the value is unchanged.
Unsuccessful approach: Dropping the last digit loses data.
Case contract
Encode ASCII digits as Interleaved 2 of 5 element widths (narrow 1, wide = ratio in {2, 2.5, 3}). An odd-length input gets a leading 0. Start is narrow bar/space/bar/space; each digit pair interleaves the first digit's pattern in the bars with the second digit's pattern in the spaces; stop is wide bar, narrow space, narrow bar. Digit patterns use weights 1,2,4,7 plus parity (0 = NNWWN). Invalid input returns None.
Why this case matters
Retail, logistics, pharmacy and document workflows depend on encoders that produce exactly the module pattern, code-set switches, separators and quiet zones scanners expect; one misplaced module or separator makes a label unreadable or, worse, scan as different data.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(digits, ratio):
if not digits or not all(c in '0123456789' for c in digits) or ratio not in (2, 2.5, 3):
return None
P = {'0': 'NNWWN', '1': 'WNNNW', '2': 'NWNNW', '3': 'WWNNN', '4': 'NNWNW',
'5': 'WNWNN', '6': 'NWWNN', '7': 'NNNWW', '8': 'WNNWN', '9': 'NWNWN'}
if len(digits) % 2:
digits = digits + '0'
wid = {'N': 1, 'W': ratio}
out = [1, 1, 1, 1]
for i in range(0, len(digits), 2):
a, b = P[digits[i]], P[digits[i + 1]]
for k in range(5):
out.append(wid[a[k]])
out.append(wid[b[k]])
out += [ratio, 1, 1]
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[('7', 3), [1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 3, 1, 3, 3, 1, 1]], [('8', 2.5), [1, 1, 1, 1, 1, 2.5, 1, 1, 2.5, 1, 2.5, 2.5, 1, 1, 2.5, 1, 1]], [('809220', 3), [1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 3, 3, 1, 3, 1, 1]], [('596257', 4), None], [('37775', 4), None], [('683', 4), None], [('960081', 3), [1, 1, 1, 1, 1, 1, 3, 3, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 1, 1, 3, 3, 1, 1, 1, 1, 3, 1, 1, 3, 3, 1, 1]], [('2', 2.5), [1, 1, 1, 1, 1, 1, 1, 2.5, 2.5, 1, 2.5, 1, 1, 2.5, 2.5, 1, 1]]], [[('954', 3), [1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 3, 3, 1, 1, 3, 1, 1, 1, 3, 3, 1, 1, 1, 3, 3, 1, 1]], [('284', 3), [1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 3, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 3, 3, 1, 1]], [('746905', 3), [1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 3, 3, 1, 1, 3, 3, 3, 1, 1, 3, 1, 1, 1, 3, 1, 1, 3, 3, 3, 1, 1, 1, 3, 1, 1]], [('83883', 4), None], [('246919', 2), [1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 1, 2, 2, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1, 2, 2, 1, 2, 1, 1]], [('6812', 2), [1, 1, 1, 1, 1, 2, 2, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1]], [('6596', 2.5), [1, 1, 1, 1, 1, 2.5, 2.5, 1, 2.5, 2.5, 1, 1, 1, 1, 1, 1, 2.5, 2.5, 1, 2.5, 2.5, 1, 1, 1, 2.5, 1, 1]], [('76847', 3), [1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 3, 1, 3, 1, 3, 3, 1, 3, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 1, 3, 3, 3, 3, 1, 1]]], [[('26563', 2.5), [1, 1, 1, 1, 1, 1, 1, 2.5, 2.5, 1, 2.5, 1, 1, 2.5, 1, 2.5, 2.5, 1, 2.5, 2.5, 1, 1, 1, 1, 1, 2.5, 2.5, 2.5, 2.5, 1, 1, 1, 1, 1, 2.5, 1, 1]], [('0', 2), [1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 2, 1, 1]], [('539', 2.5), [1, 1, 1, 1, 1, 2.5, 1, 1, 2.5, 2.5, 2.5, 1, 1, 1, 2.5, 1, 2.5, 2.5, 1, 1, 1, 2.5, 1, 1, 2.5, 1, 1]], [('063', 4), None], [('205464', 2), [1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 1, 2, 2, 1, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 1, 2, 2, 1, 1]], [('313090', 2), [1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 2, 1, 1, 2, 1, 2, 1, 1, 1, 1, 2, 1, 1, 2, 2, 2, 1, 1, 2, 1, 1]], [('3529', 3), [1, 1, 1, 1, 3, 3, 3, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 3, 3, 1, 3, 1, 1]], [('8', 3), [1, 1, 1, 1, 1, 3, 1, 1, 3, 1, 3, 3, 1, 1, 3, 1, 1]]], [[('28926', 3), [1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 3, 1, 1, 3, 3, 1, 1, 3, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 3, 1, 1, 3, 1, 3, 1, 1]], [('03860', 2), [1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 2, 1, 1]], [('7573', 2), [1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 1, 2, 1, 1, 2, 1, 2, 1, 1, 2, 1, 2, 1, 2, 1, 1]], [('26127', 4), None], [('6298', 3), [1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 3, 1, 3, 3, 1, 1, 1, 3, 3, 1, 1, 3, 1, 1]], [('866370', 2), [1, 1, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2, 1, 1]], [('6592', 2.5), [1, 1, 1, 1, 1, 2.5, 2.5, 1, 2.5, 2.5, 1, 1, 1, 1, 1, 1, 2.5, 2.5, 1, 1, 2.5, 1, 1, 2.5, 2.5, 1, 1]], [('2', 2.5), [1, 1, 1, 1, 1, 1, 1, 2.5, 2.5, 1, 2.5, 1, 1, 2.5, 2.5, 1, 1]]], [[('50677', 2.5), [1, 1, 1, 1, 1, 2.5, 1, 1, 2.5, 2.5, 2.5, 1, 1, 1, 1, 1, 1, 2.5, 2.5, 2.5, 2.5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2.5, 2.5, 2.5, 2.5, 2.5, 1, 1]], [('5', 2), [1, 1, 1, 1, 1, 2, 1, 1, 2, 2, 2, 1, 1, 1, 2, 1, 1]], [('007422', 4), None], [('151516', 2.5), [1, 1, 1, 1, 2.5, 2.5, 1, 1, 1, 2.5, 1, 1, 2.5, 1, 2.5, 2.5, 1, 1, 1, 2.5, 1, 1, 2.5, 1, 2.5, 1, 1, 2.5, 1, 2.5, 1, 1, 2.5, 1, 2.5, 1, 1]], [('40', 2), [1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 2, 2, 1, 2, 1, 1]], [('87', 2), [1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 2, 2, 1, 1]], [('5650', 3), [1, 1, 1, 1, 3, 1, 1, 3, 3, 3, 1, 1, 1, 1, 3, 1, 1, 1, 3, 3, 1, 3, 1, 1, 3, 1, 1]], [('420', 3), [1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 3, 3, 1, 3, 1, 1]]]]
labels = ["regression: odd length padding side", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("%s %d" % (labels[i % len(labels)], i), 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: odd length padding side 0 | [1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 1, 3, 1, 1] | [1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 3, 1, 3, 3, 1, 1] | Failed |
| repair trap 1 | [1, 1, 1, 1, 2.5, 1, 1, 1, 1, 2.5, 2.5, 2.5, 1, 1, 2.5, 1, 1] | [1, 1, 1, 1, 1, 2.5, 1, 1, 2.5, 1, 2.5, 2.5, 1, 1, 2.5, 1, 1] | Failed |
| combined fault 2 | [1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 3, 3, 1, 3, 1, 1] | [1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 3, 3, 1, 3, 1, 1] | Passed |
| control 3 | None | None | Passed |
| control 4 | None | None | Passed |
| boundary 5 | None | None | Passed |
| boundary 6 | [1, 1, 1, 1, 1, 1, 3, 3, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 1, 1, 3, 3, 1, 1, 1, 1, 3, 1, 1, 3, 3, 1, 1] | [1, 1, 1, 1, 1, 1, 3, 3, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 1, 1, 3, 3, 1, 1, 1, 1, 3, 1, 1, 3, 3, 1, 1] | Passed |
| control 7 | [1, 1, 1, 1, 1, 1, 2.5, 1, 1, 2.5, 1, 2.5, 2.5, 1, 2.5, 1, 1] | [1, 1, 1, 1, 1, 1, 1, 2.5, 2.5, 1, 2.5, 1, 1, 2.5, 2.5, 1, 1] | Failed |
SHA-256 / 5d32eabd3db9eb2f678bf8255ba3d4939e102616760e8828b8a5b71cecbd7d68
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(digits, ratio):
if not digits or not all(c in '0123456789' for c in digits) or ratio not in (2, 2.5, 3):
return None
P = {'0': 'NNWWN', '1': 'WNNNW', '2': 'NWNNW', '3': 'WWNNN', '4': 'NNWNW',
'5': 'WNWNN', '6': 'NWWNN', '7': 'NNNWW', '8': 'WNNWN', '9': 'NWNWN'}
if len(digits) % 2:
digits = digits[:-1]
wid = {'N': 1, 'W': ratio}
out = [1, 1, 1, 1]
for i in range(0, len(digits), 2):
a, b = P[digits[i]], P[digits[i + 1]]
for k in range(5):
out.append(wid[a[k]])
out.append(wid[b[k]])
out += [ratio, 1, 1]
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[('7', 3), [1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 3, 1, 3, 3, 1, 1]], [('8', 2.5), [1, 1, 1, 1, 1, 2.5, 1, 1, 2.5, 1, 2.5, 2.5, 1, 1, 2.5, 1, 1]], [('809220', 3), [1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 3, 3, 1, 3, 1, 1]], [('596257', 4), None], [('37775', 4), None], [('683', 4), None], [('960081', 3), [1, 1, 1, 1, 1, 1, 3, 3, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 1, 1, 3, 3, 1, 1, 1, 1, 3, 1, 1, 3, 3, 1, 1]], [('2', 2.5), [1, 1, 1, 1, 1, 1, 1, 2.5, 2.5, 1, 2.5, 1, 1, 2.5, 2.5, 1, 1]]], [[('954', 3), [1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 3, 3, 1, 1, 3, 1, 1, 1, 3, 3, 1, 1, 1, 3, 3, 1, 1]], [('284', 3), [1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 3, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 3, 3, 1, 1]], [('746905', 3), [1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 3, 3, 1, 1, 3, 3, 3, 1, 1, 3, 1, 1, 1, 3, 1, 1, 3, 3, 3, 1, 1, 1, 3, 1, 1]], [('83883', 4), None], [('246919', 2), [1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 1, 2, 2, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1, 2, 2, 1, 2, 1, 1]], [('6812', 2), [1, 1, 1, 1, 1, 2, 2, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1]], [('6596', 2.5), [1, 1, 1, 1, 1, 2.5, 2.5, 1, 2.5, 2.5, 1, 1, 1, 1, 1, 1, 2.5, 2.5, 1, 2.5, 2.5, 1, 1, 1, 2.5, 1, 1]], [('76847', 3), [1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 3, 1, 3, 1, 3, 3, 1, 3, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 1, 3, 3, 3, 3, 1, 1]]], [[('26563', 2.5), [1, 1, 1, 1, 1, 1, 1, 2.5, 2.5, 1, 2.5, 1, 1, 2.5, 1, 2.5, 2.5, 1, 2.5, 2.5, 1, 1, 1, 1, 1, 2.5, 2.5, 2.5, 2.5, 1, 1, 1, 1, 1, 2.5, 1, 1]], [('0', 2), [1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 2, 1, 1]], [('539', 2.5), [1, 1, 1, 1, 1, 2.5, 1, 1, 2.5, 2.5, 2.5, 1, 1, 1, 2.5, 1, 2.5, 2.5, 1, 1, 1, 2.5, 1, 1, 2.5, 1, 1]], [('063', 4), None], [('205464', 2), [1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 1, 2, 2, 1, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 1, 2, 2, 1, 1]], [('313090', 2), [1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 2, 1, 1, 2, 1, 2, 1, 1, 1, 1, 2, 1, 1, 2, 2, 2, 1, 1, 2, 1, 1]], [('3529', 3), [1, 1, 1, 1, 3, 3, 3, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 3, 3, 1, 3, 1, 1]], [('8', 3), [1, 1, 1, 1, 1, 3, 1, 1, 3, 1, 3, 3, 1, 1, 3, 1, 1]]], [[('28926', 3), [1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 3, 1, 1, 3, 3, 1, 1, 3, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 3, 1, 1, 3, 1, 3, 1, 1]], [('03860', 2), [1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 2, 1, 1]], [('7573', 2), [1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 1, 2, 1, 1, 2, 1, 2, 1, 1, 2, 1, 2, 1, 2, 1, 1]], [('26127', 4), None], [('6298', 3), [1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 3, 1, 3, 3, 1, 1, 1, 3, 3, 1, 1, 3, 1, 1]], [('866370', 2), [1, 1, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2, 1, 1]], [('6592', 2.5), [1, 1, 1, 1, 1, 2.5, 2.5, 1, 2.5, 2.5, 1, 1, 1, 1, 1, 1, 2.5, 2.5, 1, 1, 2.5, 1, 1, 2.5, 2.5, 1, 1]], [('2', 2.5), [1, 1, 1, 1, 1, 1, 1, 2.5, 2.5, 1, 2.5, 1, 1, 2.5, 2.5, 1, 1]]], [[('50677', 2.5), [1, 1, 1, 1, 1, 2.5, 1, 1, 2.5, 2.5, 2.5, 1, 1, 1, 1, 1, 1, 2.5, 2.5, 2.5, 2.5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2.5, 2.5, 2.5, 2.5, 2.5, 1, 1]], [('5', 2), [1, 1, 1, 1, 1, 2, 1, 1, 2, 2, 2, 1, 1, 1, 2, 1, 1]], [('007422', 4), None], [('151516', 2.5), [1, 1, 1, 1, 2.5, 2.5, 1, 1, 1, 2.5, 1, 1, 2.5, 1, 2.5, 2.5, 1, 1, 1, 2.5, 1, 1, 2.5, 1, 2.5, 1, 1, 2.5, 1, 2.5, 1, 1, 2.5, 1, 2.5, 1, 1]], [('40', 2), [1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 2, 2, 1, 2, 1, 1]], [('87', 2), [1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 2, 2, 1, 1]], [('5650', 3), [1, 1, 1, 1, 3, 1, 1, 3, 3, 3, 1, 1, 1, 1, 3, 1, 1, 1, 3, 3, 1, 3, 1, 1, 3, 1, 1]], [('420', 3), [1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 3, 3, 1, 3, 1, 1]]]]
labels = ["regression: odd length padding side", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("%s %d" % (labels[i % len(labels)], i), 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: odd length padding side 0 | [1, 1, 1, 1, 3, 1, 1] | [1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 3, 1, 3, 3, 1, 1] | Failed |
| repair trap 1 | [1, 1, 1, 1, 2.5, 1, 1] | [1, 1, 1, 1, 1, 2.5, 1, 1, 2.5, 1, 2.5, 2.5, 1, 1, 2.5, 1, 1] | Failed |
| combined fault 2 | [1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 3, 3, 1, 3, 1, 1] | [1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 3, 3, 1, 3, 1, 1] | Passed |
| control 3 | None | None | Passed |
| control 4 | None | None | Passed |
| boundary 5 | None | None | Passed |
| boundary 6 | [1, 1, 1, 1, 1, 1, 3, 3, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 1, 1, 3, 3, 1, 1, 1, 1, 3, 1, 1, 3, 3, 1, 1] | [1, 1, 1, 1, 1, 1, 3, 3, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 1, 1, 3, 3, 1, 1, 1, 1, 3, 1, 1, 3, 3, 1, 1] | Passed |
| control 7 | [1, 1, 1, 1, 2.5, 1, 1] | [1, 1, 1, 1, 1, 1, 1, 2.5, 2.5, 1, 2.5, 1, 1, 2.5, 2.5, 1, 1] | Failed |
SHA-256 / 0dc9c205af1dcf899dfcadd7f896074c14d294c7eba0fbccebd39b0efa14f4a0
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(digits, ratio):
if not digits or not all(c in '0123456789' for c in digits) or ratio not in (2, 2.5, 3):
return None
P = {'0': 'NNWWN', '1': 'WNNNW', '2': 'NWNNW', '3': 'WWNNN', '4': 'NNWNW',
'5': 'WNWNN', '6': 'NWWNN', '7': 'NNNWW', '8': 'WNNWN', '9': 'NWNWN'}
if len(digits) % 2:
digits = '0' + digits
wid = {'N': 1, 'W': ratio}
out = [1, 1, 1, 1]
for i in range(0, len(digits), 2):
a, b = P[digits[i]], P[digits[i + 1]]
for k in range(5):
out.append(wid[a[k]])
out.append(wid[b[k]])
out += [ratio, 1, 1]
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[('7', 3), [1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 3, 1, 3, 3, 1, 1]], [('8', 2.5), [1, 1, 1, 1, 1, 2.5, 1, 1, 2.5, 1, 2.5, 2.5, 1, 1, 2.5, 1, 1]], [('809220', 3), [1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 3, 3, 1, 3, 1, 1]], [('596257', 4), None], [('37775', 4), None], [('683', 4), None], [('960081', 3), [1, 1, 1, 1, 1, 1, 3, 3, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 1, 1, 3, 3, 1, 1, 1, 1, 3, 1, 1, 3, 3, 1, 1]], [('2', 2.5), [1, 1, 1, 1, 1, 1, 1, 2.5, 2.5, 1, 2.5, 1, 1, 2.5, 2.5, 1, 1]]], [[('954', 3), [1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 3, 3, 1, 1, 3, 1, 1, 1, 3, 3, 1, 1, 1, 3, 3, 1, 1]], [('284', 3), [1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 3, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 3, 3, 1, 1]], [('746905', 3), [1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 3, 3, 1, 1, 3, 3, 3, 1, 1, 3, 1, 1, 1, 3, 1, 1, 3, 3, 3, 1, 1, 1, 3, 1, 1]], [('83883', 4), None], [('246919', 2), [1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 1, 2, 2, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1, 2, 2, 1, 2, 1, 1]], [('6812', 2), [1, 1, 1, 1, 1, 2, 2, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1]], [('6596', 2.5), [1, 1, 1, 1, 1, 2.5, 2.5, 1, 2.5, 2.5, 1, 1, 1, 1, 1, 1, 2.5, 2.5, 1, 2.5, 2.5, 1, 1, 1, 2.5, 1, 1]], [('76847', 3), [1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 3, 1, 3, 1, 3, 3, 1, 3, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 1, 3, 3, 3, 3, 1, 1]]], [[('26563', 2.5), [1, 1, 1, 1, 1, 1, 1, 2.5, 2.5, 1, 2.5, 1, 1, 2.5, 1, 2.5, 2.5, 1, 2.5, 2.5, 1, 1, 1, 1, 1, 2.5, 2.5, 2.5, 2.5, 1, 1, 1, 1, 1, 2.5, 1, 1]], [('0', 2), [1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 2, 1, 1]], [('539', 2.5), [1, 1, 1, 1, 1, 2.5, 1, 1, 2.5, 2.5, 2.5, 1, 1, 1, 2.5, 1, 2.5, 2.5, 1, 1, 1, 2.5, 1, 1, 2.5, 1, 1]], [('063', 4), None], [('205464', 2), [1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 1, 2, 2, 1, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 1, 2, 2, 1, 1]], [('313090', 2), [1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 2, 1, 1, 2, 1, 2, 1, 1, 1, 1, 2, 1, 1, 2, 2, 2, 1, 1, 2, 1, 1]], [('3529', 3), [1, 1, 1, 1, 3, 3, 3, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 3, 3, 1, 3, 1, 1]], [('8', 3), [1, 1, 1, 1, 1, 3, 1, 1, 3, 1, 3, 3, 1, 1, 3, 1, 1]]], [[('28926', 3), [1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 3, 1, 1, 3, 3, 1, 1, 3, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 3, 1, 1, 3, 1, 3, 1, 1]], [('03860', 2), [1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 2, 1, 1]], [('7573', 2), [1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 1, 2, 1, 1, 2, 1, 2, 1, 1, 2, 1, 2, 1, 2, 1, 1]], [('26127', 4), None], [('6298', 3), [1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 3, 1, 3, 3, 1, 1, 1, 3, 3, 1, 1, 3, 1, 1]], [('866370', 2), [1, 1, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2, 1, 1]], [('6592', 2.5), [1, 1, 1, 1, 1, 2.5, 2.5, 1, 2.5, 2.5, 1, 1, 1, 1, 1, 1, 2.5, 2.5, 1, 1, 2.5, 1, 1, 2.5, 2.5, 1, 1]], [('2', 2.5), [1, 1, 1, 1, 1, 1, 1, 2.5, 2.5, 1, 2.5, 1, 1, 2.5, 2.5, 1, 1]]], [[('50677', 2.5), [1, 1, 1, 1, 1, 2.5, 1, 1, 2.5, 2.5, 2.5, 1, 1, 1, 1, 1, 1, 2.5, 2.5, 2.5, 2.5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2.5, 2.5, 2.5, 2.5, 2.5, 1, 1]], [('5', 2), [1, 1, 1, 1, 1, 2, 1, 1, 2, 2, 2, 1, 1, 1, 2, 1, 1]], [('007422', 4), None], [('151516', 2.5), [1, 1, 1, 1, 2.5, 2.5, 1, 1, 1, 2.5, 1, 1, 2.5, 1, 2.5, 2.5, 1, 1, 1, 2.5, 1, 1, 2.5, 1, 2.5, 1, 1, 2.5, 1, 2.5, 1, 1, 2.5, 1, 2.5, 1, 1]], [('40', 2), [1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 2, 2, 1, 2, 1, 1]], [('87', 2), [1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 2, 2, 1, 1]], [('5650', 3), [1, 1, 1, 1, 3, 1, 1, 3, 3, 3, 1, 1, 1, 1, 3, 1, 1, 1, 3, 3, 1, 3, 1, 1, 3, 1, 1]], [('420', 3), [1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 3, 3, 1, 3, 1, 1]]]]
labels = ["regression: odd length padding side", "repair trap", "combined fault", "control", "control", "boundary", "boundary", "control"]
for i, (args, expected) in enumerate(fixtures[N-1]):
check("%s %d" % (labels[i % len(labels)], i), 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: odd length padding side 0 | [1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 3, 1, 3, 3, 1, 1] | [1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 3, 3, 1, 3, 3, 1, 1] | Passed |
| repair trap 1 | [1, 1, 1, 1, 1, 2.5, 1, 1, 2.5, 1, 2.5, 2.5, 1, 1, 2.5, 1, 1] | [1, 1, 1, 1, 1, 2.5, 1, 1, 2.5, 1, 2.5, 2.5, 1, 1, 2.5, 1, 1] | Passed |
| combined fault 2 | [1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 3, 3, 1, 3, 1, 1] | [1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 3, 3, 1, 3, 1, 1] | Passed |
| control 3 | None | None | Passed |
| control 4 | None | None | Passed |
| boundary 5 | None | None | Passed |
| boundary 6 | [1, 1, 1, 1, 1, 1, 3, 3, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 1, 1, 3, 3, 1, 1, 1, 1, 3, 1, 1, 3, 3, 1, 1] | [1, 1, 1, 1, 1, 1, 3, 3, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 1, 1, 3, 3, 1, 1, 1, 1, 3, 1, 1, 3, 3, 1, 1] | Passed |
| control 7 | [1, 1, 1, 1, 1, 1, 1, 2.5, 2.5, 1, 2.5, 1, 1, 2.5, 2.5, 1, 1] | [1, 1, 1, 1, 1, 1, 1, 2.5, 2.5, 1, 2.5, 1, 1, 2.5, 2.5, 1, 1] | Passed |
SHA-256 / a02536072776e2f08c4ac81abf11f3638a291431fac1fe78b644390edf2a542c
Verification & scope
A deterministic bounded teaching model with a stipulated contract; it makes no claim of conformance to any published specification. 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:49:45.297058+00:00.
Case digest / 6f7659960f8020582e3a37ee58ef7bbe84658e7cd69f2f564309cb921913bf94