{"abstract":"\"5550198-5550201\" is emitted as \"5550198-01\".","category":"Phone number formatting","checks":8,"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.","evaluation_group":"w2-phone-number-formatting-range-compress","failed_approach":"Sizing the tail by the digit count of the span still writes \"5550198-1\".","family":"w2-phone-number-formatting-range-compress-tail-prefix","id":"FA-96731","implementations":{"attempt":{"sha256":"09e933c906afadae901d6c1df95c52914c3af65b80aeb768c031ec899876477a","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    nums = sorted(set(x), key=lambda v: (len(v), v))\n    out = []\n    i = 0\n    while i < len(nums):\n        j = i\n        while j + 1 < len(nums) and int(nums[j + 1]) == int(nums[j]) + 1 and len(nums[j + 1]) == len(nums[i]):\n            j += 1\n        a, b = nums[i], nums[j]\n        if a == b:\n            out.append(a)\n        else:\n            k = 0\n            while a[k] == b[k]:\n                k += 1\n            out.append(a + '-' + b[len(b) - len(str(int(b) - int(a))):])\n        i = j + 1\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['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']]]]\nfor label, arg, expected in fixtures[N - 1]:\n    check(label, solve(arg), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"broken":{"sha256":"23df212b97f4d50429085e493cd863d4d417de599437e987a598d6bba556d082","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    nums = sorted(set(x), key=lambda v: (len(v), v))\n    out = []\n    i = 0\n    while i < len(nums):\n        j = i\n        while j + 1 < len(nums) and int(nums[j + 1]) == int(nums[j]) + 1 and len(nums[j + 1]) == len(nums[i]):\n            j += 1\n        a, b = nums[i], nums[j]\n        if a == b:\n            out.append(a)\n        else:\n            k = 0\n            while a[k] == b[k]:\n                k += 1\n            out.append(a + '-' + b[-2:])\n        i = j + 1\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['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']]]]\nfor label, arg, expected in fixtures[N - 1]:\n    check(label, solve(arg), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"fixed":{"sha256":"7718be816344333c3799284f36a47556ec1529b37d765452bd619981c869c99a","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    nums = sorted(set(x), key=lambda v: (len(v), v))\n    out = []\n    i = 0\n    while i < len(nums):\n        j = i\n        while j + 1 < len(nums) and int(nums[j + 1]) == int(nums[j]) + 1 and len(nums[j + 1]) == len(nums[i]):\n            j += 1\n        a, b = nums[i], nums[j]\n        if a == b:\n            out.append(a)\n        else:\n            k = 0\n            while a[k] == b[k]:\n                k += 1\n            out.append(a + '-' + b[k:])\n        i = j + 1\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['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']]]]\nfor label, arg, expected in fixtures[N - 1]:\n    check(label, solve(arg), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"}},"limitations":"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.","method":"Deterministic executable model with adversarial boundary fixtures.","provenance":{"created_by":"Failure Map","dependencies":"Python standard library","family":"w2-phone-number-formatting-range-compress-tail-prefix","generated_at":"2026-09-29T14:52:25.412751+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Number inventories are displayed and exported as compressed ranges; a wrong run boundary or tail misstates which numbers are owned.","repair":"Drop exactly the prefix START and END share.","root_cause":"The tail is the last two digits instead of the part after the shared prefix.","sha256":"46b5f5f12659b67ee965f8a9f51b3ee9683d10955b73db35309babf9f16149d8","title":"Number list range compression: the tail is always two digits · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":38.585,"exit_code":1,"observations":[{"actual":["5550110-2","5550160"],"check":"run and singleton","expected":["5550110-2","5550160"],"passed":true},{"actual":["5550115-6"],"check":"duplicates inside a run","expected":["5550115-6"],"passed":true},{"actual":["5550110-2"],"check":"unsorted input","expected":["5550110-2"],"passed":true},{"actual":["5550198-1"],"check":"run crossing a hundred","expected":["5550198-201"],"passed":false},{"actual":["98-9","100-1"],"check":"different lengths do not join","expected":["98-9","100-1"],"passed":true},{"actual":["1998-0"],"check":"run crossing a thousand","expected":["1998-2000"],"passed":false},{"actual":["100","0050"],"check":"shorter number sorts first","expected":["100","0050"],"passed":true},{"actual":["5550130","5550132"],"check":"gap of two","expected":["5550130","5550132"],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"run and singleton\", \"actual\": [\"5550110-2\", \"5550160\"], \"expected\": [\"5550110-2\", \"5550160\"], \"passed\": true}, {\"check\": \"duplicates inside a run\", \"actual\": [\"5550115-6\"], \"expected\": [\"5550115-6\"], \"passed\": true}, {\"check\": \"unsorted input\", \"actual\": [\"5550110-2\"], \"expected\": [\"5550110-2\"], \"passed\": true}, {\"check\": \"run crossing a hundred\", \"actual\": [\"5550198-1\"], \"expected\": [\"5550198-201\"], \"passed\": false}, {\"check\": \"different lengths do not join\", \"actual\": [\"98-9\", \"100-1\"], \"expected\": [\"98-9\", \"100-1\"], \"passed\": true}, {\"check\": \"run crossing a thousand\", \"actual\": [\"1998-0\"], \"expected\": [\"1998-2000\"], \"passed\": false}, {\"check\": \"shorter number sorts first\", \"actual\": [\"100\", \"0050\"], \"expected\": [\"100\", \"0050\"], \"passed\": true}, {\"check\": \"gap of two\", \"actual\": [\"5550130\", \"5550132\"], \"expected\": [\"5550130\", \"5550132\"], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":39.899,"exit_code":1,"observations":[{"actual":["5550110-12","5550160"],"check":"run and singleton","expected":["5550110-2","5550160"],"passed":false},{"actual":["5550115-16"],"check":"duplicates inside a run","expected":["5550115-6"],"passed":false},{"actual":["5550110-12"],"check":"unsorted input","expected":["5550110-2"],"passed":false},{"actual":["5550198-01"],"check":"run crossing a hundred","expected":["5550198-201"],"passed":false},{"actual":["98-99","100-01"],"check":"different lengths do not join","expected":["98-9","100-1"],"passed":false},{"actual":["1998-00"],"check":"run crossing a thousand","expected":["1998-2000"],"passed":false},{"actual":["100","0050"],"check":"shorter number sorts first","expected":["100","0050"],"passed":true},{"actual":["5550130","5550132"],"check":"gap of two","expected":["5550130","5550132"],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"run and singleton\", \"actual\": [\"5550110-12\", \"5550160\"], \"expected\": [\"5550110-2\", \"5550160\"], \"passed\": false}, {\"check\": \"duplicates inside a run\", \"actual\": [\"5550115-16\"], \"expected\": [\"5550115-6\"], \"passed\": false}, {\"check\": \"unsorted input\", \"actual\": [\"5550110-12\"], \"expected\": [\"5550110-2\"], \"passed\": false}, {\"check\": \"run crossing a hundred\", \"actual\": [\"5550198-01\"], \"expected\": [\"5550198-201\"], \"passed\": false}, {\"check\": \"different lengths do not join\", \"actual\": [\"98-99\", \"100-01\"], \"expected\": [\"98-9\", \"100-1\"], \"passed\": false}, {\"check\": \"run crossing a thousand\", \"actual\": [\"1998-00\"], \"expected\": [\"1998-2000\"], \"passed\": false}, {\"check\": \"shorter number sorts first\", \"actual\": [\"100\", \"0050\"], \"expected\": [\"100\", \"0050\"], \"passed\": true}, {\"check\": \"gap of two\", \"actual\": [\"5550130\", \"5550132\"], \"expected\": [\"5550130\", \"5550132\"], \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":40.188,"exit_code":0,"observations":[{"actual":["5550110-2","5550160"],"check":"run and singleton","expected":["5550110-2","5550160"],"passed":true},{"actual":["5550115-6"],"check":"duplicates inside a run","expected":["5550115-6"],"passed":true},{"actual":["5550110-2"],"check":"unsorted input","expected":["5550110-2"],"passed":true},{"actual":["5550198-201"],"check":"run crossing a hundred","expected":["5550198-201"],"passed":true},{"actual":["98-9","100-1"],"check":"different lengths do not join","expected":["98-9","100-1"],"passed":true},{"actual":["1998-2000"],"check":"run crossing a thousand","expected":["1998-2000"],"passed":true},{"actual":["100","0050"],"check":"shorter number sorts first","expected":["100","0050"],"passed":true},{"actual":["5550130","5550132"],"check":"gap of two","expected":["5550130","5550132"],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"run and singleton\", \"actual\": [\"5550110-2\", \"5550160\"], \"expected\": [\"5550110-2\", \"5550160\"], \"passed\": true}, {\"check\": \"duplicates inside a run\", \"actual\": [\"5550115-6\"], \"expected\": [\"5550115-6\"], \"passed\": true}, {\"check\": \"unsorted input\", \"actual\": [\"5550110-2\"], \"expected\": [\"5550110-2\"], \"passed\": true}, {\"check\": \"run crossing a hundred\", \"actual\": [\"5550198-201\"], \"expected\": [\"5550198-201\"], \"passed\": true}, {\"check\": \"different lengths do not join\", \"actual\": [\"98-9\", \"100-1\"], \"expected\": [\"98-9\", \"100-1\"], \"passed\": true}, {\"check\": \"run crossing a thousand\", \"actual\": [\"1998-2000\"], \"expected\": [\"1998-2000\"], \"passed\": true}, {\"check\": \"shorter number sorts first\", \"actual\": [\"100\", \"0050\"], \"expected\": [\"100\", \"0050\"], \"passed\": true}, {\"check\": \"gap of two\", \"actual\": [\"5550130\", \"5550132\"], \"expected\": [\"5550130\", \"5550132\"], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}