FA-96111 / Postal address normalization / Open access
City-state-code last line parser: overlong digit runs are accepted as codes · case 01
"111019" is accepted as a postal code.
ROOT CAUSE
The basic code length is tested with >= 5.
VERIFIED REPAIR
Accept exactly five digits for the basic form.
Unsuccessful approach: Allowing five or nine bare digits still accepts an unhyphenated nine-digit run.
Case contract
Uppercase, turn commas into spaces and split. If the last token is 5 digits or 5 digits, hyphen, 4 digits it is the code and is removed. The new last token must be a state in the toy table (ZZ, QX, XJ or the spelled names ZEDLAND, QUIXOTA, XANJOR mapping to them) and at least one city token must precede it. Return [city, state code, postal code or ""] or None.
Why this case matters
Last lines are parsed from the right because city names have any number of words; a mistaken boundary moves words between city, state and code.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
STATES = {'ZZ': 'ZZ', 'QX': 'QX', 'XJ': 'XJ', 'ZEDLAND': 'ZZ', 'QUIXOTA': 'QX', 'XANJOR': 'XJ'}
t = x.upper().replace(',', ' ').split()
code = ''
if t and (len(t[-1]) >= 5 or (len(t[-1]) == 10 and t[-1][5] == '-')) and t[-1].replace('-', '').isdigit():
code = t.pop()
if len(t) < 2 or t[-1] not in STATES:
return None
state = STATES[t.pop()]
return [' '.join(t), state, code]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['comma and space', 'Faketown, ZZ 11101', ['FAKETOWN', 'ZZ', '11101']], ['comma without space', 'FAKETOWN,ZZ 11101', ['FAKETOWN', 'ZZ', '11101']], ['multi-word city with plus-four', 'New Faketown Heights, Qx 11101-1214', ['NEW FAKETOWN HEIGHTS', 'QX', '11101-1214']], ['spelled state without code', 'FAKETOWN Zedland', ['FAKETOWN', 'ZZ', '']], ['missing city', 'ZZ 11101', None], ['ten bare digits are not a code', 'FAKETOWN ZZ 1110112345', None], ['short plus-four is not a code', 'FAKETOWN ZZ 11101-6', None], ['six digits are not a code', 'FAKETOWN XJ 111019', None], ['nine bare digits are not a code', 'FAKETOWN XJ 111011234', None], ['unknown state', 'FAKETOWN YY 11101', None]], [['comma and space', 'Nowhereville, ZZ 22202', ['NOWHEREVILLE', 'ZZ', '22202']], ['comma without space', 'NOWHEREVILLE,ZZ 22202', ['NOWHEREVILLE', 'ZZ', '22202']], ['multi-word city with plus-four', 'New Nowhereville Heights, Qx 22202-1224', ['NEW NOWHEREVILLE HEIGHTS', 'QX', '22202-1224']], ['spelled state without code', 'NOWHEREVILLE Zedland', ['NOWHEREVILLE', 'ZZ', '']], ['missing city', 'ZZ 22202', None], ['ten bare digits are not a code', 'NOWHEREVILLE ZZ 2220212345', None], ['short plus-four is not a code', 'NOWHEREVILLE ZZ 22202-6', None], ['six digits are not a code', 'NOWHEREVILLE XJ 222029', None], ['nine bare digits are not a code', 'NOWHEREVILLE XJ 222022234', None], ['unknown state', 'NOWHEREVILLE YY 22202', None]], [['comma and space', 'Zorbleton, ZZ 33303', ['ZORBLETON', 'ZZ', '33303']], ['comma without space', 'ZORBLETON,ZZ 33303', ['ZORBLETON', 'ZZ', '33303']], ['multi-word city with plus-four', 'New Zorbleton Heights, Qx 33303-1234', ['NEW ZORBLETON HEIGHTS', 'QX', '33303-1234']], ['spelled state without code', 'ZORBLETON Zedland', ['ZORBLETON', 'ZZ', '']], ['missing city', 'ZZ 33303', None], ['ten bare digits are not a code', 'ZORBLETON ZZ 3330312345', None], ['short plus-four is not a code', 'ZORBLETON ZZ 33303-6', None], ['six digits are not a code', 'ZORBLETON XJ 333039', None], ['nine bare digits are not a code', 'ZORBLETON XJ 333033234', None], ['unknown state', 'ZORBLETON YY 33303', None]], [['comma and space', 'Quillby, ZZ 44404', ['QUILLBY', 'ZZ', '44404']], ['comma without space', 'QUILLBY,ZZ 44404', ['QUILLBY', 'ZZ', '44404']], ['multi-word city with plus-four', 'New Quillby Heights, Qx 44404-1244', ['NEW QUILLBY HEIGHTS', 'QX', '44404-1244']], ['spelled state without code', 'QUILLBY Zedland', ['QUILLBY', 'ZZ', '']], ['missing city', 'ZZ 44404', None], ['ten bare digits are not a code', 'QUILLBY ZZ 4440412345', None], ['short plus-four is not a code', 'QUILLBY ZZ 44404-6', None], ['six digits are not a code', 'QUILLBY XJ 444049', None], ['nine bare digits are not a code', 'QUILLBY XJ 444044234', None], ['unknown state', 'QUILLBY YY 44404', None]], [['comma and space', 'Spraxham, ZZ 55505', ['SPRAXHAM', 'ZZ', '55505']], ['comma without space', 'SPRAXHAM,ZZ 55505', ['SPRAXHAM', 'ZZ', '55505']], ['multi-word city with plus-four', 'New Spraxham Heights, Qx 55505-1254', ['NEW SPRAXHAM HEIGHTS', 'QX', '55505-1254']], ['spelled state without code', 'SPRAXHAM Zedland', ['SPRAXHAM', 'ZZ', '']], ['missing city', 'ZZ 55505', None], ['ten bare digits are not a code', 'SPRAXHAM ZZ 5550512345', None], ['short plus-four is not a code', 'SPRAXHAM ZZ 55505-6', None], ['six digits are not a code', 'SPRAXHAM XJ 555059', None], ['nine bare digits are not a code', 'SPRAXHAM XJ 555055234', None], ['unknown state', 'SPRAXHAM YY 55505', None]]]
for label, arg, expected in fixtures[N - 1]:
check(label, solve(arg), 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 |
|---|---|---|---|
| comma and space | ['FAKETOWN', 'ZZ', '11101'] | ['FAKETOWN', 'ZZ', '11101'] | Passed |
| comma without space | ['FAKETOWN', 'ZZ', '11101'] | ['FAKETOWN', 'ZZ', '11101'] | Passed |
| multi-word city with plus-four | ['NEW FAKETOWN HEIGHTS', 'QX', '11101-1214'] | ['NEW FAKETOWN HEIGHTS', 'QX', '11101-1214'] | Passed |
| spelled state without code | ['FAKETOWN', 'ZZ', ''] | ['FAKETOWN', 'ZZ', ''] | Passed |
| missing city | None | None | Passed |
| ten bare digits are not a code | ['FAKETOWN', 'ZZ', '1110112345'] | None | Failed |
| short plus-four is not a code | ['FAKETOWN', 'ZZ', '11101-6'] | None | Failed |
| six digits are not a code | ['FAKETOWN', 'XJ', '111019'] | None | Failed |
| nine bare digits are not a code | ['FAKETOWN', 'XJ', '111011234'] | None | Failed |
| unknown state | None | None | Passed |
SHA-256 / eabbc2915acdba17d6316ab40c17058b80d8ca925ec4f64da15f0c8123e5f16b
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
STATES = {'ZZ': 'ZZ', 'QX': 'QX', 'XJ': 'XJ', 'ZEDLAND': 'ZZ', 'QUIXOTA': 'QX', 'XANJOR': 'XJ'}
t = x.upper().replace(',', ' ').split()
code = ''
if t and (len(t[-1]) in (5, 9) or (len(t[-1]) == 10 and t[-1][5] == '-')) and t[-1].replace('-', '').isdigit():
code = t.pop()
if len(t) < 2 or t[-1] not in STATES:
return None
state = STATES[t.pop()]
return [' '.join(t), state, code]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['comma and space', 'Faketown, ZZ 11101', ['FAKETOWN', 'ZZ', '11101']], ['comma without space', 'FAKETOWN,ZZ 11101', ['FAKETOWN', 'ZZ', '11101']], ['multi-word city with plus-four', 'New Faketown Heights, Qx 11101-1214', ['NEW FAKETOWN HEIGHTS', 'QX', '11101-1214']], ['spelled state without code', 'FAKETOWN Zedland', ['FAKETOWN', 'ZZ', '']], ['missing city', 'ZZ 11101', None], ['ten bare digits are not a code', 'FAKETOWN ZZ 1110112345', None], ['short plus-four is not a code', 'FAKETOWN ZZ 11101-6', None], ['six digits are not a code', 'FAKETOWN XJ 111019', None], ['nine bare digits are not a code', 'FAKETOWN XJ 111011234', None], ['unknown state', 'FAKETOWN YY 11101', None]], [['comma and space', 'Nowhereville, ZZ 22202', ['NOWHEREVILLE', 'ZZ', '22202']], ['comma without space', 'NOWHEREVILLE,ZZ 22202', ['NOWHEREVILLE', 'ZZ', '22202']], ['multi-word city with plus-four', 'New Nowhereville Heights, Qx 22202-1224', ['NEW NOWHEREVILLE HEIGHTS', 'QX', '22202-1224']], ['spelled state without code', 'NOWHEREVILLE Zedland', ['NOWHEREVILLE', 'ZZ', '']], ['missing city', 'ZZ 22202', None], ['ten bare digits are not a code', 'NOWHEREVILLE ZZ 2220212345', None], ['short plus-four is not a code', 'NOWHEREVILLE ZZ 22202-6', None], ['six digits are not a code', 'NOWHEREVILLE XJ 222029', None], ['nine bare digits are not a code', 'NOWHEREVILLE XJ 222022234', None], ['unknown state', 'NOWHEREVILLE YY 22202', None]], [['comma and space', 'Zorbleton, ZZ 33303', ['ZORBLETON', 'ZZ', '33303']], ['comma without space', 'ZORBLETON,ZZ 33303', ['ZORBLETON', 'ZZ', '33303']], ['multi-word city with plus-four', 'New Zorbleton Heights, Qx 33303-1234', ['NEW ZORBLETON HEIGHTS', 'QX', '33303-1234']], ['spelled state without code', 'ZORBLETON Zedland', ['ZORBLETON', 'ZZ', '']], ['missing city', 'ZZ 33303', None], ['ten bare digits are not a code', 'ZORBLETON ZZ 3330312345', None], ['short plus-four is not a code', 'ZORBLETON ZZ 33303-6', None], ['six digits are not a code', 'ZORBLETON XJ 333039', None], ['nine bare digits are not a code', 'ZORBLETON XJ 333033234', None], ['unknown state', 'ZORBLETON YY 33303', None]], [['comma and space', 'Quillby, ZZ 44404', ['QUILLBY', 'ZZ', '44404']], ['comma without space', 'QUILLBY,ZZ 44404', ['QUILLBY', 'ZZ', '44404']], ['multi-word city with plus-four', 'New Quillby Heights, Qx 44404-1244', ['NEW QUILLBY HEIGHTS', 'QX', '44404-1244']], ['spelled state without code', 'QUILLBY Zedland', ['QUILLBY', 'ZZ', '']], ['missing city', 'ZZ 44404', None], ['ten bare digits are not a code', 'QUILLBY ZZ 4440412345', None], ['short plus-four is not a code', 'QUILLBY ZZ 44404-6', None], ['six digits are not a code', 'QUILLBY XJ 444049', None], ['nine bare digits are not a code', 'QUILLBY XJ 444044234', None], ['unknown state', 'QUILLBY YY 44404', None]], [['comma and space', 'Spraxham, ZZ 55505', ['SPRAXHAM', 'ZZ', '55505']], ['comma without space', 'SPRAXHAM,ZZ 55505', ['SPRAXHAM', 'ZZ', '55505']], ['multi-word city with plus-four', 'New Spraxham Heights, Qx 55505-1254', ['NEW SPRAXHAM HEIGHTS', 'QX', '55505-1254']], ['spelled state without code', 'SPRAXHAM Zedland', ['SPRAXHAM', 'ZZ', '']], ['missing city', 'ZZ 55505', None], ['ten bare digits are not a code', 'SPRAXHAM ZZ 5550512345', None], ['short plus-four is not a code', 'SPRAXHAM ZZ 55505-6', None], ['six digits are not a code', 'SPRAXHAM XJ 555059', None], ['nine bare digits are not a code', 'SPRAXHAM XJ 555055234', None], ['unknown state', 'SPRAXHAM YY 55505', None]]]
for label, arg, expected in fixtures[N - 1]:
check(label, solve(arg), 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 |
|---|---|---|---|
| comma and space | ['FAKETOWN', 'ZZ', '11101'] | ['FAKETOWN', 'ZZ', '11101'] | Passed |
| comma without space | ['FAKETOWN', 'ZZ', '11101'] | ['FAKETOWN', 'ZZ', '11101'] | Passed |
| multi-word city with plus-four | ['NEW FAKETOWN HEIGHTS', 'QX', '11101-1214'] | ['NEW FAKETOWN HEIGHTS', 'QX', '11101-1214'] | Passed |
| spelled state without code | ['FAKETOWN', 'ZZ', ''] | ['FAKETOWN', 'ZZ', ''] | Passed |
| missing city | None | None | Passed |
| ten bare digits are not a code | None | None | Passed |
| short plus-four is not a code | None | None | Passed |
| six digits are not a code | None | None | Passed |
| nine bare digits are not a code | ['FAKETOWN', 'XJ', '111011234'] | None | Failed |
| unknown state | None | None | Passed |
SHA-256 / 4684eeee50b6d5e7224cb1b651b546c53c5f92a6d368d001ecb19823dc6a5b1b
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
STATES = {'ZZ': 'ZZ', 'QX': 'QX', 'XJ': 'XJ', 'ZEDLAND': 'ZZ', 'QUIXOTA': 'QX', 'XANJOR': 'XJ'}
t = x.upper().replace(',', ' ').split()
code = ''
if t and (len(t[-1]) == 5 or (len(t[-1]) == 10 and t[-1][5] == '-')) and t[-1].replace('-', '').isdigit():
code = t.pop()
if len(t) < 2 or t[-1] not in STATES:
return None
state = STATES[t.pop()]
return [' '.join(t), state, code]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['comma and space', 'Faketown, ZZ 11101', ['FAKETOWN', 'ZZ', '11101']], ['comma without space', 'FAKETOWN,ZZ 11101', ['FAKETOWN', 'ZZ', '11101']], ['multi-word city with plus-four', 'New Faketown Heights, Qx 11101-1214', ['NEW FAKETOWN HEIGHTS', 'QX', '11101-1214']], ['spelled state without code', 'FAKETOWN Zedland', ['FAKETOWN', 'ZZ', '']], ['missing city', 'ZZ 11101', None], ['ten bare digits are not a code', 'FAKETOWN ZZ 1110112345', None], ['short plus-four is not a code', 'FAKETOWN ZZ 11101-6', None], ['six digits are not a code', 'FAKETOWN XJ 111019', None], ['nine bare digits are not a code', 'FAKETOWN XJ 111011234', None], ['unknown state', 'FAKETOWN YY 11101', None]], [['comma and space', 'Nowhereville, ZZ 22202', ['NOWHEREVILLE', 'ZZ', '22202']], ['comma without space', 'NOWHEREVILLE,ZZ 22202', ['NOWHEREVILLE', 'ZZ', '22202']], ['multi-word city with plus-four', 'New Nowhereville Heights, Qx 22202-1224', ['NEW NOWHEREVILLE HEIGHTS', 'QX', '22202-1224']], ['spelled state without code', 'NOWHEREVILLE Zedland', ['NOWHEREVILLE', 'ZZ', '']], ['missing city', 'ZZ 22202', None], ['ten bare digits are not a code', 'NOWHEREVILLE ZZ 2220212345', None], ['short plus-four is not a code', 'NOWHEREVILLE ZZ 22202-6', None], ['six digits are not a code', 'NOWHEREVILLE XJ 222029', None], ['nine bare digits are not a code', 'NOWHEREVILLE XJ 222022234', None], ['unknown state', 'NOWHEREVILLE YY 22202', None]], [['comma and space', 'Zorbleton, ZZ 33303', ['ZORBLETON', 'ZZ', '33303']], ['comma without space', 'ZORBLETON,ZZ 33303', ['ZORBLETON', 'ZZ', '33303']], ['multi-word city with plus-four', 'New Zorbleton Heights, Qx 33303-1234', ['NEW ZORBLETON HEIGHTS', 'QX', '33303-1234']], ['spelled state without code', 'ZORBLETON Zedland', ['ZORBLETON', 'ZZ', '']], ['missing city', 'ZZ 33303', None], ['ten bare digits are not a code', 'ZORBLETON ZZ 3330312345', None], ['short plus-four is not a code', 'ZORBLETON ZZ 33303-6', None], ['six digits are not a code', 'ZORBLETON XJ 333039', None], ['nine bare digits are not a code', 'ZORBLETON XJ 333033234', None], ['unknown state', 'ZORBLETON YY 33303', None]], [['comma and space', 'Quillby, ZZ 44404', ['QUILLBY', 'ZZ', '44404']], ['comma without space', 'QUILLBY,ZZ 44404', ['QUILLBY', 'ZZ', '44404']], ['multi-word city with plus-four', 'New Quillby Heights, Qx 44404-1244', ['NEW QUILLBY HEIGHTS', 'QX', '44404-1244']], ['spelled state without code', 'QUILLBY Zedland', ['QUILLBY', 'ZZ', '']], ['missing city', 'ZZ 44404', None], ['ten bare digits are not a code', 'QUILLBY ZZ 4440412345', None], ['short plus-four is not a code', 'QUILLBY ZZ 44404-6', None], ['six digits are not a code', 'QUILLBY XJ 444049', None], ['nine bare digits are not a code', 'QUILLBY XJ 444044234', None], ['unknown state', 'QUILLBY YY 44404', None]], [['comma and space', 'Spraxham, ZZ 55505', ['SPRAXHAM', 'ZZ', '55505']], ['comma without space', 'SPRAXHAM,ZZ 55505', ['SPRAXHAM', 'ZZ', '55505']], ['multi-word city with plus-four', 'New Spraxham Heights, Qx 55505-1254', ['NEW SPRAXHAM HEIGHTS', 'QX', '55505-1254']], ['spelled state without code', 'SPRAXHAM Zedland', ['SPRAXHAM', 'ZZ', '']], ['missing city', 'ZZ 55505', None], ['ten bare digits are not a code', 'SPRAXHAM ZZ 5550512345', None], ['short plus-four is not a code', 'SPRAXHAM ZZ 55505-6', None], ['six digits are not a code', 'SPRAXHAM XJ 555059', None], ['nine bare digits are not a code', 'SPRAXHAM XJ 555055234', None], ['unknown state', 'SPRAXHAM YY 55505', None]]]
for label, arg, expected in fixtures[N - 1]:
check(label, solve(arg), 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 |
|---|---|---|---|
| comma and space | ['FAKETOWN', 'ZZ', '11101'] | ['FAKETOWN', 'ZZ', '11101'] | Passed |
| comma without space | ['FAKETOWN', 'ZZ', '11101'] | ['FAKETOWN', 'ZZ', '11101'] | Passed |
| multi-word city with plus-four | ['NEW FAKETOWN HEIGHTS', 'QX', '11101-1214'] | ['NEW FAKETOWN HEIGHTS', 'QX', '11101-1214'] | Passed |
| spelled state without code | ['FAKETOWN', 'ZZ', ''] | ['FAKETOWN', 'ZZ', ''] | Passed |
| missing city | None | None | Passed |
| ten bare digits are not a code | None | None | Passed |
| short plus-four is not a code | None | None | Passed |
| six digits are not a code | None | None | Passed |
| nine bare digits are not a code | None | None | Passed |
| unknown state | None | None | Passed |
SHA-256 / 0f9f36ddcbdeeefb148e19305dfa1a2f4318a1b965b40c3eb5f01d7784f0d906
Verification & scope
A deterministic toy contract over synthetic, obviously fictitious addresses. The rules are stipulated for this model only and make no claim of conformance with any postal authority standard. 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:19.890909+00:00.
Case digest / 37202a2d30fecbd0e156b43c325758e71650cecf05f853bc0c7b7fcace8f40fa