{"abstract":"Every hit after one lost fifty-fifty is featured forever.","category":"Game economy crafting balance","checks":8,"contract":"Each roll is 0..999. Pull number n = pity+1. Top-rarity rate is 6 per mille, plus 50*(n-73) from n >= 74 (soft pity); n >= 90 always hits. On a hit pity resets to 0; the item is featured (\"F\") if guarantee is set or the roll is even, otherwise lost (\"L\") and the guarantee is set; a featured hit clears the guarantee. Misses (\"-\") set pity = n.","evaluation_group":"w2-game-economy-crafting-balance-banner-pity","failed_approach":"Toggling the flag turns a naturally won fifty-fifty into a free guarantee.","family":"w2-game-economy-crafting-balance-banner-pity-guarantee-consumption","id":"FA-85931","implementations":{"attempt":{"sha256":"7d4debd657ff90800bda7ea0557eb4f91360a1302ace09a2c72424f76048b694","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(rolls, state):\n    pity = state['pity']\n    guarantee = state['guarantee']\n    out = []\n    for r in rolls:\n        n = pity + 1\n        rate = 6\n        if n >= 74:\n            rate += 50 * (n - 73)\n        if n >= 90 or r < rate:\n            pity = 0\n            if guarantee or r % 2 == 0:\n                out.append('F')\n                guarantee = not guarantee\n            else:\n                out.append('L')\n                guarantee = True\n        else:\n            pity = n\n            out.append('-')\n    return {'results': ''.join(out), 'pity': pity, 'guarantee': guarantee}\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncases = [[('first soft pity pull #1',\n   [[100, 3], {'pity': 73, 'guarantee': True}],\n   {'results': '-F', 'pity': 0, 'guarantee': False}),\n  ('lost fifty fifty then featured #1',\n   [[1, 999, 0], {'pity': 10, 'guarantee': False}],\n   {'results': 'L-F', 'pity': 0, 'guarantee': False}),\n  ('fault site guarantee consumption #1',\n   [[15, 31, 302, 259, 332, 886, 12, 851, 55, 45, 6, 903, 946, 869, 725], {'pity': 88, 'guarantee': True}],\n   {'results': 'F--------------', 'pity': 14, 'guarantee': False}),\n  ('partial repair boundary #1',\n   [[4, 155, 441, 951, 967, 353, 21], {'pity': 68, 'guarantee': False}],\n   {'results': 'F------', 'pity': 6, 'guarantee': False}),\n  ('partial repair boundary #2',\n   [[4, 42, 253, 999, 775, 819, 42, 973, 811, 307, 835, 958, 247, 22], {'pity': 73, 'guarantee': False}],\n   {'results': 'F-------------', 'pity': 13, 'guarantee': False}),\n  ('hard pity pull #1',\n   [[999, 999], {'pity': 89, 'guarantee': False}],\n   {'results': 'L-', 'pity': 1, 'guarantee': True}),\n  ('control #1',\n   [[922, 571, 11, 40, 49, 776, 996, 952, 946, 14, 108, 822, 888, 25], {'pity': 84, 'guarantee': False}],\n   {'results': '-L------------', 'pity': 12, 'guarantee': True}),\n  ('control #2', [[911], {'pity': 73, 'guarantee': True}], {'results': '-', 'pity': 74, 'guarantee': True})],\n [('lost fifty fifty then featured #1',\n   [[1, 999, 0], {'pity': 10, 'guarantee': False}],\n   {'results': 'L-F', 'pity': 0, 'guarantee': False}),\n  ('fault site guarantee consumption #1',\n   [[15, 31, 302, 259, 332, 886, 12, 851, 55, 45, 6, 903, 946, 869, 725], {'pity': 88, 'guarantee': True}],\n   {'results': 'F--------------', 'pity': 14, 'guarantee': False}),\n  ('fault site guarantee consumption #2',\n   [[507, 965, 27, 525, 851], {'pity': 73, 'guarantee': True}],\n   {'results': '--F--', 'pity': 2, 'guarantee': False}),\n  ('partial repair boundary #1',\n   [[4], {'pity': 73, 'guarantee': False}],\n   {'results': 'F', 'pity': 0, 'guarantee': False}),\n  ('regression guarantee consumption #1',\n   [[50, 38, 898, 817, 564, 877, 22, 812, 15, 0, 190], {'pity': 73, 'guarantee': True}],\n   {'results': 'F--------F-', 'pity': 1, 'guarantee': False}),\n  ('hard pity pull #1',\n   [[999, 999], {'pity': 89, 'guarantee': False}],\n   {'results': 'L-', 'pity': 1, 'guarantee': True}),\n  ('control #1', [[911], {'pity': 73, 'guarantee': True}], {'results': '-', 'pity': 74, 'guarantee': True}),\n  ('control #2',\n   [[18, 973, 5], {'pity': 72, 'guarantee': False}],\n   {'results': '--L', 'pity': 0, 'guarantee': True})],\n [('first soft pity pull #1',\n   [[100, 3], {'pity': 73, 'guarantee': True}],\n   {'results': '-F', 'pity': 0, 'guarantee': False}),\n  ('fault site guarantee consumption #1',\n   [[480, 489, 823, 13, 936, 776, 44, 409, 26, 974, 9, 54, 911, 804, 433, 47, 942, 847],\n    {'pity': 89, 'guarantee': True}],\n   {'results': 'F-----------------', 'pity': 17, 'guarantee': False}),\n  ('fault site guarantee consumption #2',\n   [[935, 90, 29, 166, 937, 997, 903, 315, 848, 1, 893, 36, 218, 730, 858, 726, 972, 10],\n    {'pity': 89, 'guarantee': True}],\n   {'results': 'F--------L--------', 'pity': 8, 'guarantee': True}),\n  ('partial repair boundary #1',\n   [[30, 806], {'pity': 83, 'guarantee': False}],\n   {'results': 'F-', 'pity': 1, 'guarantee': False}),\n  ('partial repair boundary #2',\n   [[891, 307, 20, 907, 30, 974, 462, 957, 860, 624, 42, 985, 46], {'pity': 73, 'guarantee': False}],\n   {'results': '--F----------', 'pity': 10, 'guarantee': False}),\n  ('hard pity pull #1',\n   [[999, 999], {'pity': 89, 'guarantee': False}],\n   {'results': 'L-', 'pity': 1, 'guarantee': True}),\n  ('control #1',\n   [[685, 976, 49, 33, 16, 30, 427, 839], {'pity': 0, 'guarantee': False}],\n   {'results': '--------', 'pity': 8, 'guarantee': False}),\n  ('control #2',\n   [[773, 957, 60, 353, 59, 19, 862, 820, 993, 27, 22, 893, 950], {'pity': 0, 'guarantee': True}],\n   {'results': '-------------', 'pity': 13, 'guarantee': True})],\n [('lost fifty fifty then featured #1',\n   [[1, 999, 0], {'pity': 10, 'guarantee': False}],\n   {'results': 'L-F', 'pity': 0, 'guarantee': False}),\n  ('fault site guarantee consumption #1',\n   [[815, 889, 39, 873, 939, 933, 908, 992, 421, 939, 821, 53, 12, 40, 8, 884, 975, 551, 967, 39],\n    {'pity': 63, 'guarantee': True}],\n   {'results': '-----------F--------', 'pity': 8, 'guarantee': False}),\n  ('fault site guarantee consumption #2',\n   [[18, 16, 60, 53, 197, 713, 972, 933], {'pity': 75, 'guarantee': True}],\n   {'results': 'F-------', 'pity': 7, 'guarantee': False}),\n  ('partial repair boundary #1',\n   [[24, 872, 131, 279, 598, 873, 881, 532, 874, 898, 570, 33, 575, 16, 950, 871, 988, 895, 840],\n    {'pity': 81, 'guarantee': False}],\n   {'results': 'F------------------', 'pity': 18, 'guarantee': False}),\n  ('partial repair boundary #2',\n   [[764, 38, 847, 39, 859, 959, 58, 877, 56, 252, 44, 46, 23, 992, 525, 972, 997],\n    {'pity': 89, 'guarantee': False}],\n   {'results': 'F----------------', 'pity': 16, 'guarantee': False}),\n  ('hard pity pull #1',\n   [[999, 999], {'pity': 89, 'guarantee': False}],\n   {'results': 'L-', 'pity': 1, 'guarantee': True}),\n  ('control #1', [[54], {'pity': 61, 'guarantee': False}], {'results': '-', 'pity': 62, 'guarantee': False}),\n  ('control #2',\n   [[346, 740, 973, 629, 933, 35, 831, 930, 214, 969, 923], {'pity': 73, 'guarantee': False}],\n   {'results': '-----L-----', 'pity': 5, 'guarantee': True})],\n [('first soft pity pull #1',\n   [[100, 3], {'pity': 73, 'guarantee': True}],\n   {'results': '-F', 'pity': 0, 'guarantee': False}),\n  ('fault site guarantee consumption #1',\n   [[54, 849, 304, 44], {'pity': 72, 'guarantee': True}],\n   {'results': '---F', 'pity': 0, 'guarantee': False}),\n  ('fault site guarantee consumption #2',\n   [[975, 474, 33, 973, 869, 8, 806, 843, 21, 34, 874], {'pity': 88, 'guarantee': True}],\n   {'results': '-F---------', 'pity': 9, 'guarantee': False}),\n  ('partial repair boundary #1',\n   [[456, 631, 879, 18, 33, 855, 6], {'pity': 73, 'guarantee': False}],\n   {'results': '---F---', 'pity': 3, 'guarantee': False}),\n  ('partial repair boundary #2',\n   [[32, 1], {'pity': 73, 'guarantee': False}],\n   {'results': 'FL', 'pity': 0, 'guarantee': True}),\n  ('hard pity pull #1',\n   [[999, 999], {'pity': 89, 'guarantee': False}],\n   {'results': 'L-', 'pity': 1, 'guarantee': True}),\n  ('control #1',\n   [[860, 832, 950, 795, 21, 53, 128, 667, 5, 11, 16], {'pity': 0, 'guarantee': False}],\n   {'results': '--------L--', 'pity': 2, 'guarantee': True}),\n  ('control #2',\n   [[938, 58, 37, 11, 926, 889, 844, 11, 265], {'pity': 0, 'guarantee': False}],\n   {'results': '---------', 'pity': 9, 'guarantee': False})]]\nfor label, args, expected in cases[N-1]:\n    check(label, solve(*args), 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":"7ea5a4286b4793ee17bf38543382e2aaaa448df2972fe034030b7b8780d9d215","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(rolls, state):\n    pity = state['pity']\n    guarantee = state['guarantee']\n    out = []\n    for r in rolls:\n        n = pity + 1\n        rate = 6\n        if n >= 74:\n            rate += 50 * (n - 73)\n        if n >= 90 or r < rate:\n            pity = 0\n            if guarantee or r % 2 == 0:\n                out.append('F')\n                pass\n            else:\n                out.append('L')\n                guarantee = True\n        else:\n            pity = n\n            out.append('-')\n    return {'results': ''.join(out), 'pity': pity, 'guarantee': guarantee}\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncases = [[('first soft pity pull #1',\n   [[100, 3], {'pity': 73, 'guarantee': True}],\n   {'results': '-F', 'pity': 0, 'guarantee': False}),\n  ('lost fifty fifty then featured #1',\n   [[1, 999, 0], {'pity': 10, 'guarantee': False}],\n   {'results': 'L-F', 'pity': 0, 'guarantee': False}),\n  ('fault site guarantee consumption #1',\n   [[15, 31, 302, 259, 332, 886, 12, 851, 55, 45, 6, 903, 946, 869, 725], {'pity': 88, 'guarantee': True}],\n   {'results': 'F--------------', 'pity': 14, 'guarantee': False}),\n  ('partial repair boundary #1',\n   [[4, 155, 441, 951, 967, 353, 21], {'pity': 68, 'guarantee': False}],\n   {'results': 'F------', 'pity': 6, 'guarantee': False}),\n  ('partial repair boundary #2',\n   [[4, 42, 253, 999, 775, 819, 42, 973, 811, 307, 835, 958, 247, 22], {'pity': 73, 'guarantee': False}],\n   {'results': 'F-------------', 'pity': 13, 'guarantee': False}),\n  ('hard pity pull #1',\n   [[999, 999], {'pity': 89, 'guarantee': False}],\n   {'results': 'L-', 'pity': 1, 'guarantee': True}),\n  ('control #1',\n   [[922, 571, 11, 40, 49, 776, 996, 952, 946, 14, 108, 822, 888, 25], {'pity': 84, 'guarantee': False}],\n   {'results': '-L------------', 'pity': 12, 'guarantee': True}),\n  ('control #2', [[911], {'pity': 73, 'guarantee': True}], {'results': '-', 'pity': 74, 'guarantee': True})],\n [('lost fifty fifty then featured #1',\n   [[1, 999, 0], {'pity': 10, 'guarantee': False}],\n   {'results': 'L-F', 'pity': 0, 'guarantee': False}),\n  ('fault site guarantee consumption #1',\n   [[15, 31, 302, 259, 332, 886, 12, 851, 55, 45, 6, 903, 946, 869, 725], {'pity': 88, 'guarantee': True}],\n   {'results': 'F--------------', 'pity': 14, 'guarantee': False}),\n  ('fault site guarantee consumption #2',\n   [[507, 965, 27, 525, 851], {'pity': 73, 'guarantee': True}],\n   {'results': '--F--', 'pity': 2, 'guarantee': False}),\n  ('partial repair boundary #1',\n   [[4], {'pity': 73, 'guarantee': False}],\n   {'results': 'F', 'pity': 0, 'guarantee': False}),\n  ('regression guarantee consumption #1',\n   [[50, 38, 898, 817, 564, 877, 22, 812, 15, 0, 190], {'pity': 73, 'guarantee': True}],\n   {'results': 'F--------F-', 'pity': 1, 'guarantee': False}),\n  ('hard pity pull #1',\n   [[999, 999], {'pity': 89, 'guarantee': False}],\n   {'results': 'L-', 'pity': 1, 'guarantee': True}),\n  ('control #1', [[911], {'pity': 73, 'guarantee': True}], {'results': '-', 'pity': 74, 'guarantee': True}),\n  ('control #2',\n   [[18, 973, 5], {'pity': 72, 'guarantee': False}],\n   {'results': '--L', 'pity': 0, 'guarantee': True})],\n [('first soft pity pull #1',\n   [[100, 3], {'pity': 73, 'guarantee': True}],\n   {'results': '-F', 'pity': 0, 'guarantee': False}),\n  ('fault site guarantee consumption #1',\n   [[480, 489, 823, 13, 936, 776, 44, 409, 26, 974, 9, 54, 911, 804, 433, 47, 942, 847],\n    {'pity': 89, 'guarantee': True}],\n   {'results': 'F-----------------', 'pity': 17, 'guarantee': False}),\n  ('fault site guarantee consumption #2',\n   [[935, 90, 29, 166, 937, 997, 903, 315, 848, 1, 893, 36, 218, 730, 858, 726, 972, 10],\n    {'pity': 89, 'guarantee': True}],\n   {'results': 'F--------L--------', 'pity': 8, 'guarantee': True}),\n  ('partial repair boundary #1',\n   [[30, 806], {'pity': 83, 'guarantee': False}],\n   {'results': 'F-', 'pity': 1, 'guarantee': False}),\n  ('partial repair boundary #2',\n   [[891, 307, 20, 907, 30, 974, 462, 957, 860, 624, 42, 985, 46], {'pity': 73, 'guarantee': False}],\n   {'results': '--F----------', 'pity': 10, 'guarantee': False}),\n  ('hard pity pull #1',\n   [[999, 999], {'pity': 89, 'guarantee': False}],\n   {'results': 'L-', 'pity': 1, 'guarantee': True}),\n  ('control #1',\n   [[685, 976, 49, 33, 16, 30, 427, 839], {'pity': 0, 'guarantee': False}],\n   {'results': '--------', 'pity': 8, 'guarantee': False}),\n  ('control #2',\n   [[773, 957, 60, 353, 59, 19, 862, 820, 993, 27, 22, 893, 950], {'pity': 0, 'guarantee': True}],\n   {'results': '-------------', 'pity': 13, 'guarantee': True})],\n [('lost fifty fifty then featured #1',\n   [[1, 999, 0], {'pity': 10, 'guarantee': False}],\n   {'results': 'L-F', 'pity': 0, 'guarantee': False}),\n  ('fault site guarantee consumption #1',\n   [[815, 889, 39, 873, 939, 933, 908, 992, 421, 939, 821, 53, 12, 40, 8, 884, 975, 551, 967, 39],\n    {'pity': 63, 'guarantee': True}],\n   {'results': '-----------F--------', 'pity': 8, 'guarantee': False}),\n  ('fault site guarantee consumption #2',\n   [[18, 16, 60, 53, 197, 713, 972, 933], {'pity': 75, 'guarantee': True}],\n   {'results': 'F-------', 'pity': 7, 'guarantee': False}),\n  ('partial repair boundary #1',\n   [[24, 872, 131, 279, 598, 873, 881, 532, 874, 898, 570, 33, 575, 16, 950, 871, 988, 895, 840],\n    {'pity': 81, 'guarantee': False}],\n   {'results': 'F------------------', 'pity': 18, 'guarantee': False}),\n  ('partial repair boundary #2',\n   [[764, 38, 847, 39, 859, 959, 58, 877, 56, 252, 44, 46, 23, 992, 525, 972, 997],\n    {'pity': 89, 'guarantee': False}],\n   {'results': 'F----------------', 'pity': 16, 'guarantee': False}),\n  ('hard pity pull #1',\n   [[999, 999], {'pity': 89, 'guarantee': False}],\n   {'results': 'L-', 'pity': 1, 'guarantee': True}),\n  ('control #1', [[54], {'pity': 61, 'guarantee': False}], {'results': '-', 'pity': 62, 'guarantee': False}),\n  ('control #2',\n   [[346, 740, 973, 629, 933, 35, 831, 930, 214, 969, 923], {'pity': 73, 'guarantee': False}],\n   {'results': '-----L-----', 'pity': 5, 'guarantee': True})],\n [('first soft pity pull #1',\n   [[100, 3], {'pity': 73, 'guarantee': True}],\n   {'results': '-F', 'pity': 0, 'guarantee': False}),\n  ('fault site guarantee consumption #1',\n   [[54, 849, 304, 44], {'pity': 72, 'guarantee': True}],\n   {'results': '---F', 'pity': 0, 'guarantee': False}),\n  ('fault site guarantee consumption #2',\n   [[975, 474, 33, 973, 869, 8, 806, 843, 21, 34, 874], {'pity': 88, 'guarantee': True}],\n   {'results': '-F---------', 'pity': 9, 'guarantee': False}),\n  ('partial repair boundary #1',\n   [[456, 631, 879, 18, 33, 855, 6], {'pity': 73, 'guarantee': False}],\n   {'results': '---F---', 'pity': 3, 'guarantee': False}),\n  ('partial repair boundary #2',\n   [[32, 1], {'pity': 73, 'guarantee': False}],\n   {'results': 'FL', 'pity': 0, 'guarantee': True}),\n  ('hard pity pull #1',\n   [[999, 999], {'pity': 89, 'guarantee': False}],\n   {'results': 'L-', 'pity': 1, 'guarantee': True}),\n  ('control #1',\n   [[860, 832, 950, 795, 21, 53, 128, 667, 5, 11, 16], {'pity': 0, 'guarantee': False}],\n   {'results': '--------L--', 'pity': 2, 'guarantee': True}),\n  ('control #2',\n   [[938, 58, 37, 11, 926, 889, 844, 11, 265], {'pity': 0, 'guarantee': False}],\n   {'results': '---------', 'pity': 9, 'guarantee': False})]]\nfor label, args, expected in cases[N-1]:\n    check(label, solve(*args), 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":"92ae5e4ca3c61db1cfe25ecb0908a7fea6669204ca2b5c0e7d64d52ca28fa74f","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(rolls, state):\n    pity = state['pity']\n    guarantee = state['guarantee']\n    out = []\n    for r in rolls:\n        n = pity + 1\n        rate = 6\n        if n >= 74:\n            rate += 50 * (n - 73)\n        if n >= 90 or r < rate:\n            pity = 0\n            if guarantee or r % 2 == 0:\n                out.append('F')\n                guarantee = False\n            else:\n                out.append('L')\n                guarantee = True\n        else:\n            pity = n\n            out.append('-')\n    return {'results': ''.join(out), 'pity': pity, 'guarantee': guarantee}\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\ncases = [[('first soft pity pull #1',\n   [[100, 3], {'pity': 73, 'guarantee': True}],\n   {'results': '-F', 'pity': 0, 'guarantee': False}),\n  ('lost fifty fifty then featured #1',\n   [[1, 999, 0], {'pity': 10, 'guarantee': False}],\n   {'results': 'L-F', 'pity': 0, 'guarantee': False}),\n  ('fault site guarantee consumption #1',\n   [[15, 31, 302, 259, 332, 886, 12, 851, 55, 45, 6, 903, 946, 869, 725], {'pity': 88, 'guarantee': True}],\n   {'results': 'F--------------', 'pity': 14, 'guarantee': False}),\n  ('partial repair boundary #1',\n   [[4, 155, 441, 951, 967, 353, 21], {'pity': 68, 'guarantee': False}],\n   {'results': 'F------', 'pity': 6, 'guarantee': False}),\n  ('partial repair boundary #2',\n   [[4, 42, 253, 999, 775, 819, 42, 973, 811, 307, 835, 958, 247, 22], {'pity': 73, 'guarantee': False}],\n   {'results': 'F-------------', 'pity': 13, 'guarantee': False}),\n  ('hard pity pull #1',\n   [[999, 999], {'pity': 89, 'guarantee': False}],\n   {'results': 'L-', 'pity': 1, 'guarantee': True}),\n  ('control #1',\n   [[922, 571, 11, 40, 49, 776, 996, 952, 946, 14, 108, 822, 888, 25], {'pity': 84, 'guarantee': False}],\n   {'results': '-L------------', 'pity': 12, 'guarantee': True}),\n  ('control #2', [[911], {'pity': 73, 'guarantee': True}], {'results': '-', 'pity': 74, 'guarantee': True})],\n [('lost fifty fifty then featured #1',\n   [[1, 999, 0], {'pity': 10, 'guarantee': False}],\n   {'results': 'L-F', 'pity': 0, 'guarantee': False}),\n  ('fault site guarantee consumption #1',\n   [[15, 31, 302, 259, 332, 886, 12, 851, 55, 45, 6, 903, 946, 869, 725], {'pity': 88, 'guarantee': True}],\n   {'results': 'F--------------', 'pity': 14, 'guarantee': False}),\n  ('fault site guarantee consumption #2',\n   [[507, 965, 27, 525, 851], {'pity': 73, 'guarantee': True}],\n   {'results': '--F--', 'pity': 2, 'guarantee': False}),\n  ('partial repair boundary #1',\n   [[4], {'pity': 73, 'guarantee': False}],\n   {'results': 'F', 'pity': 0, 'guarantee': False}),\n  ('regression guarantee consumption #1',\n   [[50, 38, 898, 817, 564, 877, 22, 812, 15, 0, 190], {'pity': 73, 'guarantee': True}],\n   {'results': 'F--------F-', 'pity': 1, 'guarantee': False}),\n  ('hard pity pull #1',\n   [[999, 999], {'pity': 89, 'guarantee': False}],\n   {'results': 'L-', 'pity': 1, 'guarantee': True}),\n  ('control #1', [[911], {'pity': 73, 'guarantee': True}], {'results': '-', 'pity': 74, 'guarantee': True}),\n  ('control #2',\n   [[18, 973, 5], {'pity': 72, 'guarantee': False}],\n   {'results': '--L', 'pity': 0, 'guarantee': True})],\n [('first soft pity pull #1',\n   [[100, 3], {'pity': 73, 'guarantee': True}],\n   {'results': '-F', 'pity': 0, 'guarantee': False}),\n  ('fault site guarantee consumption #1',\n   [[480, 489, 823, 13, 936, 776, 44, 409, 26, 974, 9, 54, 911, 804, 433, 47, 942, 847],\n    {'pity': 89, 'guarantee': True}],\n   {'results': 'F-----------------', 'pity': 17, 'guarantee': False}),\n  ('fault site guarantee consumption #2',\n   [[935, 90, 29, 166, 937, 997, 903, 315, 848, 1, 893, 36, 218, 730, 858, 726, 972, 10],\n    {'pity': 89, 'guarantee': True}],\n   {'results': 'F--------L--------', 'pity': 8, 'guarantee': True}),\n  ('partial repair boundary #1',\n   [[30, 806], {'pity': 83, 'guarantee': False}],\n   {'results': 'F-', 'pity': 1, 'guarantee': False}),\n  ('partial repair boundary #2',\n   [[891, 307, 20, 907, 30, 974, 462, 957, 860, 624, 42, 985, 46], {'pity': 73, 'guarantee': False}],\n   {'results': '--F----------', 'pity': 10, 'guarantee': False}),\n  ('hard pity pull #1',\n   [[999, 999], {'pity': 89, 'guarantee': False}],\n   {'results': 'L-', 'pity': 1, 'guarantee': True}),\n  ('control #1',\n   [[685, 976, 49, 33, 16, 30, 427, 839], {'pity': 0, 'guarantee': False}],\n   {'results': '--------', 'pity': 8, 'guarantee': False}),\n  ('control #2',\n   [[773, 957, 60, 353, 59, 19, 862, 820, 993, 27, 22, 893, 950], {'pity': 0, 'guarantee': True}],\n   {'results': '-------------', 'pity': 13, 'guarantee': True})],\n [('lost fifty fifty then featured #1',\n   [[1, 999, 0], {'pity': 10, 'guarantee': False}],\n   {'results': 'L-F', 'pity': 0, 'guarantee': False}),\n  ('fault site guarantee consumption #1',\n   [[815, 889, 39, 873, 939, 933, 908, 992, 421, 939, 821, 53, 12, 40, 8, 884, 975, 551, 967, 39],\n    {'pity': 63, 'guarantee': True}],\n   {'results': '-----------F--------', 'pity': 8, 'guarantee': False}),\n  ('fault site guarantee consumption #2',\n   [[18, 16, 60, 53, 197, 713, 972, 933], {'pity': 75, 'guarantee': True}],\n   {'results': 'F-------', 'pity': 7, 'guarantee': False}),\n  ('partial repair boundary #1',\n   [[24, 872, 131, 279, 598, 873, 881, 532, 874, 898, 570, 33, 575, 16, 950, 871, 988, 895, 840],\n    {'pity': 81, 'guarantee': False}],\n   {'results': 'F------------------', 'pity': 18, 'guarantee': False}),\n  ('partial repair boundary #2',\n   [[764, 38, 847, 39, 859, 959, 58, 877, 56, 252, 44, 46, 23, 992, 525, 972, 997],\n    {'pity': 89, 'guarantee': False}],\n   {'results': 'F----------------', 'pity': 16, 'guarantee': False}),\n  ('hard pity pull #1',\n   [[999, 999], {'pity': 89, 'guarantee': False}],\n   {'results': 'L-', 'pity': 1, 'guarantee': True}),\n  ('control #1', [[54], {'pity': 61, 'guarantee': False}], {'results': '-', 'pity': 62, 'guarantee': False}),\n  ('control #2',\n   [[346, 740, 973, 629, 933, 35, 831, 930, 214, 969, 923], {'pity': 73, 'guarantee': False}],\n   {'results': '-----L-----', 'pity': 5, 'guarantee': True})],\n [('first soft pity pull #1',\n   [[100, 3], {'pity': 73, 'guarantee': True}],\n   {'results': '-F', 'pity': 0, 'guarantee': False}),\n  ('fault site guarantee consumption #1',\n   [[54, 849, 304, 44], {'pity': 72, 'guarantee': True}],\n   {'results': '---F', 'pity': 0, 'guarantee': False}),\n  ('fault site guarantee consumption #2',\n   [[975, 474, 33, 973, 869, 8, 806, 843, 21, 34, 874], {'pity': 88, 'guarantee': True}],\n   {'results': '-F---------', 'pity': 9, 'guarantee': False}),\n  ('partial repair boundary #1',\n   [[456, 631, 879, 18, 33, 855, 6], {'pity': 73, 'guarantee': False}],\n   {'results': '---F---', 'pity': 3, 'guarantee': False}),\n  ('partial repair boundary #2',\n   [[32, 1], {'pity': 73, 'guarantee': False}],\n   {'results': 'FL', 'pity': 0, 'guarantee': True}),\n  ('hard pity pull #1',\n   [[999, 999], {'pity': 89, 'guarantee': False}],\n   {'results': 'L-', 'pity': 1, 'guarantee': True}),\n  ('control #1',\n   [[860, 832, 950, 795, 21, 53, 128, 667, 5, 11, 16], {'pity': 0, 'guarantee': False}],\n   {'results': '--------L--', 'pity': 2, 'guarantee': True}),\n  ('control #2',\n   [[938, 58, 37, 11, 926, 889, 844, 11, 265], {'pity': 0, 'guarantee': False}],\n   {'results': '---------', 'pity': 9, 'guarantee': False})]]\nfor label, args, expected in cases[N-1]:\n    check(label, solve(*args), 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":"Deterministic toy contract stipulated for this model; integer or exact arithmetic only, not a reproduction of any specific game engine. 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-game-economy-crafting-balance-banner-pity-guarantee-consumption","generated_at":"2026-09-29T14:50:44.911970+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Game economies leak or destroy currency when one crafting or pricing rule is off by one boundary, rounding stage or state update; the defect is observable in exact integer outcomes.","repair":"Restore `guarantee = False` at the guarantee consumption step.","root_cause":"A featured hit leaves the guarantee flag untouched.","sha256":"58049fe2af1572efdb41f57e3208884b7309770b0b2f005ee00c76f05cc4e945","title":"Banner pity counter: Featured guarantee is never consumed · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":39.573,"exit_code":1,"observations":[{"actual":{"guarantee":false,"pity":0,"results":"-F"},"check":"first soft pity pull #1","expected":{"guarantee":false,"pity":0,"results":"-F"},"passed":true},{"actual":{"guarantee":false,"pity":0,"results":"L-F"},"check":"lost fifty fifty then featured #1","expected":{"guarantee":false,"pity":0,"results":"L-F"},"passed":true},{"actual":{"guarantee":false,"pity":14,"results":"F--------------"},"check":"fault site guarantee consumption #1","expected":{"guarantee":false,"pity":14,"results":"F--------------"},"passed":true},{"actual":{"guarantee":true,"pity":6,"results":"F------"},"check":"partial repair boundary #1","expected":{"guarantee":false,"pity":6,"results":"F------"},"passed":false},{"actual":{"guarantee":true,"pity":13,"results":"F-------------"},"check":"partial repair boundary #2","expected":{"guarantee":false,"pity":13,"results":"F-------------"},"passed":false},{"actual":{"guarantee":true,"pity":1,"results":"L-"},"check":"hard pity pull #1","expected":{"guarantee":true,"pity":1,"results":"L-"},"passed":true},{"actual":{"guarantee":true,"pity":12,"results":"-L------------"},"check":"control #1","expected":{"guarantee":true,"pity":12,"results":"-L------------"},"passed":true},{"actual":{"guarantee":true,"pity":74,"results":"-"},"check":"control #2","expected":{"guarantee":true,"pity":74,"results":"-"},"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"first soft pity pull #1\", \"actual\": {\"results\": \"-F\", \"pity\": 0, \"guarantee\": false}, \"expected\": {\"results\": \"-F\", \"pity\": 0, \"guarantee\": false}, \"passed\": true}, {\"check\": \"lost fifty fifty then featured #1\", \"actual\": {\"results\": \"L-F\", \"pity\": 0, \"guarantee\": false}, \"expected\": {\"results\": \"L-F\", \"pity\": 0, \"guarantee\": false}, \"passed\": true}, {\"check\": \"fault site guarantee consumption #1\", \"actual\": {\"results\": \"F--------------\", \"pity\": 14, \"guarantee\": false}, \"expected\": {\"results\": \"F--------------\", \"pity\": 14, \"guarantee\": false}, \"passed\": true}, {\"check\": \"partial repair boundary #1\", \"actual\": {\"results\": \"F------\", \"pity\": 6, \"guarantee\": true}, \"expected\": {\"results\": \"F------\", \"pity\": 6, \"guarantee\": false}, \"passed\": false}, {\"check\": \"partial repair boundary #2\", \"actual\": {\"results\": \"F-------------\", \"pity\": 13, \"guarantee\": true}, \"expected\": {\"results\": \"F-------------\", \"pity\": 13, \"guarantee\": false}, \"passed\": false}, {\"check\": \"hard pity pull #1\", \"actual\": {\"results\": \"L-\", \"pity\": 1, \"guarantee\": true}, \"expected\": {\"results\": \"L-\", \"pity\": 1, \"guarantee\": true}, \"passed\": true}, {\"check\": \"control #1\", \"actual\": {\"results\": \"-L------------\", \"pity\": 12, \"guarantee\": true}, \"expected\": {\"results\": \"-L------------\", \"pity\": 12, \"guarantee\": true}, \"passed\": true}, {\"check\": \"control #2\", \"actual\": {\"results\": \"-\", \"pity\": 74, \"guarantee\": true}, \"expected\": {\"results\": \"-\", \"pity\": 74, \"guarantee\": true}, \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":38.955,"exit_code":1,"observations":[{"actual":{"guarantee":true,"pity":0,"results":"-F"},"check":"first soft pity pull #1","expected":{"guarantee":false,"pity":0,"results":"-F"},"passed":false},{"actual":{"guarantee":true,"pity":0,"results":"L-F"},"check":"lost fifty fifty then featured #1","expected":{"guarantee":false,"pity":0,"results":"L-F"},"passed":false},{"actual":{"guarantee":true,"pity":14,"results":"F--------------"},"check":"fault site guarantee consumption #1","expected":{"guarantee":false,"pity":14,"results":"F--------------"},"passed":false},{"actual":{"guarantee":false,"pity":6,"results":"F------"},"check":"partial repair boundary #1","expected":{"guarantee":false,"pity":6,"results":"F------"},"passed":true},{"actual":{"guarantee":false,"pity":13,"results":"F-------------"},"check":"partial repair boundary #2","expected":{"guarantee":false,"pity":13,"results":"F-------------"},"passed":true},{"actual":{"guarantee":true,"pity":1,"results":"L-"},"check":"hard pity pull #1","expected":{"guarantee":true,"pity":1,"results":"L-"},"passed":true},{"actual":{"guarantee":true,"pity":12,"results":"-L------------"},"check":"control #1","expected":{"guarantee":true,"pity":12,"results":"-L------------"},"passed":true},{"actual":{"guarantee":true,"pity":74,"results":"-"},"check":"control #2","expected":{"guarantee":true,"pity":74,"results":"-"},"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"first soft pity pull #1\", \"actual\": {\"results\": \"-F\", \"pity\": 0, \"guarantee\": true}, \"expected\": {\"results\": \"-F\", \"pity\": 0, \"guarantee\": false}, \"passed\": false}, {\"check\": \"lost fifty fifty then featured #1\", \"actual\": {\"results\": \"L-F\", \"pity\": 0, \"guarantee\": true}, \"expected\": {\"results\": \"L-F\", \"pity\": 0, \"guarantee\": false}, \"passed\": false}, {\"check\": \"fault site guarantee consumption #1\", \"actual\": {\"results\": \"F--------------\", \"pity\": 14, \"guarantee\": true}, \"expected\": {\"results\": \"F--------------\", \"pity\": 14, \"guarantee\": false}, \"passed\": false}, {\"check\": \"partial repair boundary #1\", \"actual\": {\"results\": \"F------\", \"pity\": 6, \"guarantee\": false}, \"expected\": {\"results\": \"F------\", \"pity\": 6, \"guarantee\": false}, \"passed\": true}, {\"check\": \"partial repair boundary #2\", \"actual\": {\"results\": \"F-------------\", \"pity\": 13, \"guarantee\": false}, \"expected\": {\"results\": \"F-------------\", \"pity\": 13, \"guarantee\": false}, \"passed\": true}, {\"check\": \"hard pity pull #1\", \"actual\": {\"results\": \"L-\", \"pity\": 1, \"guarantee\": true}, \"expected\": {\"results\": \"L-\", \"pity\": 1, \"guarantee\": true}, \"passed\": true}, {\"check\": \"control #1\", \"actual\": {\"results\": \"-L------------\", \"pity\": 12, \"guarantee\": true}, \"expected\": {\"results\": \"-L------------\", \"pity\": 12, \"guarantee\": true}, \"passed\": true}, {\"check\": \"control #2\", \"actual\": {\"results\": \"-\", \"pity\": 74, \"guarantee\": true}, \"expected\": {\"results\": \"-\", \"pity\": 74, \"guarantee\": true}, \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":40.823,"exit_code":0,"observations":[{"actual":{"guarantee":false,"pity":0,"results":"-F"},"check":"first soft pity pull #1","expected":{"guarantee":false,"pity":0,"results":"-F"},"passed":true},{"actual":{"guarantee":false,"pity":0,"results":"L-F"},"check":"lost fifty fifty then featured #1","expected":{"guarantee":false,"pity":0,"results":"L-F"},"passed":true},{"actual":{"guarantee":false,"pity":14,"results":"F--------------"},"check":"fault site guarantee consumption #1","expected":{"guarantee":false,"pity":14,"results":"F--------------"},"passed":true},{"actual":{"guarantee":false,"pity":6,"results":"F------"},"check":"partial repair boundary #1","expected":{"guarantee":false,"pity":6,"results":"F------"},"passed":true},{"actual":{"guarantee":false,"pity":13,"results":"F-------------"},"check":"partial repair boundary #2","expected":{"guarantee":false,"pity":13,"results":"F-------------"},"passed":true},{"actual":{"guarantee":true,"pity":1,"results":"L-"},"check":"hard pity pull #1","expected":{"guarantee":true,"pity":1,"results":"L-"},"passed":true},{"actual":{"guarantee":true,"pity":12,"results":"-L------------"},"check":"control #1","expected":{"guarantee":true,"pity":12,"results":"-L------------"},"passed":true},{"actual":{"guarantee":true,"pity":74,"results":"-"},"check":"control #2","expected":{"guarantee":true,"pity":74,"results":"-"},"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"first soft pity pull #1\", \"actual\": {\"results\": \"-F\", \"pity\": 0, \"guarantee\": false}, \"expected\": {\"results\": \"-F\", \"pity\": 0, \"guarantee\": false}, \"passed\": true}, {\"check\": \"lost fifty fifty then featured #1\", \"actual\": {\"results\": \"L-F\", \"pity\": 0, \"guarantee\": false}, \"expected\": {\"results\": \"L-F\", \"pity\": 0, \"guarantee\": false}, \"passed\": true}, {\"check\": \"fault site guarantee consumption #1\", \"actual\": {\"results\": \"F--------------\", \"pity\": 14, \"guarantee\": false}, \"expected\": {\"results\": \"F--------------\", \"pity\": 14, \"guarantee\": false}, \"passed\": true}, {\"check\": \"partial repair boundary #1\", \"actual\": {\"results\": \"F------\", \"pity\": 6, \"guarantee\": false}, \"expected\": {\"results\": \"F------\", \"pity\": 6, \"guarantee\": false}, \"passed\": true}, {\"check\": \"partial repair boundary #2\", \"actual\": {\"results\": \"F-------------\", \"pity\": 13, \"guarantee\": false}, \"expected\": {\"results\": \"F-------------\", \"pity\": 13, \"guarantee\": false}, \"passed\": true}, {\"check\": \"hard pity pull #1\", \"actual\": {\"results\": \"L-\", \"pity\": 1, \"guarantee\": true}, \"expected\": {\"results\": \"L-\", \"pity\": 1, \"guarantee\": true}, \"passed\": true}, {\"check\": \"control #1\", \"actual\": {\"results\": \"-L------------\", \"pity\": 12, \"guarantee\": true}, \"expected\": {\"results\": \"-L------------\", \"pity\": 12, \"guarantee\": true}, \"passed\": true}, {\"check\": \"control #2\", \"actual\": {\"results\": \"-\", \"pity\": 74, \"guarantee\": true}, \"expected\": {\"results\": \"-\", \"pity\": 74, \"guarantee\": true}, \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}