FA-96731 / Phone number formatting / Open access
Number list range compression: the tail is always two digits · case 01
"5550198-5550201" is emitted as "5550198-01".
ROOT CAUSE
The tail is the last two digits instead of the part after the shared prefix.
VERIFIED REPAIR
Drop exactly the prefix START and END share.
Unsuccessful approach: Sizing the tail by the digit count of the span still writes "5550198-1".
Case contract
Input a list of digit strings. Deduplicate and sort by (length, text). Consecutive numbers of equal length (each one greater than the previous) form a run. A run of one is emitted as is; a longer run is emitted as START-TAIL where TAIL is END without the prefix it shares with START.
Why this case matters
Number inventories are displayed and exported as compressed ranges; a wrong run boundary or tail misstates which numbers are owned.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
nums = sorted(set(x), key=lambda v: (len(v), v))
out = []
i = 0
while i < len(nums):
j = i
while j + 1 < len(nums) and int(nums[j + 1]) == int(nums[j]) + 1 and len(nums[j + 1]) == len(nums[i]):
j += 1
a, b = nums[i], nums[j]
if a == b:
out.append(a)
else:
k = 0
while a[k] == b[k]:
k += 1
out.append(a + '-' + b[-2:])
i = j + 1
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['run and singleton', ['5550110', '5550111', '5550112', '5550160'], ['5550110-2', '5550160']], ['duplicates inside a run', ['5550115', '5550115', '5550116'], ['5550115-6']], ['unsorted input', ['5550112', '5550110', '5550111'], ['5550110-2']], ['run crossing a hundred', ['5550198', '5550199', '5550200', '5550201'], ['5550198-201']], ['different lengths do not join', ['98', '99', '100', '101'], ['98-9', '100-1']], ['run crossing a thousand', ['1998', '1999', '2000'], ['1998-2000']], ['shorter number sorts first', ['0050', '100'], ['100', '0050']], ['gap of two', ['5550130', '5550132'], ['5550130', '5550132']]], [['run and singleton', ['5550120', '5550121', '5550122', '5550170'], ['5550120-2', '5550170']], ['duplicates inside a run', ['5550125', '5550125', '5550126'], ['5550125-6']], ['unsorted input', ['5550122', '5550120', '5550121'], ['5550120-2']], ['run crossing a hundred', ['5550198', '5550199', '5550200', '5550201'], ['5550198-201']], ['different lengths do not join', ['98', '99', '100', '101'], ['98-9', '100-1']], ['run crossing a thousand', ['1998', '1999', '2000'], ['1998-2000']], ['shorter number sorts first', ['0050', '100'], ['100', '0050']], ['gap of two', ['5550140', '5550142'], ['5550140', '5550142']]], [['run and singleton', ['5550130', '5550131', '5550132', '5550180'], ['5550130-2', '5550180']], ['duplicates inside a run', ['5550135', '5550135', '5550136'], ['5550135-6']], ['unsorted input', ['5550132', '5550130', '5550131'], ['5550130-2']], ['run crossing a hundred', ['5550198', '5550199', '5550200', '5550201'], ['5550198-201']], ['different lengths do not join', ['98', '99', '100', '101'], ['98-9', '100-1']], ['run crossing a thousand', ['1998', '1999', '2000'], ['1998-2000']], ['shorter number sorts first', ['0050', '100'], ['100', '0050']], ['gap of two', ['5550150', '5550152'], ['5550150', '5550152']]], [['run and singleton', ['5550140', '5550141', '5550142', '5550190'], ['5550140-2', '5550190']], ['duplicates inside a run', ['5550145', '5550145', '5550146'], ['5550145-6']], ['unsorted input', ['5550142', '5550140', '5550141'], ['5550140-2']], ['run crossing a hundred', ['5550198', '5550199', '5550200', '5550201'], ['5550198-201']], ['different lengths do not join', ['98', '99', '100', '101'], ['98-9', '100-1']], ['run crossing a thousand', ['1998', '1999', '2000'], ['1998-2000']], ['shorter number sorts first', ['0050', '100'], ['100', '0050']], ['gap of two', ['5550160', '5550162'], ['5550160', '5550162']]], [['run and singleton', ['5550150', '5550151', '5550152', '5550200'], ['5550150-2', '5550200']], ['duplicates inside a run', ['5550155', '5550155', '5550156'], ['5550155-6']], ['unsorted input', ['5550152', '5550150', '5550151'], ['5550150-2']], ['run crossing a hundred', ['5550198', '5550199', '5550200', '5550201'], ['5550198-201']], ['different lengths do not join', ['98', '99', '100', '101'], ['98-9', '100-1']], ['run crossing a thousand', ['1998', '1999', '2000'], ['1998-2000']], ['shorter number sorts first', ['0050', '100'], ['100', '0050']], ['gap of two', ['5550170', '5550172'], ['5550170', '5550172']]]]
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 |
|---|---|---|---|
| run and singleton | ['5550110-12', '5550160'] | ['5550110-2', '5550160'] | Failed |
| duplicates inside a run | ['5550115-16'] | ['5550115-6'] | Failed |
| unsorted input | ['5550110-12'] | ['5550110-2'] | Failed |
| run crossing a hundred | ['5550198-01'] | ['5550198-201'] | Failed |
| different lengths do not join | ['98-99', '100-01'] | ['98-9', '100-1'] | Failed |
| run crossing a thousand | ['1998-00'] | ['1998-2000'] | Failed |
| shorter number sorts first | ['100', '0050'] | ['100', '0050'] | Passed |
| gap of two | ['5550130', '5550132'] | ['5550130', '5550132'] | Passed |
SHA-256 / 23df212b97f4d50429085e493cd863d4d417de599437e987a598d6bba556d082
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
nums = sorted(set(x), key=lambda v: (len(v), v))
out = []
i = 0
while i < len(nums):
j = i
while j + 1 < len(nums) and int(nums[j + 1]) == int(nums[j]) + 1 and len(nums[j + 1]) == len(nums[i]):
j += 1
a, b = nums[i], nums[j]
if a == b:
out.append(a)
else:
k = 0
while a[k] == b[k]:
k += 1
out.append(a + '-' + b[len(b) - len(str(int(b) - int(a))):])
i = j + 1
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['run and singleton', ['5550110', '5550111', '5550112', '5550160'], ['5550110-2', '5550160']], ['duplicates inside a run', ['5550115', '5550115', '5550116'], ['5550115-6']], ['unsorted input', ['5550112', '5550110', '5550111'], ['5550110-2']], ['run crossing a hundred', ['5550198', '5550199', '5550200', '5550201'], ['5550198-201']], ['different lengths do not join', ['98', '99', '100', '101'], ['98-9', '100-1']], ['run crossing a thousand', ['1998', '1999', '2000'], ['1998-2000']], ['shorter number sorts first', ['0050', '100'], ['100', '0050']], ['gap of two', ['5550130', '5550132'], ['5550130', '5550132']]], [['run and singleton', ['5550120', '5550121', '5550122', '5550170'], ['5550120-2', '5550170']], ['duplicates inside a run', ['5550125', '5550125', '5550126'], ['5550125-6']], ['unsorted input', ['5550122', '5550120', '5550121'], ['5550120-2']], ['run crossing a hundred', ['5550198', '5550199', '5550200', '5550201'], ['5550198-201']], ['different lengths do not join', ['98', '99', '100', '101'], ['98-9', '100-1']], ['run crossing a thousand', ['1998', '1999', '2000'], ['1998-2000']], ['shorter number sorts first', ['0050', '100'], ['100', '0050']], ['gap of two', ['5550140', '5550142'], ['5550140', '5550142']]], [['run and singleton', ['5550130', '5550131', '5550132', '5550180'], ['5550130-2', '5550180']], ['duplicates inside a run', ['5550135', '5550135', '5550136'], ['5550135-6']], ['unsorted input', ['5550132', '5550130', '5550131'], ['5550130-2']], ['run crossing a hundred', ['5550198', '5550199', '5550200', '5550201'], ['5550198-201']], ['different lengths do not join', ['98', '99', '100', '101'], ['98-9', '100-1']], ['run crossing a thousand', ['1998', '1999', '2000'], ['1998-2000']], ['shorter number sorts first', ['0050', '100'], ['100', '0050']], ['gap of two', ['5550150', '5550152'], ['5550150', '5550152']]], [['run and singleton', ['5550140', '5550141', '5550142', '5550190'], ['5550140-2', '5550190']], ['duplicates inside a run', ['5550145', '5550145', '5550146'], ['5550145-6']], ['unsorted input', ['5550142', '5550140', '5550141'], ['5550140-2']], ['run crossing a hundred', ['5550198', '5550199', '5550200', '5550201'], ['5550198-201']], ['different lengths do not join', ['98', '99', '100', '101'], ['98-9', '100-1']], ['run crossing a thousand', ['1998', '1999', '2000'], ['1998-2000']], ['shorter number sorts first', ['0050', '100'], ['100', '0050']], ['gap of two', ['5550160', '5550162'], ['5550160', '5550162']]], [['run and singleton', ['5550150', '5550151', '5550152', '5550200'], ['5550150-2', '5550200']], ['duplicates inside a run', ['5550155', '5550155', '5550156'], ['5550155-6']], ['unsorted input', ['5550152', '5550150', '5550151'], ['5550150-2']], ['run crossing a hundred', ['5550198', '5550199', '5550200', '5550201'], ['5550198-201']], ['different lengths do not join', ['98', '99', '100', '101'], ['98-9', '100-1']], ['run crossing a thousand', ['1998', '1999', '2000'], ['1998-2000']], ['shorter number sorts first', ['0050', '100'], ['100', '0050']], ['gap of two', ['5550170', '5550172'], ['5550170', '5550172']]]]
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 |
|---|---|---|---|
| run and singleton | ['5550110-2', '5550160'] | ['5550110-2', '5550160'] | Passed |
| duplicates inside a run | ['5550115-6'] | ['5550115-6'] | Passed |
| unsorted input | ['5550110-2'] | ['5550110-2'] | Passed |
| run crossing a hundred | ['5550198-1'] | ['5550198-201'] | Failed |
| different lengths do not join | ['98-9', '100-1'] | ['98-9', '100-1'] | Passed |
| run crossing a thousand | ['1998-0'] | ['1998-2000'] | Failed |
| shorter number sorts first | ['100', '0050'] | ['100', '0050'] | Passed |
| gap of two | ['5550130', '5550132'] | ['5550130', '5550132'] | Passed |
SHA-256 / 09e933c906afadae901d6c1df95c52914c3af65b80aeb768c031ec899876477a
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
nums = sorted(set(x), key=lambda v: (len(v), v))
out = []
i = 0
while i < len(nums):
j = i
while j + 1 < len(nums) and int(nums[j + 1]) == int(nums[j]) + 1 and len(nums[j + 1]) == len(nums[i]):
j += 1
a, b = nums[i], nums[j]
if a == b:
out.append(a)
else:
k = 0
while a[k] == b[k]:
k += 1
out.append(a + '-' + b[k:])
i = j + 1
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['run and singleton', ['5550110', '5550111', '5550112', '5550160'], ['5550110-2', '5550160']], ['duplicates inside a run', ['5550115', '5550115', '5550116'], ['5550115-6']], ['unsorted input', ['5550112', '5550110', '5550111'], ['5550110-2']], ['run crossing a hundred', ['5550198', '5550199', '5550200', '5550201'], ['5550198-201']], ['different lengths do not join', ['98', '99', '100', '101'], ['98-9', '100-1']], ['run crossing a thousand', ['1998', '1999', '2000'], ['1998-2000']], ['shorter number sorts first', ['0050', '100'], ['100', '0050']], ['gap of two', ['5550130', '5550132'], ['5550130', '5550132']]], [['run and singleton', ['5550120', '5550121', '5550122', '5550170'], ['5550120-2', '5550170']], ['duplicates inside a run', ['5550125', '5550125', '5550126'], ['5550125-6']], ['unsorted input', ['5550122', '5550120', '5550121'], ['5550120-2']], ['run crossing a hundred', ['5550198', '5550199', '5550200', '5550201'], ['5550198-201']], ['different lengths do not join', ['98', '99', '100', '101'], ['98-9', '100-1']], ['run crossing a thousand', ['1998', '1999', '2000'], ['1998-2000']], ['shorter number sorts first', ['0050', '100'], ['100', '0050']], ['gap of two', ['5550140', '5550142'], ['5550140', '5550142']]], [['run and singleton', ['5550130', '5550131', '5550132', '5550180'], ['5550130-2', '5550180']], ['duplicates inside a run', ['5550135', '5550135', '5550136'], ['5550135-6']], ['unsorted input', ['5550132', '5550130', '5550131'], ['5550130-2']], ['run crossing a hundred', ['5550198', '5550199', '5550200', '5550201'], ['5550198-201']], ['different lengths do not join', ['98', '99', '100', '101'], ['98-9', '100-1']], ['run crossing a thousand', ['1998', '1999', '2000'], ['1998-2000']], ['shorter number sorts first', ['0050', '100'], ['100', '0050']], ['gap of two', ['5550150', '5550152'], ['5550150', '5550152']]], [['run and singleton', ['5550140', '5550141', '5550142', '5550190'], ['5550140-2', '5550190']], ['duplicates inside a run', ['5550145', '5550145', '5550146'], ['5550145-6']], ['unsorted input', ['5550142', '5550140', '5550141'], ['5550140-2']], ['run crossing a hundred', ['5550198', '5550199', '5550200', '5550201'], ['5550198-201']], ['different lengths do not join', ['98', '99', '100', '101'], ['98-9', '100-1']], ['run crossing a thousand', ['1998', '1999', '2000'], ['1998-2000']], ['shorter number sorts first', ['0050', '100'], ['100', '0050']], ['gap of two', ['5550160', '5550162'], ['5550160', '5550162']]], [['run and singleton', ['5550150', '5550151', '5550152', '5550200'], ['5550150-2', '5550200']], ['duplicates inside a run', ['5550155', '5550155', '5550156'], ['5550155-6']], ['unsorted input', ['5550152', '5550150', '5550151'], ['5550150-2']], ['run crossing a hundred', ['5550198', '5550199', '5550200', '5550201'], ['5550198-201']], ['different lengths do not join', ['98', '99', '100', '101'], ['98-9', '100-1']], ['run crossing a thousand', ['1998', '1999', '2000'], ['1998-2000']], ['shorter number sorts first', ['0050', '100'], ['100', '0050']], ['gap of two', ['5550170', '5550172'], ['5550170', '5550172']]]]
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 |
|---|---|---|---|
| run and singleton | ['5550110-2', '5550160'] | ['5550110-2', '5550160'] | Passed |
| duplicates inside a run | ['5550115-6'] | ['5550115-6'] | Passed |
| unsorted input | ['5550110-2'] | ['5550110-2'] | Passed |
| run crossing a hundred | ['5550198-201'] | ['5550198-201'] | Passed |
| different lengths do not join | ['98-9', '100-1'] | ['98-9', '100-1'] | Passed |
| run crossing a thousand | ['1998-2000'] | ['1998-2000'] | Passed |
| shorter number sorts first | ['100', '0050'] | ['100', '0050'] | Passed |
| gap of two | ['5550130', '5550132'] | ['5550130', '5550132'] | Passed |
SHA-256 / 7718be816344333c3799284f36a47556ec1529b37d765452bd619981c869c99a
Verification & scope
A deterministic toy contract over synthetic, obviously fictitious telephone numbers and toy country tables. The rules are stipulated for this model only and make no claim of conformance with any numbering plan or telecommunications 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:25.412751+00:00.
Case digest / 46b5f5f12659b67ee965f8a9f51b3ee9683d10955b73db35309babf9f16149d8