FAILURE MAP
← Case archive

FA-63506 / Actuarial life tables / Open access

Net level annual premium: Premium periods longer than the term are accepted · case 01

A 7-pay 5-year term returns a premium.

Verified by executionVariant 1 · 8 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The m>n check is missing.

VERIFIED REPAIR

Reject m greater than n.

Unsuccessful approach: Comparing m with the table length still admits m>n.

Case contract

Input q (per 100000), n (coverage years), m (premium years, 1<=m<=n and n<=table length else 'invalid'), type term|endowment (else 'invalid type'), i (per mille), benefit. A = sum v^(k+1) kp q_k (+ v^n np for endowment); premium annuity-due over m years; return benefit*A/annuity rounded half-up.

Why this case matters

Life-table arithmetic compounds across ages, so one misplaced index or assumption shifts every downstream value.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(x):
    qs=[Fraction(q,100000) for q in x['q']]; n=x['n']; m=x['m']
    if m<1 or n>len(qs): return 'invalid'
    if x['type'] not in ('term','endowment'): return 'invalid type'
    v=1/(1+Fraction(x['i'],1000))
    A=Fraction(0); ann=Fraction(0); kp=Fraction(1)
    for k in range(n):
        if k<m: ann+=v**k*kp
        A+=v**(k+1)*kp*qs[k]
        kp*=1-qs[k]
    if x['type']=='endowment': A+=v**n*kp
    return math.floor(x['benefit']*A/ann+Fraction(1,2))
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['limited pay term', {'q': [1116, 1354, 1667, 2034, 2465, 2963, 3571, 4298, 5197, 6274, 7556, 9080], 'n': 10, 'm': 6, 'type': 'term', 'i': 50, 'benefit': 32417307}, 1236317], ['limited pay endowment', {'q': [805, 1014, 1237, 1505, 1844, 2262, 2735, 3316, 3991, 4822, 5826, 6998], 'n': 8, 'm': 3, 'type': 'endowment', 'i': 50, 'benefit': 53744860}, 13078746], ['full pay endowment', {'q': [1226, 1472, 1786, 2144, 2583, 3103, 3749, 4533, 5446, 6546, 7888, 9479], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 30, 'benefit': 17182267}, 2700402], ['full pay term', {'q': [636, 786, 984, 1192, 1450, 1750, 2140, 2614, 3160, 3797, 4603, 5551], 'n': 12, 'm': 12, 'type': 'term', 'i': 50, 'benefit': 77720826}, 1517456], ['single premium', {'q': [586, 718, 878, 1062, 1306, 1614, 1972, 2399, 2899, 3512, 4240, 5126], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 40, 'benefit': 23235362}, 19155246], ['pay period exceeds term', {'q': [704, 861, 1036, 1286, 1567, 1897, 2281, 2786, 3359, 4046, 4868, 5860], 'n': 5, 'm': 7, 'type': 'term', 'i': 40, 'benefit': 97510456}, 'invalid'], ['unknown plan type', {'q': [966, 1164, 1413, 1738, 2095, 2527, 3060, 3675, 4454, 5384, 6480, 7790], 'n': 5, 'm': 5, 'type': 'whole', 'i': 50, 'benefit': 52803794}, 'invalid type'], ['term too long for table', {'q': [1168, 1420, 1752, 2109, 2552, 3075, 3725, 4498, 5446, 6543, 7899, 9488], 'n': 13, 'm': 5, 'type': 'term', 'i': 30, 'benefit': 68032420}, 'invalid']], [['limited pay term', {'q': [841, 1053, 1267, 1547, 1901, 2290, 2783, 3379, 4070, 4927, 5917, 7143], 'n': 10, 'm': 5, 'type': 'term', 'i': 40, 'benefit': 10621995}, 390243], ['limited pay endowment', {'q': [1237, 1529, 1837, 2215, 2701, 3286, 3958, 4782, 5775, 6980, 8396, 10091], 'n': 8, 'm': 4, 'type': 'endowment', 'i': 50, 'benefit': 28755476}, 5487845], ['full pay endowment', {'q': [1149, 1421, 1734, 2104, 2524, 3074, 3738, 4524, 5429, 6522, 7842, 9459], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 50, 'benefit': 68984205}, 10136985], ['full pay term', {'q': [1155, 1401, 1706, 2084, 2505, 3052, 3702, 4479, 5396, 6523, 7831, 9442], 'n': 12, 'm': 12, 'type': 'term', 'i': 50, 'benefit': 77815499}, 2534596], ['single premium', {'q': [1488, 1827, 2210, 2701, 3269, 3941, 4765, 5757, 6948, 8343, 10034, 12042], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 30, 'benefit': 10091605}, 8753895], ['pay period exceeds term', {'q': [1434, 1757, 2137, 2589, 3128, 3764, 4523, 5445, 6554, 7912, 9512, 11438], 'n': 5, 'm': 7, 'type': 'term', 'i': 30, 'benefit': 70676453}, 'invalid'], ['unknown plan type', {'q': [1212, 1472, 1779, 2143, 2614, 3137, 3779, 4543, 5470, 6612, 7956, 9572], 'n': 5, 'm': 5, 'type': 'whole', 'i': 30, 'benefit': 15889609}, 'invalid type'], ['term too long for table', {'q': [663, 804, 993, 1231, 1479, 1787, 2159, 2637, 3213, 3881, 4704, 5656], 'n': 13, 'm': 5, 'type': 'term', 'i': 50, 'benefit': 54460124}, 'invalid']], [['limited pay term', {'q': [747, 913, 1131, 1395, 1717, 2081, 2524, 3065, 3693, 4464, 5404, 6511], 'n': 10, 'm': 5, 'type': 'term', 'i': 30, 'benefit': 87228387}, 3048879], ['limited pay endowment', {'q': [829, 1036, 1275, 1538, 1848, 2245, 2727, 3321, 4019, 4840, 5840, 7033], 'n': 8, 'm': 5, 'type': 'endowment', 'i': 40, 'benefit': 74915366}, 12250027], ['full pay endowment', {'q': [1425, 1755, 2109, 2552, 3068, 3709, 4452, 5354, 6453, 7758, 9346, 11251], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 40, 'benefit': 37157222}, 5700405], ['full pay term', {'q': [1109, 1368, 1651, 2017, 2431, 2939, 3572, 4303, 5195, 6284, 7585, 9152], 'n': 12, 'm': 12, 'type': 'term', 'i': 50, 'benefit': 11656982}, 367794], ['single premium', {'q': [526, 657, 804, 1002, 1248, 1531, 1861, 2269, 2740, 3321, 4011, 4832], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 40, 'benefit': 36779454}, 30313184], ['pay period exceeds term', {'q': [1308, 1603, 1941, 2359, 2865, 3473, 4180, 5051, 6103, 7351, 8863, 10680], 'n': 5, 'm': 7, 'type': 'term', 'i': 40, 'benefit': 33579689}, 'invalid'], ['unknown plan type', {'q': [1363, 1655, 1992, 2437, 2924, 3536, 4286, 5167, 6239, 7489, 9002, 10816], 'n': 5, 'm': 5, 'type': 'whole', 'i': 50, 'benefit': 98225689}, 'invalid type'], ['term too long for table', {'q': [1070, 1313, 1595, 1918, 2328, 2810, 3419, 4135, 5012, 6063, 7304, 8777], 'n': 13, 'm': 5, 'type': 'term', 'i': 50, 'benefit': 38738726}, 'invalid']], [['limited pay term', {'q': [512, 643, 815, 1003, 1212, 1489, 1831, 2210, 2664, 3227, 3916, 4712], 'n': 10, 'm': 3, 'type': 'term', 'i': 50, 'benefit': 45807977}, 1688215], ['limited pay endowment', {'q': [590, 709, 861, 1043, 1276, 1575, 1926, 2361, 2871, 3492, 4201, 5086], 'n': 8, 'm': 3, 'type': 'endowment', 'i': 40, 'benefit': 38192191}, 9833950], ['full pay endowment', {'q': [528, 644, 806, 1014, 1235, 1482, 1819, 2204, 2655, 3234, 3922, 4713], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 40, 'benefit': 71007672}, 10519104], ['full pay term', {'q': [1074, 1331, 1597, 1959, 2390, 2877, 3476, 4185, 5055, 6067, 7296, 8779], 'n': 12, 'm': 12, 'type': 'term', 'i': 30, 'benefit': 83944206}, 2733193], ['single premium', {'q': [678, 813, 994, 1206, 1488, 1828, 2220, 2693, 3274, 3956, 4750, 5720], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 40, 'benefit': 89899331}, 74144103], ['pay period exceeds term', {'q': [983, 1186, 1467, 1792, 2157, 2607, 3155, 3832, 4617, 5558, 6707, 8062], 'n': 5, 'm': 7, 'type': 'term', 'i': 30, 'benefit': 49415695}, 'invalid'], ['unknown plan type', {'q': [730, 884, 1091, 1323, 1616, 1984, 2415, 2929, 3548, 4275, 5150, 6215], 'n': 5, 'm': 5, 'type': 'whole', 'i': 50, 'benefit': 99033643}, 'invalid type'], ['term too long for table', {'q': [1353, 1640, 1996, 2435, 2922, 3548, 4298, 5204, 6275, 7580, 9134, 10967], 'n': 13, 'm': 5, 'type': 'term', 'i': 30, 'benefit': 56917171}, 'invalid']], [['limited pay term', {'q': [855, 1042, 1283, 1573, 1895, 2291, 2795, 3365, 4084, 4937, 5928, 7133], 'n': 10, 'm': 4, 'type': 'term', 'i': 30, 'benefit': 26591939}, 1254982], ['limited pay endowment', {'q': [1284, 1558, 1913, 2335, 2838, 3409, 4127, 4953, 5987, 7192, 8649, 10419], 'n': 8, 'm': 5, 'type': 'endowment', 'i': 40, 'benefit': 31636962}, 5267026], ['full pay endowment', {'q': [689, 831, 1026, 1257, 1516, 1826, 2201, 2686, 3249, 3931, 4730, 5695], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 40, 'benefit': 16318284}, 2431737], ['full pay term', {'q': [631, 779, 957, 1167, 1436, 1770, 2163, 2608, 3149, 3826, 4607, 5557], 'n': 12, 'm': 12, 'type': 'term', 'i': 40, 'benefit': 14803880}, 297673], ['single premium', {'q': [1499, 1817, 2219, 2684, 3268, 3964, 4795, 5778, 6979, 8381, 10061, 12080], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 30, 'benefit': 45588105}, 39545285], ['pay period exceeds term', {'q': [1089, 1329, 1604, 1944, 2381, 2862, 3441, 4130, 4970, 5966, 7192, 8664], 'n': 5, 'm': 7, 'type': 'term', 'i': 30, 'benefit': 16169173}, 'invalid'], ['unknown plan type', {'q': [627, 776, 934, 1161, 1422, 1733, 2096, 2520, 3024, 3638, 4377, 5280], 'n': 5, 'm': 5, 'type': 'whole', 'i': 30, 'benefit': 97706465}, 'invalid type'], ['term too long for table', {'q': [697, 840, 1013, 1239, 1511, 1819, 2198, 2660, 3234, 3882, 4708, 5676], 'n': 13, 'm': 5, 'type': 'term', 'i': 50, 'benefit': 62443585}, 'invalid']]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(args), 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 fixtureActualExpectedOutcome
limited pay term12363171236317Passed
limited pay endowment1307874613078746Passed
full pay endowment27004022700402Passed
full pay term15174561517456Passed
single premium1915524619155246Passed
pay period exceeds term1003055invalidFailed
unknown plan typeinvalid typeinvalid typePassed
term too long for tableinvalidinvalidPassed

SHA-256 / b6cfe357759be6bda5f48d753aee958b336f0bcd37b7b2a5c961ac4542855bee

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(x):
    qs=[Fraction(q,100000) for q in x['q']]; n=x['n']; m=x['m']
    if m>len(qs) or m<1 or n>len(qs): return 'invalid'
    if x['type'] not in ('term','endowment'): return 'invalid type'
    v=1/(1+Fraction(x['i'],1000))
    A=Fraction(0); ann=Fraction(0); kp=Fraction(1)
    for k in range(n):
        if k<m: ann+=v**k*kp
        A+=v**(k+1)*kp*qs[k]
        kp*=1-qs[k]
    if x['type']=='endowment': A+=v**n*kp
    return math.floor(x['benefit']*A/ann+Fraction(1,2))
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['limited pay term', {'q': [1116, 1354, 1667, 2034, 2465, 2963, 3571, 4298, 5197, 6274, 7556, 9080], 'n': 10, 'm': 6, 'type': 'term', 'i': 50, 'benefit': 32417307}, 1236317], ['limited pay endowment', {'q': [805, 1014, 1237, 1505, 1844, 2262, 2735, 3316, 3991, 4822, 5826, 6998], 'n': 8, 'm': 3, 'type': 'endowment', 'i': 50, 'benefit': 53744860}, 13078746], ['full pay endowment', {'q': [1226, 1472, 1786, 2144, 2583, 3103, 3749, 4533, 5446, 6546, 7888, 9479], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 30, 'benefit': 17182267}, 2700402], ['full pay term', {'q': [636, 786, 984, 1192, 1450, 1750, 2140, 2614, 3160, 3797, 4603, 5551], 'n': 12, 'm': 12, 'type': 'term', 'i': 50, 'benefit': 77720826}, 1517456], ['single premium', {'q': [586, 718, 878, 1062, 1306, 1614, 1972, 2399, 2899, 3512, 4240, 5126], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 40, 'benefit': 23235362}, 19155246], ['pay period exceeds term', {'q': [704, 861, 1036, 1286, 1567, 1897, 2281, 2786, 3359, 4046, 4868, 5860], 'n': 5, 'm': 7, 'type': 'term', 'i': 40, 'benefit': 97510456}, 'invalid'], ['unknown plan type', {'q': [966, 1164, 1413, 1738, 2095, 2527, 3060, 3675, 4454, 5384, 6480, 7790], 'n': 5, 'm': 5, 'type': 'whole', 'i': 50, 'benefit': 52803794}, 'invalid type'], ['term too long for table', {'q': [1168, 1420, 1752, 2109, 2552, 3075, 3725, 4498, 5446, 6543, 7899, 9488], 'n': 13, 'm': 5, 'type': 'term', 'i': 30, 'benefit': 68032420}, 'invalid']], [['limited pay term', {'q': [841, 1053, 1267, 1547, 1901, 2290, 2783, 3379, 4070, 4927, 5917, 7143], 'n': 10, 'm': 5, 'type': 'term', 'i': 40, 'benefit': 10621995}, 390243], ['limited pay endowment', {'q': [1237, 1529, 1837, 2215, 2701, 3286, 3958, 4782, 5775, 6980, 8396, 10091], 'n': 8, 'm': 4, 'type': 'endowment', 'i': 50, 'benefit': 28755476}, 5487845], ['full pay endowment', {'q': [1149, 1421, 1734, 2104, 2524, 3074, 3738, 4524, 5429, 6522, 7842, 9459], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 50, 'benefit': 68984205}, 10136985], ['full pay term', {'q': [1155, 1401, 1706, 2084, 2505, 3052, 3702, 4479, 5396, 6523, 7831, 9442], 'n': 12, 'm': 12, 'type': 'term', 'i': 50, 'benefit': 77815499}, 2534596], ['single premium', {'q': [1488, 1827, 2210, 2701, 3269, 3941, 4765, 5757, 6948, 8343, 10034, 12042], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 30, 'benefit': 10091605}, 8753895], ['pay period exceeds term', {'q': [1434, 1757, 2137, 2589, 3128, 3764, 4523, 5445, 6554, 7912, 9512, 11438], 'n': 5, 'm': 7, 'type': 'term', 'i': 30, 'benefit': 70676453}, 'invalid'], ['unknown plan type', {'q': [1212, 1472, 1779, 2143, 2614, 3137, 3779, 4543, 5470, 6612, 7956, 9572], 'n': 5, 'm': 5, 'type': 'whole', 'i': 30, 'benefit': 15889609}, 'invalid type'], ['term too long for table', {'q': [663, 804, 993, 1231, 1479, 1787, 2159, 2637, 3213, 3881, 4704, 5656], 'n': 13, 'm': 5, 'type': 'term', 'i': 50, 'benefit': 54460124}, 'invalid']], [['limited pay term', {'q': [747, 913, 1131, 1395, 1717, 2081, 2524, 3065, 3693, 4464, 5404, 6511], 'n': 10, 'm': 5, 'type': 'term', 'i': 30, 'benefit': 87228387}, 3048879], ['limited pay endowment', {'q': [829, 1036, 1275, 1538, 1848, 2245, 2727, 3321, 4019, 4840, 5840, 7033], 'n': 8, 'm': 5, 'type': 'endowment', 'i': 40, 'benefit': 74915366}, 12250027], ['full pay endowment', {'q': [1425, 1755, 2109, 2552, 3068, 3709, 4452, 5354, 6453, 7758, 9346, 11251], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 40, 'benefit': 37157222}, 5700405], ['full pay term', {'q': [1109, 1368, 1651, 2017, 2431, 2939, 3572, 4303, 5195, 6284, 7585, 9152], 'n': 12, 'm': 12, 'type': 'term', 'i': 50, 'benefit': 11656982}, 367794], ['single premium', {'q': [526, 657, 804, 1002, 1248, 1531, 1861, 2269, 2740, 3321, 4011, 4832], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 40, 'benefit': 36779454}, 30313184], ['pay period exceeds term', {'q': [1308, 1603, 1941, 2359, 2865, 3473, 4180, 5051, 6103, 7351, 8863, 10680], 'n': 5, 'm': 7, 'type': 'term', 'i': 40, 'benefit': 33579689}, 'invalid'], ['unknown plan type', {'q': [1363, 1655, 1992, 2437, 2924, 3536, 4286, 5167, 6239, 7489, 9002, 10816], 'n': 5, 'm': 5, 'type': 'whole', 'i': 50, 'benefit': 98225689}, 'invalid type'], ['term too long for table', {'q': [1070, 1313, 1595, 1918, 2328, 2810, 3419, 4135, 5012, 6063, 7304, 8777], 'n': 13, 'm': 5, 'type': 'term', 'i': 50, 'benefit': 38738726}, 'invalid']], [['limited pay term', {'q': [512, 643, 815, 1003, 1212, 1489, 1831, 2210, 2664, 3227, 3916, 4712], 'n': 10, 'm': 3, 'type': 'term', 'i': 50, 'benefit': 45807977}, 1688215], ['limited pay endowment', {'q': [590, 709, 861, 1043, 1276, 1575, 1926, 2361, 2871, 3492, 4201, 5086], 'n': 8, 'm': 3, 'type': 'endowment', 'i': 40, 'benefit': 38192191}, 9833950], ['full pay endowment', {'q': [528, 644, 806, 1014, 1235, 1482, 1819, 2204, 2655, 3234, 3922, 4713], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 40, 'benefit': 71007672}, 10519104], ['full pay term', {'q': [1074, 1331, 1597, 1959, 2390, 2877, 3476, 4185, 5055, 6067, 7296, 8779], 'n': 12, 'm': 12, 'type': 'term', 'i': 30, 'benefit': 83944206}, 2733193], ['single premium', {'q': [678, 813, 994, 1206, 1488, 1828, 2220, 2693, 3274, 3956, 4750, 5720], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 40, 'benefit': 89899331}, 74144103], ['pay period exceeds term', {'q': [983, 1186, 1467, 1792, 2157, 2607, 3155, 3832, 4617, 5558, 6707, 8062], 'n': 5, 'm': 7, 'type': 'term', 'i': 30, 'benefit': 49415695}, 'invalid'], ['unknown plan type', {'q': [730, 884, 1091, 1323, 1616, 1984, 2415, 2929, 3548, 4275, 5150, 6215], 'n': 5, 'm': 5, 'type': 'whole', 'i': 50, 'benefit': 99033643}, 'invalid type'], ['term too long for table', {'q': [1353, 1640, 1996, 2435, 2922, 3548, 4298, 5204, 6275, 7580, 9134, 10967], 'n': 13, 'm': 5, 'type': 'term', 'i': 30, 'benefit': 56917171}, 'invalid']], [['limited pay term', {'q': [855, 1042, 1283, 1573, 1895, 2291, 2795, 3365, 4084, 4937, 5928, 7133], 'n': 10, 'm': 4, 'type': 'term', 'i': 30, 'benefit': 26591939}, 1254982], ['limited pay endowment', {'q': [1284, 1558, 1913, 2335, 2838, 3409, 4127, 4953, 5987, 7192, 8649, 10419], 'n': 8, 'm': 5, 'type': 'endowment', 'i': 40, 'benefit': 31636962}, 5267026], ['full pay endowment', {'q': [689, 831, 1026, 1257, 1516, 1826, 2201, 2686, 3249, 3931, 4730, 5695], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 40, 'benefit': 16318284}, 2431737], ['full pay term', {'q': [631, 779, 957, 1167, 1436, 1770, 2163, 2608, 3149, 3826, 4607, 5557], 'n': 12, 'm': 12, 'type': 'term', 'i': 40, 'benefit': 14803880}, 297673], ['single premium', {'q': [1499, 1817, 2219, 2684, 3268, 3964, 4795, 5778, 6979, 8381, 10061, 12080], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 30, 'benefit': 45588105}, 39545285], ['pay period exceeds term', {'q': [1089, 1329, 1604, 1944, 2381, 2862, 3441, 4130, 4970, 5966, 7192, 8664], 'n': 5, 'm': 7, 'type': 'term', 'i': 30, 'benefit': 16169173}, 'invalid'], ['unknown plan type', {'q': [627, 776, 934, 1161, 1422, 1733, 2096, 2520, 3024, 3638, 4377, 5280], 'n': 5, 'm': 5, 'type': 'whole', 'i': 30, 'benefit': 97706465}, 'invalid type'], ['term too long for table', {'q': [697, 840, 1013, 1239, 1511, 1819, 2198, 2660, 3234, 3882, 4708, 5676], 'n': 13, 'm': 5, 'type': 'term', 'i': 50, 'benefit': 62443585}, 'invalid']]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(args), 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 fixtureActualExpectedOutcome
limited pay term12363171236317Passed
limited pay endowment1307874613078746Passed
full pay endowment27004022700402Passed
full pay term15174561517456Passed
single premium1915524619155246Passed
pay period exceeds term1003055invalidFailed
unknown plan typeinvalid typeinvalid typePassed
term too long for tableinvalidinvalidPassed

SHA-256 / 68c3965368d1fbb5b1068fb71be77acd826097de17bca7a57bca7c488e4a0bdf

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(x):
    qs=[Fraction(q,100000) for q in x['q']]; n=x['n']; m=x['m']
    if m>n or m<1 or n>len(qs): return 'invalid'
    if x['type'] not in ('term','endowment'): return 'invalid type'
    v=1/(1+Fraction(x['i'],1000))
    A=Fraction(0); ann=Fraction(0); kp=Fraction(1)
    for k in range(n):
        if k<m: ann+=v**k*kp
        A+=v**(k+1)*kp*qs[k]
        kp*=1-qs[k]
    if x['type']=='endowment': A+=v**n*kp
    return math.floor(x['benefit']*A/ann+Fraction(1,2))
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['limited pay term', {'q': [1116, 1354, 1667, 2034, 2465, 2963, 3571, 4298, 5197, 6274, 7556, 9080], 'n': 10, 'm': 6, 'type': 'term', 'i': 50, 'benefit': 32417307}, 1236317], ['limited pay endowment', {'q': [805, 1014, 1237, 1505, 1844, 2262, 2735, 3316, 3991, 4822, 5826, 6998], 'n': 8, 'm': 3, 'type': 'endowment', 'i': 50, 'benefit': 53744860}, 13078746], ['full pay endowment', {'q': [1226, 1472, 1786, 2144, 2583, 3103, 3749, 4533, 5446, 6546, 7888, 9479], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 30, 'benefit': 17182267}, 2700402], ['full pay term', {'q': [636, 786, 984, 1192, 1450, 1750, 2140, 2614, 3160, 3797, 4603, 5551], 'n': 12, 'm': 12, 'type': 'term', 'i': 50, 'benefit': 77720826}, 1517456], ['single premium', {'q': [586, 718, 878, 1062, 1306, 1614, 1972, 2399, 2899, 3512, 4240, 5126], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 40, 'benefit': 23235362}, 19155246], ['pay period exceeds term', {'q': [704, 861, 1036, 1286, 1567, 1897, 2281, 2786, 3359, 4046, 4868, 5860], 'n': 5, 'm': 7, 'type': 'term', 'i': 40, 'benefit': 97510456}, 'invalid'], ['unknown plan type', {'q': [966, 1164, 1413, 1738, 2095, 2527, 3060, 3675, 4454, 5384, 6480, 7790], 'n': 5, 'm': 5, 'type': 'whole', 'i': 50, 'benefit': 52803794}, 'invalid type'], ['term too long for table', {'q': [1168, 1420, 1752, 2109, 2552, 3075, 3725, 4498, 5446, 6543, 7899, 9488], 'n': 13, 'm': 5, 'type': 'term', 'i': 30, 'benefit': 68032420}, 'invalid']], [['limited pay term', {'q': [841, 1053, 1267, 1547, 1901, 2290, 2783, 3379, 4070, 4927, 5917, 7143], 'n': 10, 'm': 5, 'type': 'term', 'i': 40, 'benefit': 10621995}, 390243], ['limited pay endowment', {'q': [1237, 1529, 1837, 2215, 2701, 3286, 3958, 4782, 5775, 6980, 8396, 10091], 'n': 8, 'm': 4, 'type': 'endowment', 'i': 50, 'benefit': 28755476}, 5487845], ['full pay endowment', {'q': [1149, 1421, 1734, 2104, 2524, 3074, 3738, 4524, 5429, 6522, 7842, 9459], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 50, 'benefit': 68984205}, 10136985], ['full pay term', {'q': [1155, 1401, 1706, 2084, 2505, 3052, 3702, 4479, 5396, 6523, 7831, 9442], 'n': 12, 'm': 12, 'type': 'term', 'i': 50, 'benefit': 77815499}, 2534596], ['single premium', {'q': [1488, 1827, 2210, 2701, 3269, 3941, 4765, 5757, 6948, 8343, 10034, 12042], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 30, 'benefit': 10091605}, 8753895], ['pay period exceeds term', {'q': [1434, 1757, 2137, 2589, 3128, 3764, 4523, 5445, 6554, 7912, 9512, 11438], 'n': 5, 'm': 7, 'type': 'term', 'i': 30, 'benefit': 70676453}, 'invalid'], ['unknown plan type', {'q': [1212, 1472, 1779, 2143, 2614, 3137, 3779, 4543, 5470, 6612, 7956, 9572], 'n': 5, 'm': 5, 'type': 'whole', 'i': 30, 'benefit': 15889609}, 'invalid type'], ['term too long for table', {'q': [663, 804, 993, 1231, 1479, 1787, 2159, 2637, 3213, 3881, 4704, 5656], 'n': 13, 'm': 5, 'type': 'term', 'i': 50, 'benefit': 54460124}, 'invalid']], [['limited pay term', {'q': [747, 913, 1131, 1395, 1717, 2081, 2524, 3065, 3693, 4464, 5404, 6511], 'n': 10, 'm': 5, 'type': 'term', 'i': 30, 'benefit': 87228387}, 3048879], ['limited pay endowment', {'q': [829, 1036, 1275, 1538, 1848, 2245, 2727, 3321, 4019, 4840, 5840, 7033], 'n': 8, 'm': 5, 'type': 'endowment', 'i': 40, 'benefit': 74915366}, 12250027], ['full pay endowment', {'q': [1425, 1755, 2109, 2552, 3068, 3709, 4452, 5354, 6453, 7758, 9346, 11251], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 40, 'benefit': 37157222}, 5700405], ['full pay term', {'q': [1109, 1368, 1651, 2017, 2431, 2939, 3572, 4303, 5195, 6284, 7585, 9152], 'n': 12, 'm': 12, 'type': 'term', 'i': 50, 'benefit': 11656982}, 367794], ['single premium', {'q': [526, 657, 804, 1002, 1248, 1531, 1861, 2269, 2740, 3321, 4011, 4832], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 40, 'benefit': 36779454}, 30313184], ['pay period exceeds term', {'q': [1308, 1603, 1941, 2359, 2865, 3473, 4180, 5051, 6103, 7351, 8863, 10680], 'n': 5, 'm': 7, 'type': 'term', 'i': 40, 'benefit': 33579689}, 'invalid'], ['unknown plan type', {'q': [1363, 1655, 1992, 2437, 2924, 3536, 4286, 5167, 6239, 7489, 9002, 10816], 'n': 5, 'm': 5, 'type': 'whole', 'i': 50, 'benefit': 98225689}, 'invalid type'], ['term too long for table', {'q': [1070, 1313, 1595, 1918, 2328, 2810, 3419, 4135, 5012, 6063, 7304, 8777], 'n': 13, 'm': 5, 'type': 'term', 'i': 50, 'benefit': 38738726}, 'invalid']], [['limited pay term', {'q': [512, 643, 815, 1003, 1212, 1489, 1831, 2210, 2664, 3227, 3916, 4712], 'n': 10, 'm': 3, 'type': 'term', 'i': 50, 'benefit': 45807977}, 1688215], ['limited pay endowment', {'q': [590, 709, 861, 1043, 1276, 1575, 1926, 2361, 2871, 3492, 4201, 5086], 'n': 8, 'm': 3, 'type': 'endowment', 'i': 40, 'benefit': 38192191}, 9833950], ['full pay endowment', {'q': [528, 644, 806, 1014, 1235, 1482, 1819, 2204, 2655, 3234, 3922, 4713], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 40, 'benefit': 71007672}, 10519104], ['full pay term', {'q': [1074, 1331, 1597, 1959, 2390, 2877, 3476, 4185, 5055, 6067, 7296, 8779], 'n': 12, 'm': 12, 'type': 'term', 'i': 30, 'benefit': 83944206}, 2733193], ['single premium', {'q': [678, 813, 994, 1206, 1488, 1828, 2220, 2693, 3274, 3956, 4750, 5720], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 40, 'benefit': 89899331}, 74144103], ['pay period exceeds term', {'q': [983, 1186, 1467, 1792, 2157, 2607, 3155, 3832, 4617, 5558, 6707, 8062], 'n': 5, 'm': 7, 'type': 'term', 'i': 30, 'benefit': 49415695}, 'invalid'], ['unknown plan type', {'q': [730, 884, 1091, 1323, 1616, 1984, 2415, 2929, 3548, 4275, 5150, 6215], 'n': 5, 'm': 5, 'type': 'whole', 'i': 50, 'benefit': 99033643}, 'invalid type'], ['term too long for table', {'q': [1353, 1640, 1996, 2435, 2922, 3548, 4298, 5204, 6275, 7580, 9134, 10967], 'n': 13, 'm': 5, 'type': 'term', 'i': 30, 'benefit': 56917171}, 'invalid']], [['limited pay term', {'q': [855, 1042, 1283, 1573, 1895, 2291, 2795, 3365, 4084, 4937, 5928, 7133], 'n': 10, 'm': 4, 'type': 'term', 'i': 30, 'benefit': 26591939}, 1254982], ['limited pay endowment', {'q': [1284, 1558, 1913, 2335, 2838, 3409, 4127, 4953, 5987, 7192, 8649, 10419], 'n': 8, 'm': 5, 'type': 'endowment', 'i': 40, 'benefit': 31636962}, 5267026], ['full pay endowment', {'q': [689, 831, 1026, 1257, 1516, 1826, 2201, 2686, 3249, 3931, 4730, 5695], 'n': 6, 'm': 6, 'type': 'endowment', 'i': 40, 'benefit': 16318284}, 2431737], ['full pay term', {'q': [631, 779, 957, 1167, 1436, 1770, 2163, 2608, 3149, 3826, 4607, 5557], 'n': 12, 'm': 12, 'type': 'term', 'i': 40, 'benefit': 14803880}, 297673], ['single premium', {'q': [1499, 1817, 2219, 2684, 3268, 3964, 4795, 5778, 6979, 8381, 10061, 12080], 'n': 5, 'm': 1, 'type': 'endowment', 'i': 30, 'benefit': 45588105}, 39545285], ['pay period exceeds term', {'q': [1089, 1329, 1604, 1944, 2381, 2862, 3441, 4130, 4970, 5966, 7192, 8664], 'n': 5, 'm': 7, 'type': 'term', 'i': 30, 'benefit': 16169173}, 'invalid'], ['unknown plan type', {'q': [627, 776, 934, 1161, 1422, 1733, 2096, 2520, 3024, 3638, 4377, 5280], 'n': 5, 'm': 5, 'type': 'whole', 'i': 30, 'benefit': 97706465}, 'invalid type'], ['term too long for table', {'q': [697, 840, 1013, 1239, 1511, 1819, 2198, 2660, 3234, 3882, 4708, 5676], 'n': 13, 'm': 5, 'type': 'term', 'i': 50, 'benefit': 62443585}, 'invalid']]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(args), 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 fixtureActualExpectedOutcome
limited pay term12363171236317Passed
limited pay endowment1307874613078746Passed
full pay endowment27004022700402Passed
full pay term15174561517456Passed
single premium1915524619155246Passed
pay period exceeds terminvalidinvalidPassed
unknown plan typeinvalid typeinvalid typePassed
term too long for tableinvalidinvalidPassed

SHA-256 / 0d64f6383f387abbefc1e2298ce7be85ea21fe43c4684d563834fa7bd0cff405

Verification & scope

A deterministic bounded teaching model of a stipulated toy actuarial contract. Rates are small synthetic tables, exact rationals are used where practical and floats are rounded at the output; it makes no claim of conformance with any published table, standard of practice or regulation. 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:47:15.038722+00:00.

Case digest / a491cdfa86b30371edc49f56037b1601b82bda3caed941fb5602b20f8dc8bc23