{"abstract":"\"(555) quizzap\" is rejected as too short.","category":"Phone number formatting","checks":7,"contract":"Uppercase. Digits are kept, letters map to keypad digits (ABC2 DEF3 GHI4 JKL5 MNO6 PQRS7 TUV8 WXYZ9), spaces, hyphens, dots and parentheses are ignored and anything else returns None. At least ten symbols are needed; symbols after the tenth may only be letters (vanity overflow) and are dropped. Return the first ten digits as \"DDD-DDD-DDDD\".","evaluation_group":"w2-phone-number-formatting-vanity-keypad","failed_approach":"Capitalizing only the first character leaves later lowercase letters unmatched.","family":"w2-phone-number-formatting-vanity-keypad-letter-case","id":"FA-96426","implementations":{"attempt":{"sha256":"41af6bf564bec2937725e20f8dd607b169413f6ab0633bd5c49e351e2dd8956e","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    KEYS = {'ABC': '2', 'DEF': '3', 'GHI': '4', 'JKL': '5', 'MNO': '6', 'PQRS': '7', 'TUV': '8', 'WXYZ': '9'}\n    out = []\n    for c in x.capitalize():\n        if c.isdigit():\n            out.append(c)\n        elif c.isalpha():\n            for letters, digit in KEYS.items():\n                if c in letters:\n                    out.append(digit + '*')\n                    break\n        elif c not in ' -.()':\n            return None\n    if len(out) < 10:\n        return None\n    if any(not t.endswith('*') for t in out[10:]):\n        return None\n    d = ''.join(t[0] for t in out[:10])\n    return d[:3] + '-' + d[3:6] + '-' + d[6:]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['letters with Q and Z', '555-QUIZZAP', '555-784-9927'], ['lowercase letters', '(555) quizzap', '555-784-9927'], ['dotted vanity number', '555.QUIZZAP', '555-784-9927'], ['extra vanity letter is ignored', '555-QUIZZAPS', '555-784-9927'], ['extra digit is rejected', '555QUIZZAP9', None], ['too short', '555-FAKE', None], ['slash rejected', '555/QUIZZAP', None]], [['letters with Q and Z', '555-QUIZZIP', '555-784-9947'], ['lowercase letters', '(555) quizzip', '555-784-9947'], ['dotted vanity number', '555.QUIZZIP', '555-784-9947'], ['extra vanity letter is ignored', '555-QUIZZIPS', '555-784-9947'], ['extra digit is rejected', '555QUIZZIP9', None], ['too short', '555-FAKE', None], ['slash rejected', '555/QUIZZIP', None]], [['letters with Q and Z', '555-QUIZZOO', '555-784-9966'], ['lowercase letters', '(555) quizzoo', '555-784-9966'], ['dotted vanity number', '555.QUIZZOO', '555-784-9966'], ['extra vanity letter is ignored', '555-QUIZZOOS', '555-784-9966'], ['extra digit is rejected', '555QUIZZOO9', None], ['too short', '555-FAKE', None], ['slash rejected', '555/QUIZZOO', None]], [['letters with Q and Z', '555-QUIZZEN', '555-784-9936'], ['lowercase letters', '(555) quizzen', '555-784-9936'], ['dotted vanity number', '555.QUIZZEN', '555-784-9936'], ['extra vanity letter is ignored', '555-QUIZZENS', '555-784-9936'], ['extra digit is rejected', '555QUIZZEN9', None], ['too short', '555-FAKE', None], ['slash rejected', '555/QUIZZEN', None]], [['letters with Q and Z', '555-QUIZZED', '555-784-9933'], ['lowercase letters', '(555) quizzed', '555-784-9933'], ['dotted vanity number', '555.QUIZZED', '555-784-9933'], ['extra vanity letter is ignored', '555-QUIZZEDS', '555-784-9933'], ['extra digit is rejected', '555QUIZZED9', None], ['too short', '555-FAKE', None], ['slash rejected', '555/QUIZZED', None]]]\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":"b43712a64405dce365767ebc4fec9c02588291bdfe63bfb8065caa8668699abb","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    KEYS = {'ABC': '2', 'DEF': '3', 'GHI': '4', 'JKL': '5', 'MNO': '6', 'PQRS': '7', 'TUV': '8', 'WXYZ': '9'}\n    out = []\n    for c in x:\n        if c.isdigit():\n            out.append(c)\n        elif c.isalpha():\n            for letters, digit in KEYS.items():\n                if c in letters:\n                    out.append(digit + '*')\n                    break\n        elif c not in ' -.()':\n            return None\n    if len(out) < 10:\n        return None\n    if any(not t.endswith('*') for t in out[10:]):\n        return None\n    d = ''.join(t[0] for t in out[:10])\n    return d[:3] + '-' + d[3:6] + '-' + d[6:]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['letters with Q and Z', '555-QUIZZAP', '555-784-9927'], ['lowercase letters', '(555) quizzap', '555-784-9927'], ['dotted vanity number', '555.QUIZZAP', '555-784-9927'], ['extra vanity letter is ignored', '555-QUIZZAPS', '555-784-9927'], ['extra digit is rejected', '555QUIZZAP9', None], ['too short', '555-FAKE', None], ['slash rejected', '555/QUIZZAP', None]], [['letters with Q and Z', '555-QUIZZIP', '555-784-9947'], ['lowercase letters', '(555) quizzip', '555-784-9947'], ['dotted vanity number', '555.QUIZZIP', '555-784-9947'], ['extra vanity letter is ignored', '555-QUIZZIPS', '555-784-9947'], ['extra digit is rejected', '555QUIZZIP9', None], ['too short', '555-FAKE', None], ['slash rejected', '555/QUIZZIP', None]], [['letters with Q and Z', '555-QUIZZOO', '555-784-9966'], ['lowercase letters', '(555) quizzoo', '555-784-9966'], ['dotted vanity number', '555.QUIZZOO', '555-784-9966'], ['extra vanity letter is ignored', '555-QUIZZOOS', '555-784-9966'], ['extra digit is rejected', '555QUIZZOO9', None], ['too short', '555-FAKE', None], ['slash rejected', '555/QUIZZOO', None]], [['letters with Q and Z', '555-QUIZZEN', '555-784-9936'], ['lowercase letters', '(555) quizzen', '555-784-9936'], ['dotted vanity number', '555.QUIZZEN', '555-784-9936'], ['extra vanity letter is ignored', '555-QUIZZENS', '555-784-9936'], ['extra digit is rejected', '555QUIZZEN9', None], ['too short', '555-FAKE', None], ['slash rejected', '555/QUIZZEN', None]], [['letters with Q and Z', '555-QUIZZED', '555-784-9933'], ['lowercase letters', '(555) quizzed', '555-784-9933'], ['dotted vanity number', '555.QUIZZED', '555-784-9933'], ['extra vanity letter is ignored', '555-QUIZZEDS', '555-784-9933'], ['extra digit is rejected', '555QUIZZED9', None], ['too short', '555-FAKE', None], ['slash rejected', '555/QUIZZED', None]]]\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":"daae50b438ddd3cced1c118c7ed824812a7812e6d11ff2c1580281c9ff60722b","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    KEYS = {'ABC': '2', 'DEF': '3', 'GHI': '4', 'JKL': '5', 'MNO': '6', 'PQRS': '7', 'TUV': '8', 'WXYZ': '9'}\n    out = []\n    for c in x.upper():\n        if c.isdigit():\n            out.append(c)\n        elif c.isalpha():\n            for letters, digit in KEYS.items():\n                if c in letters:\n                    out.append(digit + '*')\n                    break\n        elif c not in ' -.()':\n            return None\n    if len(out) < 10:\n        return None\n    if any(not t.endswith('*') for t in out[10:]):\n        return None\n    d = ''.join(t[0] for t in out[:10])\n    return d[:3] + '-' + d[3:6] + '-' + d[6:]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['letters with Q and Z', '555-QUIZZAP', '555-784-9927'], ['lowercase letters', '(555) quizzap', '555-784-9927'], ['dotted vanity number', '555.QUIZZAP', '555-784-9927'], ['extra vanity letter is ignored', '555-QUIZZAPS', '555-784-9927'], ['extra digit is rejected', '555QUIZZAP9', None], ['too short', '555-FAKE', None], ['slash rejected', '555/QUIZZAP', None]], [['letters with Q and Z', '555-QUIZZIP', '555-784-9947'], ['lowercase letters', '(555) quizzip', '555-784-9947'], ['dotted vanity number', '555.QUIZZIP', '555-784-9947'], ['extra vanity letter is ignored', '555-QUIZZIPS', '555-784-9947'], ['extra digit is rejected', '555QUIZZIP9', None], ['too short', '555-FAKE', None], ['slash rejected', '555/QUIZZIP', None]], [['letters with Q and Z', '555-QUIZZOO', '555-784-9966'], ['lowercase letters', '(555) quizzoo', '555-784-9966'], ['dotted vanity number', '555.QUIZZOO', '555-784-9966'], ['extra vanity letter is ignored', '555-QUIZZOOS', '555-784-9966'], ['extra digit is rejected', '555QUIZZOO9', None], ['too short', '555-FAKE', None], ['slash rejected', '555/QUIZZOO', None]], [['letters with Q and Z', '555-QUIZZEN', '555-784-9936'], ['lowercase letters', '(555) quizzen', '555-784-9936'], ['dotted vanity number', '555.QUIZZEN', '555-784-9936'], ['extra vanity letter is ignored', '555-QUIZZENS', '555-784-9936'], ['extra digit is rejected', '555QUIZZEN9', None], ['too short', '555-FAKE', None], ['slash rejected', '555/QUIZZEN', None]], [['letters with Q and Z', '555-QUIZZED', '555-784-9933'], ['lowercase letters', '(555) quizzed', '555-784-9933'], ['dotted vanity number', '555.QUIZZED', '555-784-9933'], ['extra vanity letter is ignored', '555-QUIZZEDS', '555-784-9933'], ['extra digit is rejected', '555QUIZZED9', None], ['too short', '555-FAKE', None], ['slash rejected', '555/QUIZZED', None]]]\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-vanity-keypad-letter-case","generated_at":"2026-09-29T14:52:22.610321+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Vanity numbers printed in advertising are translated before dialing or storing; a wrong keypad table dials a stranger.","repair":"Uppercase the input first.","root_cause":"Input is not uppercased before table lookup, so lowercase letters match no key.","sha256":"281963e60e5421680dd70a596fa05d57530641559f889d1960a2eb43b2ee10ba","title":"Vanity keypad translator: lowercase letters are dropped · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":40.695,"exit_code":1,"observations":[{"actual":null,"check":"letters with Q and Z","expected":"555-784-9927","passed":false},{"actual":null,"check":"lowercase letters","expected":"555-784-9927","passed":false},{"actual":null,"check":"dotted vanity number","expected":"555-784-9927","passed":false},{"actual":null,"check":"extra vanity letter is ignored","expected":"555-784-9927","passed":false},{"actual":null,"check":"extra digit is rejected","expected":null,"passed":true},{"actual":null,"check":"too short","expected":null,"passed":true},{"actual":null,"check":"slash rejected","expected":null,"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"letters with Q and Z\", \"actual\": null, \"expected\": \"555-784-9927\", \"passed\": false}, {\"check\": \"lowercase letters\", \"actual\": null, \"expected\": \"555-784-9927\", \"passed\": false}, {\"check\": \"dotted vanity number\", \"actual\": null, \"expected\": \"555-784-9927\", \"passed\": false}, {\"check\": \"extra vanity letter is ignored\", \"actual\": null, \"expected\": \"555-784-9927\", \"passed\": false}, {\"check\": \"extra digit is rejected\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"too short\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"slash rejected\", \"actual\": null, \"expected\": null, \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":39.207,"exit_code":1,"observations":[{"actual":"555-784-9927","check":"letters with Q and Z","expected":"555-784-9927","passed":true},{"actual":null,"check":"lowercase letters","expected":"555-784-9927","passed":false},{"actual":"555-784-9927","check":"dotted vanity number","expected":"555-784-9927","passed":true},{"actual":"555-784-9927","check":"extra vanity letter is ignored","expected":"555-784-9927","passed":true},{"actual":null,"check":"extra digit is rejected","expected":null,"passed":true},{"actual":null,"check":"too short","expected":null,"passed":true},{"actual":null,"check":"slash rejected","expected":null,"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"letters with Q and Z\", \"actual\": \"555-784-9927\", \"expected\": \"555-784-9927\", \"passed\": true}, {\"check\": \"lowercase letters\", \"actual\": null, \"expected\": \"555-784-9927\", \"passed\": false}, {\"check\": \"dotted vanity number\", \"actual\": \"555-784-9927\", \"expected\": \"555-784-9927\", \"passed\": true}, {\"check\": \"extra vanity letter is ignored\", \"actual\": \"555-784-9927\", \"expected\": \"555-784-9927\", \"passed\": true}, {\"check\": \"extra digit is rejected\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"too short\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"slash rejected\", \"actual\": null, \"expected\": null, \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":41.46,"exit_code":0,"observations":[{"actual":"555-784-9927","check":"letters with Q and Z","expected":"555-784-9927","passed":true},{"actual":"555-784-9927","check":"lowercase letters","expected":"555-784-9927","passed":true},{"actual":"555-784-9927","check":"dotted vanity number","expected":"555-784-9927","passed":true},{"actual":"555-784-9927","check":"extra vanity letter is ignored","expected":"555-784-9927","passed":true},{"actual":null,"check":"extra digit is rejected","expected":null,"passed":true},{"actual":null,"check":"too short","expected":null,"passed":true},{"actual":null,"check":"slash rejected","expected":null,"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"letters with Q and Z\", \"actual\": \"555-784-9927\", \"expected\": \"555-784-9927\", \"passed\": true}, {\"check\": \"lowercase letters\", \"actual\": \"555-784-9927\", \"expected\": \"555-784-9927\", \"passed\": true}, {\"check\": \"dotted vanity number\", \"actual\": \"555-784-9927\", \"expected\": \"555-784-9927\", \"passed\": true}, {\"check\": \"extra vanity letter is ignored\", \"actual\": \"555-784-9927\", \"expected\": \"555-784-9927\", \"passed\": true}, {\"check\": \"extra digit is rejected\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"too short\", \"actual\": null, \"expected\": null, \"passed\": true}, {\"check\": \"slash rejected\", \"actual\": null, \"expected\": null, \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}