FA-68416 / Toll and parking fee computation / Open access
Early bird flat rate: the early bird is compared with the uncapped hourly fee · case 01
Early bird flat rate returns a wrong result when the early bird is compared with the uncapped hourly fee.
ROOT CAUSE
Qualifying customers are charged the flat rate even when the regular fee is lower.
VERIFIED REPAIR
Restore the regular fee comparison rule so that the step reads `return min(regular, x['early'])`.
Unsuccessful approach: Comparing against the uncapped hourly fee ignores a daily maximum below the early bird price.
Case contract
Input {entry: [day, minute], exit: [day, minute], hourly, daily_max, early}; day % 7 == 0 is Monday. Regular fee = min(started hours*hourly, started 24h periods (at least 1)*daily_max). Early bird applies on weekdays when entry is 06:00-09:00 inclusive and exit is the same day 15:00-19:00 inclusive; the customer pays min(regular, early). Negative durations are 'invalid'.
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):
ed, em = x['entry']
xd, xm = x['exit']
dur = (xd - ed) * 1440 + xm - em
if dur < 0:
return 'invalid'
hours = -(-dur // 60)
days = max(1, -(-dur // 1440))
regular = min(hours * x['hourly'], days * x['daily_max'])
eligible = ed % 7 < 5 and 360 <= em <= 540 and xd == ed and 900 <= xm <= 1140
if eligible:
return x['early']
return regular
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'entry': [8, 360], 'exit': [8, 1140], 'hourly': 200, 'daily_max': 1200, 'early': 1000}, 1000), ({'entry': [8, 360], 'exit': [8, 900], 'hourly': 200, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [1, 541], 'exit': [2, 899], 'hourly': 400, 'daily_max': 2500, 'early': 1000}, 5000), ({'entry': [0, 480], 'exit': [0, 1300], 'hourly': 300, 'daily_max': 2500, 'early': 1000}, 2500), ({'entry': [1, 360], 'exit': [1, 1140], 'hourly': 400, 'daily_max': 1800, 'early': 1000}, 1000), ({'entry': [3, 420], 'exit': [4, 960], 'hourly': 300, 'daily_max': 1800, 'early': 900}, 3600), ({'entry': [3, 540], 'exit': [3, 1140], 'hourly': 400, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [0, 540], 'exit': [0, 1140], 'hourly': 200, 'daily_max': 1200, 'early': 1400}, 1200)], [({'entry': [11, 810], 'exit': [11, 913], 'hourly': 300, 'daily_max': 1800, 'early': 1400}, 600), ({'entry': [5, 400], 'exit': [5, 1000], 'hourly': 300, 'daily_max': 2500, 'early': 1000}, 2500), ({'entry': [1, 0], 'exit': [2, 0], 'hourly': 300, 'daily_max': 1800, 'early': 1000}, 1800), ({'entry': [11, 540], 'exit': [11, 1140], 'hourly': 400, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [2, 930], 'exit': [2, 1141], 'hourly': 300, 'daily_max': 2500, 'early': 1000}, 1200), ({'entry': [8, 360], 'exit': [8, 900], 'hourly': 400, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [2, 540], 'exit': [2, 1000], 'hourly': 300, 'daily_max': 2500, 'early': 1000}, 1000), ({'entry': [4, 360], 'exit': [4, 900], 'hourly': 300, 'daily_max': 1200, 'early': 1400}, 1200)], [({'entry': [2, 540], 'exit': [2, 1000], 'hourly': 300, 'daily_max': 2500, 'early': 1000}, 1000), ({'entry': [7, 360], 'exit': [7, 900], 'hourly': 300, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [0, 540], 'exit': [0, 921], 'hourly': 300, 'daily_max': 1800, 'early': 1000}, 1000), ({'entry': [1, 0], 'exit': [2, 0], 'hourly': 300, 'daily_max': 1800, 'early': 1000}, 1800), ({'entry': [8, 360], 'exit': [8, 1140], 'hourly': 200, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [3, 420], 'exit': [4, 960], 'hourly': 300, 'daily_max': 1800, 'early': 900}, 3600), ({'entry': [0, 360], 'exit': [0, 900], 'hourly': 300, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [2, 540], 'exit': [2, 899], 'hourly': 300, 'daily_max': 2500, 'early': 900}, 1800)], [({'entry': [9, 540], 'exit': [9, 900], 'hourly': 200, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [2, 540], 'exit': [2, 1000], 'hourly': 300, 'daily_max': 2500, 'early': 1000}, 1000), ({'entry': [2, 540], 'exit': [2, 900], 'hourly': 200, 'daily_max': 1800, 'early': 1400}, 1200), ({'entry': [5, 400], 'exit': [5, 1000], 'hourly': 300, 'daily_max': 2500, 'early': 1000}, 2500), ({'entry': [0, 360], 'exit': [0, 1140], 'hourly': 200, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [1, 0], 'exit': [2, 0], 'hourly': 300, 'daily_max': 1800, 'early': 1000}, 1800), ({'entry': [8, 541], 'exit': [8, 1232], 'hourly': 400, 'daily_max': 2500, 'early': 1400}, 2500), ({'entry': [3, 400], 'exit': [3, 1000], 'hourly': 300, 'daily_max': 800, 'early': 1000}, 800)], [({'entry': [3, 400], 'exit': [3, 1000], 'hourly': 300, 'daily_max': 800, 'early': 1000}, 800), ({'entry': [3, 420], 'exit': [4, 960], 'hourly': 300, 'daily_max': 1800, 'early': 900}, 3600), ({'entry': [1, 540], 'exit': [1, 899], 'hourly': 300, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [3, 540], 'exit': [5, 1218], 'hourly': 400, 'daily_max': 1800, 'early': 900}, 5400), ({'entry': [2, 470], 'exit': [2, 1140], 'hourly': 200, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [8, 541], 'exit': [8, 996], 'hourly': 200, 'daily_max': 1200, 'early': 1000}, 1200), ({'entry': [3, 450], 'exit': [3, 930], 'hourly': 400, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [1, 360], 'exit': [1, 1140], 'hourly': 400, 'daily_max': 1800, 'early': 1000}, 1000)]]
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 | 1000 | 1000 | Passed |
| fee oracle 1 | 1400 | 1200 | Failed |
| fee oracle 2 | 5000 | 5000 | Passed |
| fee oracle 3 | 2500 | 2500 | Passed |
| fee oracle 4 | 1000 | 1000 | Passed |
| fee oracle 5 | 3600 | 3600 | Passed |
| fee oracle 6 | 1400 | 1200 | Failed |
| fee oracle 7 | 1400 | 1200 | Failed |
SHA-256 / d5ab0a1d6a3f92ad9a539d1f81dbf0200f6c8807f72c17fe0c2de6bc1d82b8ef
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
ed, em = x['entry']
xd, xm = x['exit']
dur = (xd - ed) * 1440 + xm - em
if dur < 0:
return 'invalid'
hours = -(-dur // 60)
days = max(1, -(-dur // 1440))
regular = min(hours * x['hourly'], days * x['daily_max'])
eligible = ed % 7 < 5 and 360 <= em <= 540 and xd == ed and 900 <= xm <= 1140
if eligible:
return min(hours * x['hourly'], x['early'])
return regular
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'entry': [8, 360], 'exit': [8, 1140], 'hourly': 200, 'daily_max': 1200, 'early': 1000}, 1000), ({'entry': [8, 360], 'exit': [8, 900], 'hourly': 200, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [1, 541], 'exit': [2, 899], 'hourly': 400, 'daily_max': 2500, 'early': 1000}, 5000), ({'entry': [0, 480], 'exit': [0, 1300], 'hourly': 300, 'daily_max': 2500, 'early': 1000}, 2500), ({'entry': [1, 360], 'exit': [1, 1140], 'hourly': 400, 'daily_max': 1800, 'early': 1000}, 1000), ({'entry': [3, 420], 'exit': [4, 960], 'hourly': 300, 'daily_max': 1800, 'early': 900}, 3600), ({'entry': [3, 540], 'exit': [3, 1140], 'hourly': 400, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [0, 540], 'exit': [0, 1140], 'hourly': 200, 'daily_max': 1200, 'early': 1400}, 1200)], [({'entry': [11, 810], 'exit': [11, 913], 'hourly': 300, 'daily_max': 1800, 'early': 1400}, 600), ({'entry': [5, 400], 'exit': [5, 1000], 'hourly': 300, 'daily_max': 2500, 'early': 1000}, 2500), ({'entry': [1, 0], 'exit': [2, 0], 'hourly': 300, 'daily_max': 1800, 'early': 1000}, 1800), ({'entry': [11, 540], 'exit': [11, 1140], 'hourly': 400, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [2, 930], 'exit': [2, 1141], 'hourly': 300, 'daily_max': 2500, 'early': 1000}, 1200), ({'entry': [8, 360], 'exit': [8, 900], 'hourly': 400, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [2, 540], 'exit': [2, 1000], 'hourly': 300, 'daily_max': 2500, 'early': 1000}, 1000), ({'entry': [4, 360], 'exit': [4, 900], 'hourly': 300, 'daily_max': 1200, 'early': 1400}, 1200)], [({'entry': [2, 540], 'exit': [2, 1000], 'hourly': 300, 'daily_max': 2500, 'early': 1000}, 1000), ({'entry': [7, 360], 'exit': [7, 900], 'hourly': 300, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [0, 540], 'exit': [0, 921], 'hourly': 300, 'daily_max': 1800, 'early': 1000}, 1000), ({'entry': [1, 0], 'exit': [2, 0], 'hourly': 300, 'daily_max': 1800, 'early': 1000}, 1800), ({'entry': [8, 360], 'exit': [8, 1140], 'hourly': 200, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [3, 420], 'exit': [4, 960], 'hourly': 300, 'daily_max': 1800, 'early': 900}, 3600), ({'entry': [0, 360], 'exit': [0, 900], 'hourly': 300, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [2, 540], 'exit': [2, 899], 'hourly': 300, 'daily_max': 2500, 'early': 900}, 1800)], [({'entry': [9, 540], 'exit': [9, 900], 'hourly': 200, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [2, 540], 'exit': [2, 1000], 'hourly': 300, 'daily_max': 2500, 'early': 1000}, 1000), ({'entry': [2, 540], 'exit': [2, 900], 'hourly': 200, 'daily_max': 1800, 'early': 1400}, 1200), ({'entry': [5, 400], 'exit': [5, 1000], 'hourly': 300, 'daily_max': 2500, 'early': 1000}, 2500), ({'entry': [0, 360], 'exit': [0, 1140], 'hourly': 200, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [1, 0], 'exit': [2, 0], 'hourly': 300, 'daily_max': 1800, 'early': 1000}, 1800), ({'entry': [8, 541], 'exit': [8, 1232], 'hourly': 400, 'daily_max': 2500, 'early': 1400}, 2500), ({'entry': [3, 400], 'exit': [3, 1000], 'hourly': 300, 'daily_max': 800, 'early': 1000}, 800)], [({'entry': [3, 400], 'exit': [3, 1000], 'hourly': 300, 'daily_max': 800, 'early': 1000}, 800), ({'entry': [3, 420], 'exit': [4, 960], 'hourly': 300, 'daily_max': 1800, 'early': 900}, 3600), ({'entry': [1, 540], 'exit': [1, 899], 'hourly': 300, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [3, 540], 'exit': [5, 1218], 'hourly': 400, 'daily_max': 1800, 'early': 900}, 5400), ({'entry': [2, 470], 'exit': [2, 1140], 'hourly': 200, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [8, 541], 'exit': [8, 996], 'hourly': 200, 'daily_max': 1200, 'early': 1000}, 1200), ({'entry': [3, 450], 'exit': [3, 930], 'hourly': 400, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [1, 360], 'exit': [1, 1140], 'hourly': 400, 'daily_max': 1800, 'early': 1000}, 1000)]]
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 | 1000 | 1000 | Passed |
| fee oracle 1 | 1400 | 1200 | Failed |
| fee oracle 2 | 5000 | 5000 | Passed |
| fee oracle 3 | 2500 | 2500 | Passed |
| fee oracle 4 | 1000 | 1000 | Passed |
| fee oracle 5 | 3600 | 3600 | Passed |
| fee oracle 6 | 1400 | 1200 | Failed |
| fee oracle 7 | 1400 | 1200 | Failed |
SHA-256 / 4c178ec59dccb7137151c741038ecf8f1d5e5e6d5f0d529926765abbb21c3f28
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
ed, em = x['entry']
xd, xm = x['exit']
dur = (xd - ed) * 1440 + xm - em
if dur < 0:
return 'invalid'
hours = -(-dur // 60)
days = max(1, -(-dur // 1440))
regular = min(hours * x['hourly'], days * x['daily_max'])
eligible = ed % 7 < 5 and 360 <= em <= 540 and xd == ed and 900 <= xm <= 1140
if eligible:
return min(regular, x['early'])
return regular
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'entry': [8, 360], 'exit': [8, 1140], 'hourly': 200, 'daily_max': 1200, 'early': 1000}, 1000), ({'entry': [8, 360], 'exit': [8, 900], 'hourly': 200, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [1, 541], 'exit': [2, 899], 'hourly': 400, 'daily_max': 2500, 'early': 1000}, 5000), ({'entry': [0, 480], 'exit': [0, 1300], 'hourly': 300, 'daily_max': 2500, 'early': 1000}, 2500), ({'entry': [1, 360], 'exit': [1, 1140], 'hourly': 400, 'daily_max': 1800, 'early': 1000}, 1000), ({'entry': [3, 420], 'exit': [4, 960], 'hourly': 300, 'daily_max': 1800, 'early': 900}, 3600), ({'entry': [3, 540], 'exit': [3, 1140], 'hourly': 400, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [0, 540], 'exit': [0, 1140], 'hourly': 200, 'daily_max': 1200, 'early': 1400}, 1200)], [({'entry': [11, 810], 'exit': [11, 913], 'hourly': 300, 'daily_max': 1800, 'early': 1400}, 600), ({'entry': [5, 400], 'exit': [5, 1000], 'hourly': 300, 'daily_max': 2500, 'early': 1000}, 2500), ({'entry': [1, 0], 'exit': [2, 0], 'hourly': 300, 'daily_max': 1800, 'early': 1000}, 1800), ({'entry': [11, 540], 'exit': [11, 1140], 'hourly': 400, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [2, 930], 'exit': [2, 1141], 'hourly': 300, 'daily_max': 2500, 'early': 1000}, 1200), ({'entry': [8, 360], 'exit': [8, 900], 'hourly': 400, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [2, 540], 'exit': [2, 1000], 'hourly': 300, 'daily_max': 2500, 'early': 1000}, 1000), ({'entry': [4, 360], 'exit': [4, 900], 'hourly': 300, 'daily_max': 1200, 'early': 1400}, 1200)], [({'entry': [2, 540], 'exit': [2, 1000], 'hourly': 300, 'daily_max': 2500, 'early': 1000}, 1000), ({'entry': [7, 360], 'exit': [7, 900], 'hourly': 300, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [0, 540], 'exit': [0, 921], 'hourly': 300, 'daily_max': 1800, 'early': 1000}, 1000), ({'entry': [1, 0], 'exit': [2, 0], 'hourly': 300, 'daily_max': 1800, 'early': 1000}, 1800), ({'entry': [8, 360], 'exit': [8, 1140], 'hourly': 200, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [3, 420], 'exit': [4, 960], 'hourly': 300, 'daily_max': 1800, 'early': 900}, 3600), ({'entry': [0, 360], 'exit': [0, 900], 'hourly': 300, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [2, 540], 'exit': [2, 899], 'hourly': 300, 'daily_max': 2500, 'early': 900}, 1800)], [({'entry': [9, 540], 'exit': [9, 900], 'hourly': 200, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [2, 540], 'exit': [2, 1000], 'hourly': 300, 'daily_max': 2500, 'early': 1000}, 1000), ({'entry': [2, 540], 'exit': [2, 900], 'hourly': 200, 'daily_max': 1800, 'early': 1400}, 1200), ({'entry': [5, 400], 'exit': [5, 1000], 'hourly': 300, 'daily_max': 2500, 'early': 1000}, 2500), ({'entry': [0, 360], 'exit': [0, 1140], 'hourly': 200, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [1, 0], 'exit': [2, 0], 'hourly': 300, 'daily_max': 1800, 'early': 1000}, 1800), ({'entry': [8, 541], 'exit': [8, 1232], 'hourly': 400, 'daily_max': 2500, 'early': 1400}, 2500), ({'entry': [3, 400], 'exit': [3, 1000], 'hourly': 300, 'daily_max': 800, 'early': 1000}, 800)], [({'entry': [3, 400], 'exit': [3, 1000], 'hourly': 300, 'daily_max': 800, 'early': 1000}, 800), ({'entry': [3, 420], 'exit': [4, 960], 'hourly': 300, 'daily_max': 1800, 'early': 900}, 3600), ({'entry': [1, 540], 'exit': [1, 899], 'hourly': 300, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [3, 540], 'exit': [5, 1218], 'hourly': 400, 'daily_max': 1800, 'early': 900}, 5400), ({'entry': [2, 470], 'exit': [2, 1140], 'hourly': 200, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [8, 541], 'exit': [8, 996], 'hourly': 200, 'daily_max': 1200, 'early': 1000}, 1200), ({'entry': [3, 450], 'exit': [3, 930], 'hourly': 400, 'daily_max': 1200, 'early': 1400}, 1200), ({'entry': [1, 360], 'exit': [1, 1140], 'hourly': 400, 'daily_max': 1800, 'early': 1000}, 1000)]]
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 | 1000 | 1000 | Passed |
| fee oracle 1 | 1200 | 1200 | Passed |
| fee oracle 2 | 5000 | 5000 | Passed |
| fee oracle 3 | 2500 | 2500 | Passed |
| fee oracle 4 | 1000 | 1000 | Passed |
| fee oracle 5 | 3600 | 3600 | Passed |
| fee oracle 6 | 1200 | 1200 | Passed |
| fee oracle 7 | 1200 | 1200 | Passed |
SHA-256 / 2048c85ae412f3b42f65ddbf102230ed7581200532b54eac7f30fad61c6309a7
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:02.021508+00:00.
Case digest / c5e1a8ceffd636a611f46f1f03069bc19b20084fe5958cca78df9559b665e11b