FA-63496 / Actuarial life tables / Open access
Net level annual premium: Premiums are valued as payable in arrears · case 01
Net premiums are too high because premiums are discounted an extra year.
ROOT CAUSE
The premium annuity uses v^(k+1).
VERIFIED REPAIR
Premiums are due at the start of each year.
Unsuccessful approach: Dropping survival values premiums as certain payments.
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>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+1)*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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| limited pay term | 1298133 | 1236317 | Failed |
| limited pay endowment | 13732683 | 13078746 | Failed |
| full pay endowment | 2781414 | 2700402 | Failed |
| full pay term | 1593329 | 1517456 | Failed |
| single premium | 19921456 | 19155246 | Failed |
| pay period exceeds term | invalid | invalid | Passed |
| unknown plan type | invalid type | invalid type | Passed |
| term too long for table | invalid | invalid | Passed |
SHA-256 / abca6490cc2f62750eb349621a34924d27eee085148feb0672487a15d1c3aaa1
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>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
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| limited pay term | 1193822 | 1236317 | Failed |
| limited pay endowment | 12968553 | 13078746 | Failed |
| full pay endowment | 2597953 | 2700402 | Failed |
| full pay term | 1418215 | 1517456 | Failed |
| single premium | 19155246 | 19155246 | Passed |
| pay period exceeds term | invalid | invalid | Passed |
| unknown plan type | invalid type | invalid type | Passed |
| term too long for table | invalid | invalid | Passed |
SHA-256 / 31dc4edd7c51dda8d1390427b9e0f8281ea0e78dd9e73c9551d270f076530503
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| limited pay term | 1236317 | 1236317 | Passed |
| limited pay endowment | 13078746 | 13078746 | Passed |
| full pay endowment | 2700402 | 2700402 | Passed |
| full pay term | 1517456 | 1517456 | Passed |
| single premium | 19155246 | 19155246 | Passed |
| pay period exceeds term | invalid | invalid | Passed |
| unknown plan type | invalid type | invalid type | Passed |
| term too long for table | invalid | invalid | Passed |
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.034376+00:00.
Case digest / 8a9f0eca3903e31483ed9fae052b1ecfaf4a361efb6fdcdbc480b97be3c684ae