FA-68781 / Toll and parking fee computation / Open access
Airport parking weekly cap: a partial day is counted as a full day before the weekly split · case 01
Airport parking weekly cap returns a wrong result when a partial day is counted as a full day before the weekly split.
ROOT CAUSE
The partial day is billed both as a full day and as its hourly remainder.
VERIFIED REPAIR
Restore the week and day split rule so that the step reads `weeks, days = divmod(full, 7)`.
Unsuccessful approach: A half-day rule rounds long remainders into a full day that is billed twice.
Case contract
Input {minutes, daily, weekly, hourly}. Full 1440-minute days and a remainder; the remainder costs started hours * hourly capped at daily. Each full 7-day week costs weekly; the leftover full days plus the remainder cost days*daily + remainder charge, capped at weekly.
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']
full, r = divmod(m, 1440)
part = min(x['daily'], -(-r // 60) * x['hourly'])
weeks, days = divmod(-(-m // 1440), 7)
return weeks * x['weekly'] + min(x['weekly'], days * x['daily'] + part)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'minutes': 8000, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 11000), ({'minutes': 5760, 'daily': 2200, 'weekly': 9000, 'hourly': 400}, 8800), ({'minutes': 2651, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 4400), ({'minutes': 2156, 'daily': 2800, 'weekly': 9000, 'hourly': 500}, 5600), ({'minutes': 28800, 'daily': 2200, 'weekly': 9000, 'hourly': 400}, 27000), ({'minutes': 10180, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 12000), ({'minutes': 2719, 'daily': 1800, 'weekly': 11000, 'hourly': 500}, 3600), ({'minutes': 7200, 'daily': 2200, 'weekly': 9000, 'hourly': 600}, 9000)], [({'minutes': 10180, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 12000), ({'minutes': 1757, 'daily': 2800, 'weekly': 9000, 'hourly': 500}, 5600), ({'minutes': 20792, 'daily': 2800, 'weekly': 9000, 'hourly': 500}, 20800), ({'minutes': 1215, 'daily': 2800, 'weekly': 13000, 'hourly': 500}, 2800), ({'minutes': 780, 'daily': 2200, 'weekly': 9000, 'hourly': 400}, 2200), ({'minutes': 8000, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 11000), ({'minutes': 28800, 'daily': 2800, 'weekly': 9000, 'hourly': 500}, 27000), ({'minutes': 18051, 'daily': 2800, 'weekly': 13000, 'hourly': 600}, 26000)], [({'minutes': 15840, 'daily': 1800, 'weekly': 9000, 'hourly': 400}, 16200), ({'minutes': 25920, 'daily': 1800, 'weekly': 13000, 'hourly': 500}, 33200), ({'minutes': 2339, 'daily': 1800, 'weekly': 11000, 'hourly': 400}, 3600), ({'minutes': 860, 'daily': 1800, 'weekly': 11000, 'hourly': 600}, 1800), ({'minutes': 10180, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 12000), ({'minutes': 418, 'daily': 2800, 'weekly': 9000, 'hourly': 600}, 2800), ({'minutes': 553, 'daily': 1800, 'weekly': 13000, 'hourly': 600}, 1800), ({'minutes': 8000, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 11000)], [({'minutes': 740, 'daily': 2800, 'weekly': 11000, 'hourly': 600}, 2800), ({'minutes': 24656, 'daily': 2200, 'weekly': 13000, 'hourly': 500}, 34100), ({'minutes': 28970, 'daily': 2200, 'weekly': 9000, 'hourly': 400}, 27000), ({'minutes': 17056, 'daily': 1800, 'weekly': 9000, 'hourly': 400}, 18000), ({'minutes': 10180, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 12000), ({'minutes': 20909, 'daily': 2800, 'weekly': 9000, 'hourly': 400}, 20800), ({'minutes': 14400, 'daily': 2200, 'weekly': 9000, 'hourly': 500}, 15600), ({'minutes': 8000, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 11000)], [({'minutes': 10180, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 12000), ({'minutes': 11520, 'daily': 2800, 'weekly': 13000, 'hourly': 400}, 15800), ({'minutes': 2346, 'daily': 2800, 'weekly': 11000, 'hourly': 600}, 5600), ({'minutes': 15840, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 19800), ({'minutes': 1090, 'daily': 1800, 'weekly': 11000, 'hourly': 600}, 1800), ({'minutes': 8000, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 11000), ({'minutes': 25920, 'daily': 1800, 'weekly': 11000, 'hourly': 600}, 29200), ({'minutes': 8762, 'daily': 1800, 'weekly': 9000, 'hourly': 600}, 9000)]]
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 | 11000 | 11000 | Passed |
| fee oracle 1 | 8800 | 8800 | Passed |
| fee oracle 2 | 6600 | 4400 | Failed |
| fee oracle 3 | 8400 | 5600 | Failed |
| fee oracle 4 | 27000 | 27000 | Passed |
| fee oracle 5 | 14200 | 12000 | Failed |
| fee oracle 6 | 5400 | 3600 | Failed |
| fee oracle 7 | 9000 | 9000 | Passed |
SHA-256 / b2fe9218a781921bd4103e1ecddd16cfe450340b447d4694071c0577eb155a01
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']
full, r = divmod(m, 1440)
part = min(x['daily'], -(-r // 60) * x['hourly'])
weeks, days = full // 7, full % 7 + (1 if r >= 720 else 0)
return weeks * x['weekly'] + min(x['weekly'], days * x['daily'] + part)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'minutes': 8000, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 11000), ({'minutes': 5760, 'daily': 2200, 'weekly': 9000, 'hourly': 400}, 8800), ({'minutes': 2651, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 4400), ({'minutes': 2156, 'daily': 2800, 'weekly': 9000, 'hourly': 500}, 5600), ({'minutes': 28800, 'daily': 2200, 'weekly': 9000, 'hourly': 400}, 27000), ({'minutes': 10180, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 12000), ({'minutes': 2719, 'daily': 1800, 'weekly': 11000, 'hourly': 500}, 3600), ({'minutes': 7200, 'daily': 2200, 'weekly': 9000, 'hourly': 600}, 9000)], [({'minutes': 10180, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 12000), ({'minutes': 1757, 'daily': 2800, 'weekly': 9000, 'hourly': 500}, 5600), ({'minutes': 20792, 'daily': 2800, 'weekly': 9000, 'hourly': 500}, 20800), ({'minutes': 1215, 'daily': 2800, 'weekly': 13000, 'hourly': 500}, 2800), ({'minutes': 780, 'daily': 2200, 'weekly': 9000, 'hourly': 400}, 2200), ({'minutes': 8000, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 11000), ({'minutes': 28800, 'daily': 2800, 'weekly': 9000, 'hourly': 500}, 27000), ({'minutes': 18051, 'daily': 2800, 'weekly': 13000, 'hourly': 600}, 26000)], [({'minutes': 15840, 'daily': 1800, 'weekly': 9000, 'hourly': 400}, 16200), ({'minutes': 25920, 'daily': 1800, 'weekly': 13000, 'hourly': 500}, 33200), ({'minutes': 2339, 'daily': 1800, 'weekly': 11000, 'hourly': 400}, 3600), ({'minutes': 860, 'daily': 1800, 'weekly': 11000, 'hourly': 600}, 1800), ({'minutes': 10180, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 12000), ({'minutes': 418, 'daily': 2800, 'weekly': 9000, 'hourly': 600}, 2800), ({'minutes': 553, 'daily': 1800, 'weekly': 13000, 'hourly': 600}, 1800), ({'minutes': 8000, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 11000)], [({'minutes': 740, 'daily': 2800, 'weekly': 11000, 'hourly': 600}, 2800), ({'minutes': 24656, 'daily': 2200, 'weekly': 13000, 'hourly': 500}, 34100), ({'minutes': 28970, 'daily': 2200, 'weekly': 9000, 'hourly': 400}, 27000), ({'minutes': 17056, 'daily': 1800, 'weekly': 9000, 'hourly': 400}, 18000), ({'minutes': 10180, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 12000), ({'minutes': 20909, 'daily': 2800, 'weekly': 9000, 'hourly': 400}, 20800), ({'minutes': 14400, 'daily': 2200, 'weekly': 9000, 'hourly': 500}, 15600), ({'minutes': 8000, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 11000)], [({'minutes': 10180, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 12000), ({'minutes': 11520, 'daily': 2800, 'weekly': 13000, 'hourly': 400}, 15800), ({'minutes': 2346, 'daily': 2800, 'weekly': 11000, 'hourly': 600}, 5600), ({'minutes': 15840, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 19800), ({'minutes': 1090, 'daily': 1800, 'weekly': 11000, 'hourly': 600}, 1800), ({'minutes': 8000, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 11000), ({'minutes': 25920, 'daily': 1800, 'weekly': 11000, 'hourly': 600}, 29200), ({'minutes': 8762, 'daily': 1800, 'weekly': 9000, 'hourly': 600}, 9000)]]
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 | 11000 | 11000 | Passed |
| fee oracle 1 | 8800 | 8800 | Passed |
| fee oracle 2 | 6600 | 4400 | Failed |
| fee oracle 3 | 5600 | 5600 | Passed |
| fee oracle 4 | 27000 | 27000 | Passed |
| fee oracle 5 | 12000 | 12000 | Passed |
| fee oracle 6 | 5400 | 3600 | Failed |
| fee oracle 7 | 9000 | 9000 | Passed |
SHA-256 / eee7b599d0a8dceac68f1895eef20f450c91024562fbd51ea2532ac1929e4c84
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']
full, r = divmod(m, 1440)
part = min(x['daily'], -(-r // 60) * x['hourly'])
weeks, days = divmod(full, 7)
return weeks * x['weekly'] + min(x['weekly'], days * x['daily'] + part)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'minutes': 8000, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 11000), ({'minutes': 5760, 'daily': 2200, 'weekly': 9000, 'hourly': 400}, 8800), ({'minutes': 2651, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 4400), ({'minutes': 2156, 'daily': 2800, 'weekly': 9000, 'hourly': 500}, 5600), ({'minutes': 28800, 'daily': 2200, 'weekly': 9000, 'hourly': 400}, 27000), ({'minutes': 10180, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 12000), ({'minutes': 2719, 'daily': 1800, 'weekly': 11000, 'hourly': 500}, 3600), ({'minutes': 7200, 'daily': 2200, 'weekly': 9000, 'hourly': 600}, 9000)], [({'minutes': 10180, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 12000), ({'minutes': 1757, 'daily': 2800, 'weekly': 9000, 'hourly': 500}, 5600), ({'minutes': 20792, 'daily': 2800, 'weekly': 9000, 'hourly': 500}, 20800), ({'minutes': 1215, 'daily': 2800, 'weekly': 13000, 'hourly': 500}, 2800), ({'minutes': 780, 'daily': 2200, 'weekly': 9000, 'hourly': 400}, 2200), ({'minutes': 8000, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 11000), ({'minutes': 28800, 'daily': 2800, 'weekly': 9000, 'hourly': 500}, 27000), ({'minutes': 18051, 'daily': 2800, 'weekly': 13000, 'hourly': 600}, 26000)], [({'minutes': 15840, 'daily': 1800, 'weekly': 9000, 'hourly': 400}, 16200), ({'minutes': 25920, 'daily': 1800, 'weekly': 13000, 'hourly': 500}, 33200), ({'minutes': 2339, 'daily': 1800, 'weekly': 11000, 'hourly': 400}, 3600), ({'minutes': 860, 'daily': 1800, 'weekly': 11000, 'hourly': 600}, 1800), ({'minutes': 10180, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 12000), ({'minutes': 418, 'daily': 2800, 'weekly': 9000, 'hourly': 600}, 2800), ({'minutes': 553, 'daily': 1800, 'weekly': 13000, 'hourly': 600}, 1800), ({'minutes': 8000, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 11000)], [({'minutes': 740, 'daily': 2800, 'weekly': 11000, 'hourly': 600}, 2800), ({'minutes': 24656, 'daily': 2200, 'weekly': 13000, 'hourly': 500}, 34100), ({'minutes': 28970, 'daily': 2200, 'weekly': 9000, 'hourly': 400}, 27000), ({'minutes': 17056, 'daily': 1800, 'weekly': 9000, 'hourly': 400}, 18000), ({'minutes': 10180, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 12000), ({'minutes': 20909, 'daily': 2800, 'weekly': 9000, 'hourly': 400}, 20800), ({'minutes': 14400, 'daily': 2200, 'weekly': 9000, 'hourly': 500}, 15600), ({'minutes': 8000, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 11000)], [({'minutes': 10180, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 12000), ({'minutes': 11520, 'daily': 2800, 'weekly': 13000, 'hourly': 400}, 15800), ({'minutes': 2346, 'daily': 2800, 'weekly': 11000, 'hourly': 600}, 5600), ({'minutes': 15840, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 19800), ({'minutes': 1090, 'daily': 1800, 'weekly': 11000, 'hourly': 600}, 1800), ({'minutes': 8000, 'daily': 2200, 'weekly': 11000, 'hourly': 500}, 11000), ({'minutes': 25920, 'daily': 1800, 'weekly': 11000, 'hourly': 600}, 29200), ({'minutes': 8762, 'daily': 1800, 'weekly': 9000, 'hourly': 600}, 9000)]]
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 | 11000 | 11000 | Passed |
| fee oracle 1 | 8800 | 8800 | Passed |
| fee oracle 2 | 4400 | 4400 | Passed |
| fee oracle 3 | 5600 | 5600 | Passed |
| fee oracle 4 | 27000 | 27000 | Passed |
| fee oracle 5 | 12000 | 12000 | Passed |
| fee oracle 6 | 3600 | 3600 | Passed |
| fee oracle 7 | 9000 | 9000 | Passed |
SHA-256 / 6c31fead9445c33ef480929e14a245833dc4a5d9f140888679afad94de37659d
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:05.459828+00:00.
Case digest / 43293d8d7652c8aa47c020f10f8a9568de454472aa846e67cdf534d2c5c54cb0