FA-68356 / Toll and parking fee computation / Open access
Garage hourly fee with grace and daily maximum: full day blocks are billed at 24 hourly charges · case 01
Garage hourly fee with grace and daily maximum returns a wrong result when full day blocks are billed at 24 hourly charges.
ROOT CAUSE
Each complete day is billed as 24 hours instead of the daily maximum.
VERIFIED REPAIR
Restore the full day blocks rule so that the step reads `days * x['daily_max']`.
Unsuccessful approach: Skipping the first full day undercharges every multi-day stay.
Case contract
Input {entry, exit (absolute minutes), grace, hourly, daily_max, lost_ticket, lost_fee}; cents. Exit before entry is 'invalid'. A stay no longer than grace is free (grace is not deducted from longer stays). Otherwise each full 1440-minute block costs daily_max and the remainder costs hourly per started hour, capped at daily_max. A lost ticket pays the greater of the computed fee and lost_fee.
Why this case matters
Fee engines bill customers in integer cents; a wrong boundary, rounding stage or cap scope silently over- or under-charges.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
if x['exit'] < x['entry']:
return 'invalid'
dur = x['exit'] - x['entry']
if dur <= x['grace']:
fee = 0
else:
days, rem = divmod(dur, 1440)
fee = days * 24 * x['hourly'] + min(x['daily_max'], -(-rem // 60) * x['hourly'])
if x['lost_ticket']:
fee = max(fee, x['lost_fee'])
return fee
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'entry': 2887, 'exit': 5767, 'grace': 10, 'hourly': 300, 'daily_max': 1500, 'lost_ticket': False, 'lost_fee': 2500}, 3000), ({'entry': 1112, 'exit': 1101, 'grace': 0, 'hourly': 200, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 2500}, 'invalid'), ({'entry': 558, 'exit': 4878, 'grace': 10, 'hourly': 450, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 6000), ({'entry': 2883, 'exit': 2887, 'grace': 15, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 0), ({'entry': 0, 'exit': 1560, 'grace': 10, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 2600), ({'entry': 60, 'exit': 240, 'grace': 15, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 1350), ({'entry': 100, 'exit': 115, 'grace': 15, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 0), ({'entry': 1964, 'exit': 3429, 'grace': 15, 'hourly': 300, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 2700)], [({'entry': 633, 'exit': 4953, 'grace': 10, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 2500}, 7200), ({'entry': 2832, 'exit': 4032, 'grace': 10, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 2400), ({'entry': 0, 'exit': 1560, 'grace': 10, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 2600), ({'entry': 500, 'exit': 500, 'grace': 0, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': True, 'lost_fee': 2500}, 2500), ({'entry': 491, 'exit': 518, 'grace': 15, 'hourly': 300, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 300), ({'entry': 2071, 'exit': 3511, 'grace': 15, 'hourly': 200, 'daily_max': 2400, 'lost_ticket': True, 'lost_fee': 2500}, 2500), ({'entry': 60, 'exit': 240, 'grace': 15, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 1350), ({'entry': 1163, 'exit': 5200, 'grace': 0, 'hourly': 200, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 7200)], [({'entry': 333, 'exit': 633, 'grace': 10, 'hourly': 450, 'daily_max': 1500, 'lost_ticket': False, 'lost_fee': 2500}, 1500), ({'entry': 0, 'exit': 1560, 'grace': 10, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 2600), ({'entry': 2127, 'exit': 2128, 'grace': 10, 'hourly': 300, 'daily_max': 2400, 'lost_ticket': True, 'lost_fee': 2500}, 2500), ({'entry': 140, 'exit': 1640, 'grace': 0, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 3000}, 2300), ({'entry': 500, 'exit': 500, 'grace': 0, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': True, 'lost_fee': 2500}, 2500), ({'entry': 60, 'exit': 240, 'grace': 15, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 1350), ({'entry': 703, 'exit': 3465, 'grace': 15, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': True, 'lost_fee': 3000}, 4800), ({'entry': 2181, 'exit': 6501, 'grace': 15, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 3000}, 6000)], [({'entry': 1596, 'exit': 5916, 'grace': 10, 'hourly': 200, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 6000), ({'entry': 162, 'exit': 942, 'grace': 0, 'hourly': 450, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 3000}, 2000), ({'entry': 0, 'exit': 1560, 'grace': 10, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 2600), ({'entry': 2284, 'exit': 5992, 'grace': 15, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 7200), ({'entry': 60, 'exit': 240, 'grace': 15, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 1350), ({'entry': 500, 'exit': 500, 'grace': 0, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': True, 'lost_fee': 2500}, 2500), ({'entry': 1031, 'exit': 2171, 'grace': 20, 'hourly': 200, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 2500}, 2400), ({'entry': 371, 'exit': 905, 'grace': 15, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 2400)], [({'entry': 500, 'exit': 500, 'grace': 0, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': True, 'lost_fee': 2500}, 2500), ({'entry': 2834, 'exit': 2808, 'grace': 0, 'hourly': 300, 'daily_max': 2400, 'lost_ticket': True, 'lost_fee': 3000}, 'invalid'), ({'entry': 228, 'exit': 211, 'grace': 20, 'hourly': 200, 'daily_max': 1500, 'lost_ticket': False, 'lost_fee': 2500}, 'invalid'), ({'entry': 60, 'exit': 240, 'grace': 15, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 1350), ({'entry': 728, 'exit': 3608, 'grace': 20, 'hourly': 300, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 2500}, 4800), ({'entry': 2865, 'exit': 2837, 'grace': 15, 'hourly': 300, 'daily_max': 1500, 'lost_ticket': False, 'lost_fee': 3000}, 'invalid'), ({'entry': 1658, 'exit': 4538, 'grace': 20, 'hourly': 200, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 4000), ({'entry': 0, 'exit': 1560, 'grace': 10, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 2600)]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check('fee oracle' + ' %d' % i, 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 |
|---|---|---|---|
| fee oracle 0 | 14400 | 3000 | Failed |
| fee oracle 1 | invalid | invalid | Passed |
| fee oracle 2 | 32400 | 6000 | Failed |
| fee oracle 3 | 0 | 0 | Passed |
| fee oracle 4 | 7800 | 2600 | Failed |
| fee oracle 5 | 1350 | 1350 | Passed |
| fee oracle 6 | 0 | 0 | Passed |
| fee oracle 7 | 7500 | 2700 | Failed |
SHA-256 / 622f43f64469737c29c7d4ae6fe188fdc586b28ca09ab1cc0058892b3076683c
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
if x['exit'] < x['entry']:
return 'invalid'
dur = x['exit'] - x['entry']
if dur <= x['grace']:
fee = 0
else:
days, rem = divmod(dur, 1440)
fee = max(0, days - 1) * x['daily_max'] + min(x['daily_max'], -(-rem // 60) * x['hourly'])
if x['lost_ticket']:
fee = max(fee, x['lost_fee'])
return fee
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'entry': 2887, 'exit': 5767, 'grace': 10, 'hourly': 300, 'daily_max': 1500, 'lost_ticket': False, 'lost_fee': 2500}, 3000), ({'entry': 1112, 'exit': 1101, 'grace': 0, 'hourly': 200, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 2500}, 'invalid'), ({'entry': 558, 'exit': 4878, 'grace': 10, 'hourly': 450, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 6000), ({'entry': 2883, 'exit': 2887, 'grace': 15, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 0), ({'entry': 0, 'exit': 1560, 'grace': 10, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 2600), ({'entry': 60, 'exit': 240, 'grace': 15, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 1350), ({'entry': 100, 'exit': 115, 'grace': 15, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 0), ({'entry': 1964, 'exit': 3429, 'grace': 15, 'hourly': 300, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 2700)], [({'entry': 633, 'exit': 4953, 'grace': 10, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 2500}, 7200), ({'entry': 2832, 'exit': 4032, 'grace': 10, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 2400), ({'entry': 0, 'exit': 1560, 'grace': 10, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 2600), ({'entry': 500, 'exit': 500, 'grace': 0, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': True, 'lost_fee': 2500}, 2500), ({'entry': 491, 'exit': 518, 'grace': 15, 'hourly': 300, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 300), ({'entry': 2071, 'exit': 3511, 'grace': 15, 'hourly': 200, 'daily_max': 2400, 'lost_ticket': True, 'lost_fee': 2500}, 2500), ({'entry': 60, 'exit': 240, 'grace': 15, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 1350), ({'entry': 1163, 'exit': 5200, 'grace': 0, 'hourly': 200, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 7200)], [({'entry': 333, 'exit': 633, 'grace': 10, 'hourly': 450, 'daily_max': 1500, 'lost_ticket': False, 'lost_fee': 2500}, 1500), ({'entry': 0, 'exit': 1560, 'grace': 10, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 2600), ({'entry': 2127, 'exit': 2128, 'grace': 10, 'hourly': 300, 'daily_max': 2400, 'lost_ticket': True, 'lost_fee': 2500}, 2500), ({'entry': 140, 'exit': 1640, 'grace': 0, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 3000}, 2300), ({'entry': 500, 'exit': 500, 'grace': 0, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': True, 'lost_fee': 2500}, 2500), ({'entry': 60, 'exit': 240, 'grace': 15, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 1350), ({'entry': 703, 'exit': 3465, 'grace': 15, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': True, 'lost_fee': 3000}, 4800), ({'entry': 2181, 'exit': 6501, 'grace': 15, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 3000}, 6000)], [({'entry': 1596, 'exit': 5916, 'grace': 10, 'hourly': 200, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 6000), ({'entry': 162, 'exit': 942, 'grace': 0, 'hourly': 450, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 3000}, 2000), ({'entry': 0, 'exit': 1560, 'grace': 10, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 2600), ({'entry': 2284, 'exit': 5992, 'grace': 15, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 7200), ({'entry': 60, 'exit': 240, 'grace': 15, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 1350), ({'entry': 500, 'exit': 500, 'grace': 0, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': True, 'lost_fee': 2500}, 2500), ({'entry': 1031, 'exit': 2171, 'grace': 20, 'hourly': 200, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 2500}, 2400), ({'entry': 371, 'exit': 905, 'grace': 15, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 2400)], [({'entry': 500, 'exit': 500, 'grace': 0, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': True, 'lost_fee': 2500}, 2500), ({'entry': 2834, 'exit': 2808, 'grace': 0, 'hourly': 300, 'daily_max': 2400, 'lost_ticket': True, 'lost_fee': 3000}, 'invalid'), ({'entry': 228, 'exit': 211, 'grace': 20, 'hourly': 200, 'daily_max': 1500, 'lost_ticket': False, 'lost_fee': 2500}, 'invalid'), ({'entry': 60, 'exit': 240, 'grace': 15, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 1350), ({'entry': 728, 'exit': 3608, 'grace': 20, 'hourly': 300, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 2500}, 4800), ({'entry': 2865, 'exit': 2837, 'grace': 15, 'hourly': 300, 'daily_max': 1500, 'lost_ticket': False, 'lost_fee': 3000}, 'invalid'), ({'entry': 1658, 'exit': 4538, 'grace': 20, 'hourly': 200, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 4000), ({'entry': 0, 'exit': 1560, 'grace': 10, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 2600)]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check('fee oracle' + ' %d' % i, 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 |
|---|---|---|---|
| fee oracle 0 | 1500 | 3000 | Failed |
| fee oracle 1 | invalid | invalid | Passed |
| fee oracle 2 | 4000 | 6000 | Failed |
| fee oracle 3 | 0 | 0 | Passed |
| fee oracle 4 | 600 | 2600 | Failed |
| fee oracle 5 | 1350 | 1350 | Passed |
| fee oracle 6 | 0 | 0 | Passed |
| fee oracle 7 | 300 | 2700 | Failed |
SHA-256 / ab184112dd3e124bc9945e0f29b6bb23e6bfd9cec371a1f5ef687c4efa35e13c
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
if x['exit'] < x['entry']:
return 'invalid'
dur = x['exit'] - x['entry']
if dur <= x['grace']:
fee = 0
else:
days, rem = divmod(dur, 1440)
fee = days * x['daily_max'] + min(x['daily_max'], -(-rem // 60) * x['hourly'])
if x['lost_ticket']:
fee = max(fee, x['lost_fee'])
return fee
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'entry': 2887, 'exit': 5767, 'grace': 10, 'hourly': 300, 'daily_max': 1500, 'lost_ticket': False, 'lost_fee': 2500}, 3000), ({'entry': 1112, 'exit': 1101, 'grace': 0, 'hourly': 200, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 2500}, 'invalid'), ({'entry': 558, 'exit': 4878, 'grace': 10, 'hourly': 450, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 6000), ({'entry': 2883, 'exit': 2887, 'grace': 15, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 0), ({'entry': 0, 'exit': 1560, 'grace': 10, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 2600), ({'entry': 60, 'exit': 240, 'grace': 15, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 1350), ({'entry': 100, 'exit': 115, 'grace': 15, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 0), ({'entry': 1964, 'exit': 3429, 'grace': 15, 'hourly': 300, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 2700)], [({'entry': 633, 'exit': 4953, 'grace': 10, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 2500}, 7200), ({'entry': 2832, 'exit': 4032, 'grace': 10, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 2400), ({'entry': 0, 'exit': 1560, 'grace': 10, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 2600), ({'entry': 500, 'exit': 500, 'grace': 0, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': True, 'lost_fee': 2500}, 2500), ({'entry': 491, 'exit': 518, 'grace': 15, 'hourly': 300, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 300), ({'entry': 2071, 'exit': 3511, 'grace': 15, 'hourly': 200, 'daily_max': 2400, 'lost_ticket': True, 'lost_fee': 2500}, 2500), ({'entry': 60, 'exit': 240, 'grace': 15, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 1350), ({'entry': 1163, 'exit': 5200, 'grace': 0, 'hourly': 200, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 7200)], [({'entry': 333, 'exit': 633, 'grace': 10, 'hourly': 450, 'daily_max': 1500, 'lost_ticket': False, 'lost_fee': 2500}, 1500), ({'entry': 0, 'exit': 1560, 'grace': 10, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 2600), ({'entry': 2127, 'exit': 2128, 'grace': 10, 'hourly': 300, 'daily_max': 2400, 'lost_ticket': True, 'lost_fee': 2500}, 2500), ({'entry': 140, 'exit': 1640, 'grace': 0, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 3000}, 2300), ({'entry': 500, 'exit': 500, 'grace': 0, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': True, 'lost_fee': 2500}, 2500), ({'entry': 60, 'exit': 240, 'grace': 15, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 1350), ({'entry': 703, 'exit': 3465, 'grace': 15, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': True, 'lost_fee': 3000}, 4800), ({'entry': 2181, 'exit': 6501, 'grace': 15, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 3000}, 6000)], [({'entry': 1596, 'exit': 5916, 'grace': 10, 'hourly': 200, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 6000), ({'entry': 162, 'exit': 942, 'grace': 0, 'hourly': 450, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 3000}, 2000), ({'entry': 0, 'exit': 1560, 'grace': 10, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 2600), ({'entry': 2284, 'exit': 5992, 'grace': 15, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 7200), ({'entry': 60, 'exit': 240, 'grace': 15, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 1350), ({'entry': 500, 'exit': 500, 'grace': 0, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': True, 'lost_fee': 2500}, 2500), ({'entry': 1031, 'exit': 2171, 'grace': 20, 'hourly': 200, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 2500}, 2400), ({'entry': 371, 'exit': 905, 'grace': 15, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 2400)], [({'entry': 500, 'exit': 500, 'grace': 0, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': True, 'lost_fee': 2500}, 2500), ({'entry': 2834, 'exit': 2808, 'grace': 0, 'hourly': 300, 'daily_max': 2400, 'lost_ticket': True, 'lost_fee': 3000}, 'invalid'), ({'entry': 228, 'exit': 211, 'grace': 20, 'hourly': 200, 'daily_max': 1500, 'lost_ticket': False, 'lost_fee': 2500}, 'invalid'), ({'entry': 60, 'exit': 240, 'grace': 15, 'hourly': 450, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 3000}, 1350), ({'entry': 728, 'exit': 3608, 'grace': 20, 'hourly': 300, 'daily_max': 2400, 'lost_ticket': False, 'lost_fee': 2500}, 4800), ({'entry': 2865, 'exit': 2837, 'grace': 15, 'hourly': 300, 'daily_max': 1500, 'lost_ticket': False, 'lost_fee': 3000}, 'invalid'), ({'entry': 1658, 'exit': 4538, 'grace': 20, 'hourly': 200, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 4000), ({'entry': 0, 'exit': 1560, 'grace': 10, 'hourly': 300, 'daily_max': 2000, 'lost_ticket': False, 'lost_fee': 2500}, 2600)]]
for i, (args, expected) in enumerate(fixtures[N-1]):
check('fee oracle' + ' %d' % i, 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 |
|---|---|---|---|
| fee oracle 0 | 3000 | 3000 | Passed |
| fee oracle 1 | invalid | invalid | Passed |
| fee oracle 2 | 6000 | 6000 | Passed |
| fee oracle 3 | 0 | 0 | Passed |
| fee oracle 4 | 2600 | 2600 | Passed |
| fee oracle 5 | 1350 | 1350 | Passed |
| fee oracle 6 | 0 | 0 | Passed |
| fee oracle 7 | 2700 | 2700 | Passed |
SHA-256 / d0830e1f4dd1011e407fb18fce09e8257bf67ccfe589e4153a58d7078d236a11
Verification & scope
A deterministic, bounded toy model with a stipulated contract; it makes no claim of conformance to any agency manual or 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.
Observations recorded using Python 3.12.14 at 2026-09-29T14:48:01.501053+00:00.
Case digest / b12951cd95b5ba06b7056c0d72fb0742b7c8e96e91c37dd6a1ee75da45564fd4