FA-68381 / Toll and parking fee computation / Open access
Tiered parking rate table: additional blocks are counted from time zero · case 01
Tiered parking rate table returns a wrong result when additional blocks are counted from time zero.
ROOT CAUSE
Only completed blocks beyond the last tier are charged.
VERIFIED REPAIR
Restore the additional block count rule so that the step reads `-(-(m - last_upto) // blk)`.
Unsuccessful approach: Counting blocks on the absolute clock mis-aligns blocks when the last tier is not a multiple of the block length.
Case contract
Input {minutes, tiers: [[upto minutes, cumulative price]] in any order, extra_per: [block minutes, cents], max}. A stay of 0 minutes is free. Tiers are applied in ascending upto order and a stay of exactly upto minutes belongs to that tier (price capped at max). Beyond the last tier each started block after its upto adds the block price; the whole fee is capped at max.
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):
m = x['minutes']
tiers = sorted(x['tiers'])
if m <= 0:
return 0
for upto, price in tiers:
if m <= upto:
return min(price, x['max'])
last_upto, last_price = tiers[-1]
blk, add = x['extra_per']
extra = (m - last_upto) // blk
return min(last_price + extra * add, x['max'])
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'minutes': 0, 'tiers': [[60, 300]], 'extra_per': [30, 100], 'max': 1500}, 0), ({'minutes': 675, 'tiers': [[60, 300], [120, 1200], [240, 1350]], 'extra_per': [60, 50], 'max': 4000}, 1750), ({'minutes': 301, 'tiers': [[300, 200]], 'extra_per': [15, 50], 'max': 4000}, 250), ({'minutes': 391, 'tiers': [[60, 200], [120, 750], [270, 950]], 'extra_per': [20, 150], 'max': 2500}, 2000), ({'minutes': 38, 'tiers': [[210, 100], [270, 500]], 'extra_per': [15, 100], 'max': 4000}, 100), ({'minutes': 435, 'tiers': [[30, 800], [150, 1800], [60, 850], [90, 1650]], 'extra_per': [20, 50], 'max': 4000}, 2550), ({'minutes': 60, 'tiers': [[60, 300], [120, 500], [240, 800]], 'extra_per': [60, 200], 'max': 2000}, 300), ({'minutes': 250, 'tiers': [[240, 800], [60, 300], [120, 500]], 'extra_per': [60, 200], 'max': 2000}, 1000)], [({'minutes': 31, 'tiers': [[30, 500], [210, 1450], [360, 1950]], 'extra_per': [30, 150], 'max': 2500}, 1450), ({'minutes': 250, 'tiers': [[240, 800], [60, 300], [120, 500]], 'extra_per': [60, 200], 'max': 2000}, 1000), ({'minutes': 271, 'tiers': [[180, 700], [210, 1600], [270, 1950]], 'extra_per': [20, 150], 'max': 2500}, 2100), ({'minutes': 222, 'tiers': [[180, 2000], [120, 300]], 'extra_per': [60, 100], 'max': 2500}, 2100), ({'minutes': 1000, 'tiers': [[90, 400], [180, 700]], 'extra_per': [45, 150], 'max': 2500}, 2500), ({'minutes': 60, 'tiers': [[60, 300], [120, 500], [240, 800]], 'extra_per': [60, 200], 'max': 2000}, 300), ({'minutes': 618, 'tiers': [[330, 950], [270, 500], [360, 1000]], 'extra_per': [60, 100], 'max': 1500}, 1500), ({'minutes': 643, 'tiers': [[330, 650], [120, 350], [240, 400]], 'extra_per': [60, 50], 'max': 2500}, 950)], [({'minutes': 1, 'tiers': [[30, 150], [60, 300]], 'extra_per': [30, 100], 'max': 1500}, 150), ({'minutes': 211, 'tiers': [[210, 1300]], 'extra_per': [60, 100], 'max': 2500}, 1400), ({'minutes': 61, 'tiers': [[30, 400], [60, 1250]], 'extra_per': [30, 150], 'max': 1500}, 1400), ({'minutes': 175, 'tiers': [[30, 250]], 'extra_per': [60, 50], 'max': 4000}, 400), ({'minutes': 61, 'tiers': [[60, 350], [210, 2000], [150, 1950]], 'extra_per': [20, 150], 'max': 4000}, 1950), ({'minutes': 468, 'tiers': [[30, 750], [90, 1050], [240, 1150]], 'extra_per': [15, 50], 'max': 2500}, 1950), ({'minutes': 0, 'tiers': [[60, 300]], 'extra_per': [30, 100], 'max': 1500}, 0), ({'minutes': 250, 'tiers': [[240, 800], [60, 300], [120, 500]], 'extra_per': [60, 200], 'max': 2000}, 1000)], [({'minutes': 0, 'tiers': [[60, 300]], 'extra_per': [30, 100], 'max': 1500}, 0), ({'minutes': 348, 'tiers': [[150, 1400]], 'extra_per': [60, 50], 'max': 4000}, 1600), ({'minutes': 198, 'tiers': [[90, 450], [180, 600], [300, 1250]], 'extra_per': [30, 50], 'max': 2500}, 1250), ({'minutes': 1, 'tiers': [[30, 150], [60, 300]], 'extra_per': [30, 100], 'max': 1500}, 150), ({'minutes': 113, 'tiers': [[30, 900], [90, 1750]], 'extra_per': [30, 100], 'max': 4000}, 1850), ({'minutes': 271, 'tiers': [[270, 1150]], 'extra_per': [60, 150], 'max': 2500}, 1300), ({'minutes': 250, 'tiers': [[240, 800], [60, 300], [120, 500]], 'extra_per': [60, 200], 'max': 2000}, 1000), ({'minutes': 191, 'tiers': [[360, 1700], [330, 1100], [210, 1000]], 'extra_per': [60, 50], 'max': 4000}, 1000)], [({'minutes': 181, 'tiers': [[90, 1150], [180, 1200]], 'extra_per': [60, 50], 'max': 1500}, 1250), ({'minutes': 1, 'tiers': [[30, 150], [60, 300]], 'extra_per': [30, 100], 'max': 1500}, 150), ({'minutes': 60, 'tiers': [[60, 300], [120, 500], [240, 800]], 'extra_per': [60, 200], 'max': 2000}, 300), ({'minutes': 361, 'tiers': [[30, 250], [90, 300], [360, 1650]], 'extra_per': [30, 50], 'max': 4000}, 1700), ({'minutes': 271, 'tiers': [[60, 450], [270, 1600]], 'extra_per': [60, 150], 'max': 2500}, 1750), ({'minutes': 0, 'tiers': [[60, 300]], 'extra_per': [30, 100], 'max': 1500}, 0), ({'minutes': 394, 'tiers': [[30, 100], [150, 1600]], 'extra_per': [60, 100], 'max': 4000}, 2100), ({'minutes': 375, 'tiers': [[30, 350], [300, 2000], [60, 850], [210, 1350]], 'extra_per': [20, 150], 'max': 4000}, 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 | 0 | 0 | Passed |
| fee oracle 1 | 1700 | 1750 | Failed |
| fee oracle 2 | 200 | 250 | Failed |
| fee oracle 3 | 1850 | 2000 | Failed |
| fee oracle 4 | 100 | 100 | Passed |
| fee oracle 5 | 2500 | 2550 | Failed |
| fee oracle 6 | 300 | 300 | Passed |
| fee oracle 7 | 800 | 1000 | Failed |
SHA-256 / c47f9438d5b7230730c32b203b587aaccad606c5af11dc145316477a34812026
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
m = x['minutes']
tiers = sorted(x['tiers'])
if m <= 0:
return 0
for upto, price in tiers:
if m <= upto:
return min(price, x['max'])
last_upto, last_price = tiers[-1]
blk, add = x['extra_per']
extra = -(-m // blk) - -(-last_upto // blk)
return min(last_price + extra * add, x['max'])
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'minutes': 0, 'tiers': [[60, 300]], 'extra_per': [30, 100], 'max': 1500}, 0), ({'minutes': 675, 'tiers': [[60, 300], [120, 1200], [240, 1350]], 'extra_per': [60, 50], 'max': 4000}, 1750), ({'minutes': 301, 'tiers': [[300, 200]], 'extra_per': [15, 50], 'max': 4000}, 250), ({'minutes': 391, 'tiers': [[60, 200], [120, 750], [270, 950]], 'extra_per': [20, 150], 'max': 2500}, 2000), ({'minutes': 38, 'tiers': [[210, 100], [270, 500]], 'extra_per': [15, 100], 'max': 4000}, 100), ({'minutes': 435, 'tiers': [[30, 800], [150, 1800], [60, 850], [90, 1650]], 'extra_per': [20, 50], 'max': 4000}, 2550), ({'minutes': 60, 'tiers': [[60, 300], [120, 500], [240, 800]], 'extra_per': [60, 200], 'max': 2000}, 300), ({'minutes': 250, 'tiers': [[240, 800], [60, 300], [120, 500]], 'extra_per': [60, 200], 'max': 2000}, 1000)], [({'minutes': 31, 'tiers': [[30, 500], [210, 1450], [360, 1950]], 'extra_per': [30, 150], 'max': 2500}, 1450), ({'minutes': 250, 'tiers': [[240, 800], [60, 300], [120, 500]], 'extra_per': [60, 200], 'max': 2000}, 1000), ({'minutes': 271, 'tiers': [[180, 700], [210, 1600], [270, 1950]], 'extra_per': [20, 150], 'max': 2500}, 2100), ({'minutes': 222, 'tiers': [[180, 2000], [120, 300]], 'extra_per': [60, 100], 'max': 2500}, 2100), ({'minutes': 1000, 'tiers': [[90, 400], [180, 700]], 'extra_per': [45, 150], 'max': 2500}, 2500), ({'minutes': 60, 'tiers': [[60, 300], [120, 500], [240, 800]], 'extra_per': [60, 200], 'max': 2000}, 300), ({'minutes': 618, 'tiers': [[330, 950], [270, 500], [360, 1000]], 'extra_per': [60, 100], 'max': 1500}, 1500), ({'minutes': 643, 'tiers': [[330, 650], [120, 350], [240, 400]], 'extra_per': [60, 50], 'max': 2500}, 950)], [({'minutes': 1, 'tiers': [[30, 150], [60, 300]], 'extra_per': [30, 100], 'max': 1500}, 150), ({'minutes': 211, 'tiers': [[210, 1300]], 'extra_per': [60, 100], 'max': 2500}, 1400), ({'minutes': 61, 'tiers': [[30, 400], [60, 1250]], 'extra_per': [30, 150], 'max': 1500}, 1400), ({'minutes': 175, 'tiers': [[30, 250]], 'extra_per': [60, 50], 'max': 4000}, 400), ({'minutes': 61, 'tiers': [[60, 350], [210, 2000], [150, 1950]], 'extra_per': [20, 150], 'max': 4000}, 1950), ({'minutes': 468, 'tiers': [[30, 750], [90, 1050], [240, 1150]], 'extra_per': [15, 50], 'max': 2500}, 1950), ({'minutes': 0, 'tiers': [[60, 300]], 'extra_per': [30, 100], 'max': 1500}, 0), ({'minutes': 250, 'tiers': [[240, 800], [60, 300], [120, 500]], 'extra_per': [60, 200], 'max': 2000}, 1000)], [({'minutes': 0, 'tiers': [[60, 300]], 'extra_per': [30, 100], 'max': 1500}, 0), ({'minutes': 348, 'tiers': [[150, 1400]], 'extra_per': [60, 50], 'max': 4000}, 1600), ({'minutes': 198, 'tiers': [[90, 450], [180, 600], [300, 1250]], 'extra_per': [30, 50], 'max': 2500}, 1250), ({'minutes': 1, 'tiers': [[30, 150], [60, 300]], 'extra_per': [30, 100], 'max': 1500}, 150), ({'minutes': 113, 'tiers': [[30, 900], [90, 1750]], 'extra_per': [30, 100], 'max': 4000}, 1850), ({'minutes': 271, 'tiers': [[270, 1150]], 'extra_per': [60, 150], 'max': 2500}, 1300), ({'minutes': 250, 'tiers': [[240, 800], [60, 300], [120, 500]], 'extra_per': [60, 200], 'max': 2000}, 1000), ({'minutes': 191, 'tiers': [[360, 1700], [330, 1100], [210, 1000]], 'extra_per': [60, 50], 'max': 4000}, 1000)], [({'minutes': 181, 'tiers': [[90, 1150], [180, 1200]], 'extra_per': [60, 50], 'max': 1500}, 1250), ({'minutes': 1, 'tiers': [[30, 150], [60, 300]], 'extra_per': [30, 100], 'max': 1500}, 150), ({'minutes': 60, 'tiers': [[60, 300], [120, 500], [240, 800]], 'extra_per': [60, 200], 'max': 2000}, 300), ({'minutes': 361, 'tiers': [[30, 250], [90, 300], [360, 1650]], 'extra_per': [30, 50], 'max': 4000}, 1700), ({'minutes': 271, 'tiers': [[60, 450], [270, 1600]], 'extra_per': [60, 150], 'max': 2500}, 1750), ({'minutes': 0, 'tiers': [[60, 300]], 'extra_per': [30, 100], 'max': 1500}, 0), ({'minutes': 394, 'tiers': [[30, 100], [150, 1600]], 'extra_per': [60, 100], 'max': 4000}, 2100), ({'minutes': 375, 'tiers': [[30, 350], [300, 2000], [60, 850], [210, 1350]], 'extra_per': [20, 150], 'max': 4000}, 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 | 0 | 0 | Passed |
| fee oracle 1 | 1750 | 1750 | Passed |
| fee oracle 2 | 250 | 250 | Passed |
| fee oracle 3 | 1850 | 2000 | Failed |
| fee oracle 4 | 100 | 100 | Passed |
| fee oracle 5 | 2500 | 2550 | Failed |
| fee oracle 6 | 300 | 300 | Passed |
| fee oracle 7 | 1000 | 1000 | Passed |
SHA-256 / 00545a2d013ab9c733039a979be0f9b3ee43a59a4d4ca74a068cb1d9e12c5366
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
m = x['minutes']
tiers = sorted(x['tiers'])
if m <= 0:
return 0
for upto, price in tiers:
if m <= upto:
return min(price, x['max'])
last_upto, last_price = tiers[-1]
blk, add = x['extra_per']
extra = -(-(m - last_upto) // blk)
return min(last_price + extra * add, x['max'])
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'minutes': 0, 'tiers': [[60, 300]], 'extra_per': [30, 100], 'max': 1500}, 0), ({'minutes': 675, 'tiers': [[60, 300], [120, 1200], [240, 1350]], 'extra_per': [60, 50], 'max': 4000}, 1750), ({'minutes': 301, 'tiers': [[300, 200]], 'extra_per': [15, 50], 'max': 4000}, 250), ({'minutes': 391, 'tiers': [[60, 200], [120, 750], [270, 950]], 'extra_per': [20, 150], 'max': 2500}, 2000), ({'minutes': 38, 'tiers': [[210, 100], [270, 500]], 'extra_per': [15, 100], 'max': 4000}, 100), ({'minutes': 435, 'tiers': [[30, 800], [150, 1800], [60, 850], [90, 1650]], 'extra_per': [20, 50], 'max': 4000}, 2550), ({'minutes': 60, 'tiers': [[60, 300], [120, 500], [240, 800]], 'extra_per': [60, 200], 'max': 2000}, 300), ({'minutes': 250, 'tiers': [[240, 800], [60, 300], [120, 500]], 'extra_per': [60, 200], 'max': 2000}, 1000)], [({'minutes': 31, 'tiers': [[30, 500], [210, 1450], [360, 1950]], 'extra_per': [30, 150], 'max': 2500}, 1450), ({'minutes': 250, 'tiers': [[240, 800], [60, 300], [120, 500]], 'extra_per': [60, 200], 'max': 2000}, 1000), ({'minutes': 271, 'tiers': [[180, 700], [210, 1600], [270, 1950]], 'extra_per': [20, 150], 'max': 2500}, 2100), ({'minutes': 222, 'tiers': [[180, 2000], [120, 300]], 'extra_per': [60, 100], 'max': 2500}, 2100), ({'minutes': 1000, 'tiers': [[90, 400], [180, 700]], 'extra_per': [45, 150], 'max': 2500}, 2500), ({'minutes': 60, 'tiers': [[60, 300], [120, 500], [240, 800]], 'extra_per': [60, 200], 'max': 2000}, 300), ({'minutes': 618, 'tiers': [[330, 950], [270, 500], [360, 1000]], 'extra_per': [60, 100], 'max': 1500}, 1500), ({'minutes': 643, 'tiers': [[330, 650], [120, 350], [240, 400]], 'extra_per': [60, 50], 'max': 2500}, 950)], [({'minutes': 1, 'tiers': [[30, 150], [60, 300]], 'extra_per': [30, 100], 'max': 1500}, 150), ({'minutes': 211, 'tiers': [[210, 1300]], 'extra_per': [60, 100], 'max': 2500}, 1400), ({'minutes': 61, 'tiers': [[30, 400], [60, 1250]], 'extra_per': [30, 150], 'max': 1500}, 1400), ({'minutes': 175, 'tiers': [[30, 250]], 'extra_per': [60, 50], 'max': 4000}, 400), ({'minutes': 61, 'tiers': [[60, 350], [210, 2000], [150, 1950]], 'extra_per': [20, 150], 'max': 4000}, 1950), ({'minutes': 468, 'tiers': [[30, 750], [90, 1050], [240, 1150]], 'extra_per': [15, 50], 'max': 2500}, 1950), ({'minutes': 0, 'tiers': [[60, 300]], 'extra_per': [30, 100], 'max': 1500}, 0), ({'minutes': 250, 'tiers': [[240, 800], [60, 300], [120, 500]], 'extra_per': [60, 200], 'max': 2000}, 1000)], [({'minutes': 0, 'tiers': [[60, 300]], 'extra_per': [30, 100], 'max': 1500}, 0), ({'minutes': 348, 'tiers': [[150, 1400]], 'extra_per': [60, 50], 'max': 4000}, 1600), ({'minutes': 198, 'tiers': [[90, 450], [180, 600], [300, 1250]], 'extra_per': [30, 50], 'max': 2500}, 1250), ({'minutes': 1, 'tiers': [[30, 150], [60, 300]], 'extra_per': [30, 100], 'max': 1500}, 150), ({'minutes': 113, 'tiers': [[30, 900], [90, 1750]], 'extra_per': [30, 100], 'max': 4000}, 1850), ({'minutes': 271, 'tiers': [[270, 1150]], 'extra_per': [60, 150], 'max': 2500}, 1300), ({'minutes': 250, 'tiers': [[240, 800], [60, 300], [120, 500]], 'extra_per': [60, 200], 'max': 2000}, 1000), ({'minutes': 191, 'tiers': [[360, 1700], [330, 1100], [210, 1000]], 'extra_per': [60, 50], 'max': 4000}, 1000)], [({'minutes': 181, 'tiers': [[90, 1150], [180, 1200]], 'extra_per': [60, 50], 'max': 1500}, 1250), ({'minutes': 1, 'tiers': [[30, 150], [60, 300]], 'extra_per': [30, 100], 'max': 1500}, 150), ({'minutes': 60, 'tiers': [[60, 300], [120, 500], [240, 800]], 'extra_per': [60, 200], 'max': 2000}, 300), ({'minutes': 361, 'tiers': [[30, 250], [90, 300], [360, 1650]], 'extra_per': [30, 50], 'max': 4000}, 1700), ({'minutes': 271, 'tiers': [[60, 450], [270, 1600]], 'extra_per': [60, 150], 'max': 2500}, 1750), ({'minutes': 0, 'tiers': [[60, 300]], 'extra_per': [30, 100], 'max': 1500}, 0), ({'minutes': 394, 'tiers': [[30, 100], [150, 1600]], 'extra_per': [60, 100], 'max': 4000}, 2100), ({'minutes': 375, 'tiers': [[30, 350], [300, 2000], [60, 850], [210, 1350]], 'extra_per': [20, 150], 'max': 4000}, 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 | 0 | 0 | Passed |
| fee oracle 1 | 1750 | 1750 | Passed |
| fee oracle 2 | 250 | 250 | Passed |
| fee oracle 3 | 2000 | 2000 | Passed |
| fee oracle 4 | 100 | 100 | Passed |
| fee oracle 5 | 2550 | 2550 | Passed |
| fee oracle 6 | 300 | 300 | Passed |
| fee oracle 7 | 1000 | 1000 | Passed |
SHA-256 / 2b4c247813599d61bfa0f9ef13781a6660d0dc5d6eee468a008ba15b0271aefa
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.676294+00:00.
Case digest / 14e12cf9082c519bcf466e618bea3781281d6bd7cd6bb94e056978f3a4a3ae12