broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    energy = -(-x['wh'] * x['price_per_kwh'] // 1000)
    idle = max(0, x['unplug'] - x['charge_end'] - x['idle_grace'])
    idle_fee = -(-idle // 10) * x['idle_rate']
    total = x['session_fee'] + energy + idle_fee
    return {'energy': energy, 'idle': idle_fee, 'total': max(x['min_fee'], total)}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'plug_in': 131, 'charge_end': 273, 'unplug': 283, 'wh': 37842, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 2000, 'session_fee': 150, 'min_fee': 500}, {'energy': 1325, 'idle': 0, 'total': 1475}), ({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 241, 'charge_end': 257, 'unplug': 457, 'wh': 25918, 'price_per_kwh': 29, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 200}, {'energy': 752, 'idle': 1000, 'total': 1902}), ({'plug_in': 407, 'charge_end': 459, 'unplug': 659, 'wh': 2348, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 300}, {'energy': 83, 'idle': 1000, 'total': 1233}), ({'plug_in': 406, 'charge_end': 466, 'unplug': 476, 'wh': 46986, 'price_per_kwh': 35, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 3000, 'session_fee': 100, 'min_fee': 200}, {'energy': 1645, 'idle': 0, 'total': 1745}), ({'plug_in': 577, 'charge_end': 673, 'unplug': 698, 'wh': 33233, 'price_per_kwh': 52, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 500}, {'energy': 1729, 'idle': 50, 'total': 1929}), ({'plug_in': 357, 'charge_end': 490, 'unplug': 490, 'wh': 37874, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 1000, 'session_fee': 100, 'min_fee': 200}, {'energy': 1326, 'idle': 0, 'total': 1426}), ({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024})], [({'plug_in': 567, 'charge_end': 630, 'unplug': 1030, 'wh': 36618, 'price_per_kwh': 52, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 3000, 'session_fee': 150, 'min_fee': 500}, {'energy': 1905, 'idle': 3000, 'total': 5055}), ({'plug_in': 240, 'charge_end': 417, 'unplug': 442, 'wh': 22897, 'price_per_kwh': 52, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 3000, 'session_fee': 0, 'min_fee': 200}, {'energy': 1191, 'idle': 100, 'total': 1291}), ({'plug_in': 412, 'charge_end': 513, 'unplug': 913, 'wh': 37562, 'price_per_kwh': 52, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 300}, {'energy': 1954, 'idle': 1000, 'total': 3104}), ({'plug_in': 577, 'charge_end': 875, 'unplug': 890, 'wh': 36979, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 1000, 'session_fee': 100, 'min_fee': 300}, {'energy': 1295, 'idle': 0, 'total': 1395}), ({'plug_in': 507, 'charge_end': 619, 'unplug': 624, 'wh': 58769, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 1000, 'session_fee': 100, 'min_fee': 200}, {'energy': 2645, 'idle': 0, 'total': 2745}), ({'plug_in': 219, 'charge_end': 302, 'unplug': 502, 'wh': 7040, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 2000, 'session_fee': 0, 'min_fee': 200}, {'energy': 247, 'idle': 1900, 'total': 2147}), ({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024})], [({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024}), ({'plug_in': 431, 'charge_end': 515, 'unplug': 520, 'wh': 37388, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 3000, 'session_fee': 100, 'min_fee': 200}, {'energy': 1309, 'idle': 0, 'total': 1409}), ({'plug_in': 355, 'charge_end': 644, 'unplug': 659, 'wh': 31439, 'price_per_kwh': 29, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 150, 'min_fee': 500}, {'energy': 912, 'idle': 0, 'total': 1062}), ({'plug_in': 361, 'charge_end': 432, 'unplug': 832, 'wh': 39144, 'price_per_kwh': 52, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 500}, {'energy': 2036, 'idle': 1000, 'total': 3186}), ({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 281, 'charge_end': 329, 'unplug': 529, 'wh': 43856, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 3000, 'session_fee': 100, 'min_fee': 200}, {'energy': 1535, 'idle': 950, 'total': 2585}), ({'plug_in': 14, 'charge_end': 237, 'unplug': 637, 'wh': 4090, 'price_per_kwh': 29, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 200}, {'energy': 119, 'idle': 1000, 'total': 1269}), ({'plug_in': 525, 'charge_end': 752, 'unplug': 767, 'wh': 24814, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 2000, 'session_fee': 150, 'min_fee': 300}, {'energy': 720, 'idle': 100, 'total': 970})], [({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 489, 'charge_end': 568, 'unplug': 768, 'wh': 1647, 'price_per_kwh': 29, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 200}, {'energy': 48, 'idle': 1000, 'total': 1198}), ({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024}), ({'plug_in': 231, 'charge_end': 437, 'unplug': 442, 'wh': 31724, 'price_per_kwh': 35, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 100, 'min_fee': 300}, {'energy': 1111, 'idle': 0, 'total': 1211}), ({'plug_in': 506, 'charge_end': 796, 'unplug': 801, 'wh': 18131, 'price_per_kwh': 52, 'idle_grace': 10, 'idle_rate': 40, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 300}, {'energy': 943, 'idle': 0, 'total': 943}), ({'plug_in': 412, 'charge_end': 659, 'unplug': 1059, 'wh': 41636, 'price_per_kwh': 35, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 3000, 'session_fee': 0, 'min_fee': 200}, {'energy': 1458, 'idle': 1950, 'total': 3408}), ({'plug_in': 472, 'charge_end': 580, 'unplug': 980, 'wh': 58243, 'price_per_kwh': 29, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 200}, {'energy': 1690, 'idle': 1000, 'total': 2840}), ({'plug_in': 234, 'charge_end': 284, 'unplug': 309, 'wh': 13379, 'price_per_kwh': 45, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 3000, 'session_fee': 0, 'min_fee': 300}, {'energy': 603, 'idle': 50, 'total': 653})], [({'plug_in': 458, 'charge_end': 619, 'unplug': 1019, 'wh': 42887, 'price_per_kwh': 35, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 3000, 'session_fee': 0, 'min_fee': 500}, {'energy': 1502, 'idle': 3000, 'total': 4502}), ({'plug_in': 422, 'charge_end': 479, 'unplug': 679, 'wh': 52516, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 40, 'idle_cap': 2000, 'session_fee': 150, 'min_fee': 300}, {'energy': 1523, 'idle': 760, 'total': 2433}), ({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024}), ({'plug_in': 447, 'charge_end': 641, 'unplug': 1041, 'wh': 10840, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 200}, {'energy': 488, 'idle': 1000, 'total': 1638}), ({'plug_in': 230, 'charge_end': 296, 'unplug': 296, 'wh': 48898, 'price_per_kwh': 45, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 150, 'min_fee': 200}, {'energy': 2201, 'idle': 0, 'total': 2351}), ({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 579, 'charge_end': 718, 'unplug': 723, 'wh': 50758, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 200}, {'energy': 2285, 'idle': 0, 'total': 2385}), ({'plug_in': 89, 'charge_end': 303, 'unplug': 703, 'wh': 15398, 'price_per_kwh': 45, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 3000, 'session_fee': 0, 'min_fee': 300}, {'energy': 693, 'idle': 1950, 'total': 2643})]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    energy = -(-x['wh'] * x['price_per_kwh'] // 1000)
    idle = max(0, x['unplug'] - x['charge_end'] - x['idle_grace'])
    idle_fee = min(x['idle_cap'], -(-idle // 10)) * x['idle_rate']
    total = x['session_fee'] + energy + idle_fee
    return {'energy': energy, 'idle': idle_fee, 'total': max(x['min_fee'], total)}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'plug_in': 131, 'charge_end': 273, 'unplug': 283, 'wh': 37842, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 2000, 'session_fee': 150, 'min_fee': 500}, {'energy': 1325, 'idle': 0, 'total': 1475}), ({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 241, 'charge_end': 257, 'unplug': 457, 'wh': 25918, 'price_per_kwh': 29, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 200}, {'energy': 752, 'idle': 1000, 'total': 1902}), ({'plug_in': 407, 'charge_end': 459, 'unplug': 659, 'wh': 2348, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 300}, {'energy': 83, 'idle': 1000, 'total': 1233}), ({'plug_in': 406, 'charge_end': 466, 'unplug': 476, 'wh': 46986, 'price_per_kwh': 35, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 3000, 'session_fee': 100, 'min_fee': 200}, {'energy': 1645, 'idle': 0, 'total': 1745}), ({'plug_in': 577, 'charge_end': 673, 'unplug': 698, 'wh': 33233, 'price_per_kwh': 52, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 500}, {'energy': 1729, 'idle': 50, 'total': 1929}), ({'plug_in': 357, 'charge_end': 490, 'unplug': 490, 'wh': 37874, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 1000, 'session_fee': 100, 'min_fee': 200}, {'energy': 1326, 'idle': 0, 'total': 1426}), ({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024})], [({'plug_in': 567, 'charge_end': 630, 'unplug': 1030, 'wh': 36618, 'price_per_kwh': 52, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 3000, 'session_fee': 150, 'min_fee': 500}, {'energy': 1905, 'idle': 3000, 'total': 5055}), ({'plug_in': 240, 'charge_end': 417, 'unplug': 442, 'wh': 22897, 'price_per_kwh': 52, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 3000, 'session_fee': 0, 'min_fee': 200}, {'energy': 1191, 'idle': 100, 'total': 1291}), ({'plug_in': 412, 'charge_end': 513, 'unplug': 913, 'wh': 37562, 'price_per_kwh': 52, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 300}, {'energy': 1954, 'idle': 1000, 'total': 3104}), ({'plug_in': 577, 'charge_end': 875, 'unplug': 890, 'wh': 36979, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 1000, 'session_fee': 100, 'min_fee': 300}, {'energy': 1295, 'idle': 0, 'total': 1395}), ({'plug_in': 507, 'charge_end': 619, 'unplug': 624, 'wh': 58769, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 1000, 'session_fee': 100, 'min_fee': 200}, {'energy': 2645, 'idle': 0, 'total': 2745}), ({'plug_in': 219, 'charge_end': 302, 'unplug': 502, 'wh': 7040, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 2000, 'session_fee': 0, 'min_fee': 200}, {'energy': 247, 'idle': 1900, 'total': 2147}), ({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024})], [({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024}), ({'plug_in': 431, 'charge_end': 515, 'unplug': 520, 'wh': 37388, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 3000, 'session_fee': 100, 'min_fee': 200}, {'energy': 1309, 'idle': 0, 'total': 1409}), ({'plug_in': 355, 'charge_end': 644, 'unplug': 659, 'wh': 31439, 'price_per_kwh': 29, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 150, 'min_fee': 500}, {'energy': 912, 'idle': 0, 'total': 1062}), ({'plug_in': 361, 'charge_end': 432, 'unplug': 832, 'wh': 39144, 'price_per_kwh': 52, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 500}, {'energy': 2036, 'idle': 1000, 'total': 3186}), ({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 281, 'charge_end': 329, 'unplug': 529, 'wh': 43856, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 3000, 'session_fee': 100, 'min_fee': 200}, {'energy': 1535, 'idle': 950, 'total': 2585}), ({'plug_in': 14, 'charge_end': 237, 'unplug': 637, 'wh': 4090, 'price_per_kwh': 29, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 200}, {'energy': 119, 'idle': 1000, 'total': 1269}), ({'plug_in': 525, 'charge_end': 752, 'unplug': 767, 'wh': 24814, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 2000, 'session_fee': 150, 'min_fee': 300}, {'energy': 720, 'idle': 100, 'total': 970})], [({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 489, 'charge_end': 568, 'unplug': 768, 'wh': 1647, 'price_per_kwh': 29, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 200}, {'energy': 48, 'idle': 1000, 'total': 1198}), ({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024}), ({'plug_in': 231, 'charge_end': 437, 'unplug': 442, 'wh': 31724, 'price_per_kwh': 35, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 100, 'min_fee': 300}, {'energy': 1111, 'idle': 0, 'total': 1211}), ({'plug_in': 506, 'charge_end': 796, 'unplug': 801, 'wh': 18131, 'price_per_kwh': 52, 'idle_grace': 10, 'idle_rate': 40, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 300}, {'energy': 943, 'idle': 0, 'total': 943}), ({'plug_in': 412, 'charge_end': 659, 'unplug': 1059, 'wh': 41636, 'price_per_kwh': 35, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 3000, 'session_fee': 0, 'min_fee': 200}, {'energy': 1458, 'idle': 1950, 'total': 3408}), ({'plug_in': 472, 'charge_end': 580, 'unplug': 980, 'wh': 58243, 'price_per_kwh': 29, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 200}, {'energy': 1690, 'idle': 1000, 'total': 2840}), ({'plug_in': 234, 'charge_end': 284, 'unplug': 309, 'wh': 13379, 'price_per_kwh': 45, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 3000, 'session_fee': 0, 'min_fee': 300}, {'energy': 603, 'idle': 50, 'total': 653})], [({'plug_in': 458, 'charge_end': 619, 'unplug': 1019, 'wh': 42887, 'price_per_kwh': 35, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 3000, 'session_fee': 0, 'min_fee': 500}, {'energy': 1502, 'idle': 3000, 'total': 4502}), ({'plug_in': 422, 'charge_end': 479, 'unplug': 679, 'wh': 52516, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 40, 'idle_cap': 2000, 'session_fee': 150, 'min_fee': 300}, {'energy': 1523, 'idle': 760, 'total': 2433}), ({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024}), ({'plug_in': 447, 'charge_end': 641, 'unplug': 1041, 'wh': 10840, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 200}, {'energy': 488, 'idle': 1000, 'total': 1638}), ({'plug_in': 230, 'charge_end': 296, 'unplug': 296, 'wh': 48898, 'price_per_kwh': 45, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 150, 'min_fee': 200}, {'energy': 2201, 'idle': 0, 'total': 2351}), ({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 579, 'charge_end': 718, 'unplug': 723, 'wh': 50758, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 200}, {'energy': 2285, 'idle': 0, 'total': 2385}), ({'plug_in': 89, 'charge_end': 303, 'unplug': 703, 'wh': 15398, 'price_per_kwh': 45, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 3000, 'session_fee': 0, 'min_fee': 300}, {'energy': 693, 'idle': 1950, 'total': 2643})]]
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)

prompt:
EV charging session and idle fee returns a wrong result when the idle cap limits block count instead of cents.

Input {plug_in, charge_end, unplug (minutes), wh, price_per_kwh, idle_grace, idle_rate (per started 10 min), idle_cap, session_fee, min_fee}. Energy = ceil(wh*price/1000). Idle minutes = max(0, unplug - charge_end - grace); idle fee = min(idle_cap, started 10-minute blocks * idle_rate). Total = max(min_fee, session_fee + energy + idle). Return {energy, idle, total}.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    energy = -(-x['wh'] * x['price_per_kwh'] // 1000)
    idle = max(0, x['unplug'] - x['charge_end'] - x['idle_grace'])
    idle_fee = min(x['idle_cap'], idle // 10 * x['idle_rate'])
    total = x['session_fee'] + energy + idle_fee
    return {'energy': energy, 'idle': idle_fee, 'total': max(x['min_fee'], total)}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'plug_in': 336, 'charge_end': 546, 'unplug': 746, 'wh': 47420, 'price_per_kwh': 52, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 300}, {'energy': 2466, 'idle': 1000, 'total': 3616}), ({'plug_in': 255, 'charge_end': 415, 'unplug': 440, 'wh': 45074, 'price_per_kwh': 52, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 300}, {'energy': 2344, 'idle': 100, 'total': 2594}), ({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024}), ({'plug_in': 255, 'charge_end': 363, 'unplug': 363, 'wh': 22789, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 1026, 'idle': 0, 'total': 1026}), ({'plug_in': 33, 'charge_end': 201, 'unplug': 217, 'wh': 16946, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 492, 'idle': 100, 'total': 692}), ({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 383, 'charge_end': 637, 'unplug': 653, 'wh': 34401, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 40, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 200}, {'energy': 1549, 'idle': 40, 'total': 1689}), ({'plug_in': 442, 'charge_end': 688, 'unplug': 693, 'wh': 8503, 'price_per_kwh': 52, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 3000, 'session_fee': 150, 'min_fee': 300}, {'energy': 443, 'idle': 0, 'total': 593})], [({'plug_in': 310, 'charge_end': 372, 'unplug': 372, 'wh': 43702, 'price_per_kwh': 45, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 2000, 'session_fee': 0, 'min_fee': 300}, {'energy': 1967, 'idle': 0, 'total': 1967}), ({'plug_in': 407, 'charge_end': 628, 'unplug': 638, 'wh': 39296, 'price_per_kwh': 35, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 3000, 'session_fee': 0, 'min_fee': 200}, {'energy': 1376, 'idle': 0, 'total': 1376}), ({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024}), ({'plug_in': 185, 'charge_end': 213, 'unplug': 273, 'wh': 18018, 'price_per_kwh': 45, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 3000, 'session_fee': 100, 'min_fee': 300}, {'energy': 811, 'idle': 250, 'total': 1161}), ({'plug_in': 196, 'charge_end': 211, 'unplug': 216, 'wh': 46993, 'price_per_kwh': 35, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 1645, 'idle': 0, 'total': 1745}), ({'plug_in': 395, 'charge_end': 691, 'unplug': 751, 'wh': 31873, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 40, 'idle_cap': 1000, 'session_fee': 100, 'min_fee': 200}, {'energy': 925, 'idle': 200, 'total': 1225}), ({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 389, 'charge_end': 598, 'unplug': 998, 'wh': 45639, 'price_per_kwh': 52, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 3000, 'session_fee': 100, 'min_fee': 300}, {'energy': 2374, 'idle': 1560, 'total': 4034})], [({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024}), ({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 103, 'charge_end': 327, 'unplug': 342, 'wh': 43561, 'price_per_kwh': 35, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 3000, 'session_fee': 0, 'min_fee': 500}, {'energy': 1525, 'idle': 100, 'total': 1625}), ({'plug_in': 249, 'charge_end': 531, 'unplug': 931, 'wh': 12324, 'price_per_kwh': 35, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 200}, {'energy': 432, 'idle': 1000, 'total': 1582}), ({'plug_in': 183, 'charge_end': 471, 'unplug': 481, 'wh': 40929, 'price_per_kwh': 52, 'idle_grace': 10, 'idle_rate': 40, 'idle_cap': 1000, 'session_fee': 100, 'min_fee': 500}, {'energy': 2129, 'idle': 0, 'total': 2229}), ({'plug_in': 429, 'charge_end': 480, 'unplug': 505, 'wh': 10405, 'price_per_kwh': 52, 'idle_grace': 10, 'idle_rate': 40, 'idle_cap': 1000, 'session_fee': 100, 'min_fee': 300}, {'energy': 542, 'idle': 80, 'total': 722}), ({'plug_in': 424, 'charge_end': 656, 'unplug': 666, 'wh': 17973, 'price_per_kwh': 35, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 300}, {'energy': 630, 'idle': 0, 'total': 780}), ({'plug_in': 48, 'charge_end': 125, 'unplug': 325, 'wh': 4894, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 3000, 'session_fee': 0, 'min_fee': 300}, {'energy': 221, 'idle': 950, 'total': 1171})], [({'plug_in': 50, 'charge_end': 200, 'unplug': 600, 'wh': 44399, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 0, 'min_fee': 500}, {'energy': 1998, 'idle': 1950, 'total': 3948}), ({'plug_in': 314, 'charge_end': 544, 'unplug': 604, 'wh': 35460, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 2000, 'session_fee': 0, 'min_fee': 300}, {'energy': 1242, 'idle': 200, 'total': 1442}), ({'plug_in': 399, 'charge_end': 662, 'unplug': 667, 'wh': 39622, 'price_per_kwh': 29, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 2000, 'session_fee': 150, 'min_fee': 500}, {'energy': 1150, 'idle': 0, 'total': 1300}), ({'plug_in': 79, 'charge_end': 176, 'unplug': 376, 'wh': 17360, 'price_per_kwh': 45, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 500}, {'energy': 782, 'idle': 1000, 'total': 1932}), ({'plug_in': 294, 'charge_end': 497, 'unplug': 507, 'wh': 31972, 'price_per_kwh': 29, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 2000, 'session_fee': 150, 'min_fee': 200}, {'energy': 928, 'idle': 0, 'total': 1078}), ({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 544, 'charge_end': 698, 'unplug': 714, 'wh': 37260, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 3000, 'session_fee': 100, 'min_fee': 500}, {'energy': 1081, 'idle': 50, 'total': 1231}), ({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024})], [({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024}), ({'plug_in': 499, 'charge_end': 740, 'unplug': 755, 'wh': 27977, 'price_per_kwh': 35, 'idle_grace': 10, 'idle_rate': 40, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 200}, {'energy': 980, 'idle': 40, 'total': 1170}), ({'plug_in': 80, 'charge_end': 251, 'unplug': 276, 'wh': 7861, 'price_per_kwh': 52, 'idle_grace': 10, 'idle_rate': 40, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 409, 'idle': 80, 'total': 500}), ({'plug_in': 61, 'charge_end': 225, 'unplug': 425, 'wh': 56258, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 300}, {'energy': 2532, 'idle': 1000, 'total': 3532}), ({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 369, 'charge_end': 528, 'unplug': 728, 'wh': 22284, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 1000, 'session_fee': 100, 'min_fee': 200}, {'energy': 1003, 'idle': 950, 'total': 2053}), ({'plug_in': 547, 'charge_end': 608, 'unplug': 618, 'wh': 31626, 'price_per_kwh': 45, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 3000, 'session_fee': 100, 'min_fee': 200}, {'energy': 1424, 'idle': 0, 'total': 1524}), ({'plug_in': 593, 'charge_end': 863, 'unplug': 863, 'wh': 5933, 'price_per_kwh': 52, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 3000, 'session_fee': 0, 'min_fee': 500}, {'energy': 309, 'idle': 0, 'total': 500})]]
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)

meaning: Fixture-count band, not measured model difficulty

deps: stdlib

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    energy = -(-x['wh'] * x['price_per_kwh'] // 1000)
    idle = max(0, x['unplug'] - x['charge_end'] - x['idle_grace'])
    idle_fee = min(x['idle_cap'], -(-idle // 60) * 6 * x['idle_rate'])
    total = x['session_fee'] + energy + idle_fee
    return {'energy': energy, 'idle': idle_fee, 'total': max(x['min_fee'], total)}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'plug_in': 336, 'charge_end': 546, 'unplug': 746, 'wh': 47420, 'price_per_kwh': 52, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 300}, {'energy': 2466, 'idle': 1000, 'total': 3616}), ({'plug_in': 255, 'charge_end': 415, 'unplug': 440, 'wh': 45074, 'price_per_kwh': 52, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 300}, {'energy': 2344, 'idle': 100, 'total': 2594}), ({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024}), ({'plug_in': 255, 'charge_end': 363, 'unplug': 363, 'wh': 22789, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 1026, 'idle': 0, 'total': 1026}), ({'plug_in': 33, 'charge_end': 201, 'unplug': 217, 'wh': 16946, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 492, 'idle': 100, 'total': 692}), ({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 383, 'charge_end': 637, 'unplug': 653, 'wh': 34401, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 40, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 200}, {'energy': 1549, 'idle': 40, 'total': 1689}), ({'plug_in': 442, 'charge_end': 688, 'unplug': 693, 'wh': 8503, 'price_per_kwh': 52, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 3000, 'session_fee': 150, 'min_fee': 300}, {'energy': 443, 'idle': 0, 'total': 593})], [({'plug_in': 310, 'charge_end': 372, 'unplug': 372, 'wh': 43702, 'price_per_kwh': 45, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 2000, 'session_fee': 0, 'min_fee': 300}, {'energy': 1967, 'idle': 0, 'total': 1967}), ({'plug_in': 407, 'charge_end': 628, 'unplug': 638, 'wh': 39296, 'price_per_kwh': 35, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 3000, 'session_fee': 0, 'min_fee': 200}, {'energy': 1376, 'idle': 0, 'total': 1376}), ({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024}), ({'plug_in': 185, 'charge_end': 213, 'unplug': 273, 'wh': 18018, 'price_per_kwh': 45, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 3000, 'session_fee': 100, 'min_fee': 300}, {'energy': 811, 'idle': 250, 'total': 1161}), ({'plug_in': 196, 'charge_end': 211, 'unplug': 216, 'wh': 46993, 'price_per_kwh': 35, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 1645, 'idle': 0, 'total': 1745}), ({'plug_in': 395, 'charge_end': 691, 'unplug': 751, 'wh': 31873, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 40, 'idle_cap': 1000, 'session_fee': 100, 'min_fee': 200}, {'energy': 925, 'idle': 200, 'total': 1225}), ({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 389, 'charge_end': 598, 'unplug': 998, 'wh': 45639, 'price_per_kwh': 52, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 3000, 'session_fee': 100, 'min_fee': 300}, {'energy': 2374, 'idle': 1560, 'total': 4034})], [({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024}), ({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 103, 'charge_end': 327, 'unplug': 342, 'wh': 43561, 'price_per_kwh': 35, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 3000, 'session_fee': 0, 'min_fee': 500}, {'energy': 1525, 'idle': 100, 'total': 1625}), ({'plug_in': 249, 'charge_end': 531, 'unplug': 931, 'wh': 12324, 'price_per_kwh': 35, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 200}, {'energy': 432, 'idle': 1000, 'total': 1582}), ({'plug_in': 183, 'charge_end': 471, 'unplug': 481, 'wh': 40929, 'price_per_kwh': 52, 'idle_grace': 10, 'idle_rate': 40, 'idle_cap': 1000, 'session_fee': 100, 'min_fee': 500}, {'energy': 2129, 'idle': 0, 'total': 2229}), ({'plug_in': 429, 'charge_end': 480, 'unplug': 505, 'wh': 10405, 'price_per_kwh': 52, 'idle_grace': 10, 'idle_rate': 40, 'idle_cap': 1000, 'session_fee': 100, 'min_fee': 300}, {'energy': 542, 'idle': 80, 'total': 722}), ({'plug_in': 424, 'charge_end': 656, 'unplug': 666, 'wh': 17973, 'price_per_kwh': 35, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 300}, {'energy': 630, 'idle': 0, 'total': 780}), ({'plug_in': 48, 'charge_end': 125, 'unplug': 325, 'wh': 4894, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 3000, 'session_fee': 0, 'min_fee': 300}, {'energy': 221, 'idle': 950, 'total': 1171})], [({'plug_in': 50, 'charge_end': 200, 'unplug': 600, 'wh': 44399, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 0, 'min_fee': 500}, {'energy': 1998, 'idle': 1950, 'total': 3948}), ({'plug_in': 314, 'charge_end': 544, 'unplug': 604, 'wh': 35460, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 2000, 'session_fee': 0, 'min_fee': 300}, {'energy': 1242, 'idle': 200, 'total': 1442}), ({'plug_in': 399, 'charge_end': 662, 'unplug': 667, 'wh': 39622, 'price_per_kwh': 29, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 2000, 'session_fee': 150, 'min_fee': 500}, {'energy': 1150, 'idle': 0, 'total': 1300}), ({'plug_in': 79, 'charge_end': 176, 'unplug': 376, 'wh': 17360, 'price_per_kwh': 45, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 500}, {'energy': 782, 'idle': 1000, 'total': 1932}), ({'plug_in': 294, 'charge_end': 497, 'unplug': 507, 'wh': 31972, 'price_per_kwh': 29, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 2000, 'session_fee': 150, 'min_fee': 200}, {'energy': 928, 'idle': 0, 'total': 1078}), ({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 544, 'charge_end': 698, 'unplug': 714, 'wh': 37260, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 3000, 'session_fee': 100, 'min_fee': 500}, {'energy': 1081, 'idle': 50, 'total': 1231}), ({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024})], [({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024}), ({'plug_in': 499, 'charge_end': 740, 'unplug': 755, 'wh': 27977, 'price_per_kwh': 35, 'idle_grace': 10, 'idle_rate': 40, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 200}, {'energy': 980, 'idle': 40, 'total': 1170}), ({'plug_in': 80, 'charge_end': 251, 'unplug': 276, 'wh': 7861, 'price_per_kwh': 52, 'idle_grace': 10, 'idle_rate': 40, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 409, 'idle': 80, 'total': 500}), ({'plug_in': 61, 'charge_end': 225, 'unplug': 425, 'wh': 56258, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 300}, {'energy': 2532, 'idle': 1000, 'total': 3532}), ({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 369, 'charge_end': 528, 'unplug': 728, 'wh': 22284, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 1000, 'session_fee': 100, 'min_fee': 200}, {'energy': 1003, 'idle': 950, 'total': 2053}), ({'plug_in': 547, 'charge_end': 608, 'unplug': 618, 'wh': 31626, 'price_per_kwh': 45, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 3000, 'session_fee': 100, 'min_fee': 200}, {'energy': 1424, 'idle': 0, 'total': 1524}), ({'plug_in': 593, 'charge_end': 863, 'unplug': 863, 'wh': 5933, 'price_per_kwh': 52, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 3000, 'session_fee': 0, 'min_fee': 500}, {'energy': 309, 'idle': 0, 'total': 500})]]
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)

prompt:
EV charging session and idle fee returns a wrong result when idle time is billed in whole hours.

Input {plug_in, charge_end, unplug (minutes), wh, price_per_kwh, idle_grace, idle_rate (per started 10 min), idle_cap, session_fee, min_fee}. Energy = ceil(wh*price/1000). Idle minutes = max(0, unplug - charge_end - grace); idle fee = min(idle_cap, started 10-minute blocks * idle_rate). Total = max(min_fee, session_fee + energy + idle). Return {energy, idle, total}.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    energy = -(-x['wh'] * x['price_per_kwh'] // 1000)
    idle = max(0, x['unplug'] - x['charge_end'] - x['idle_grace'])
    idle_fee = min(x['idle_cap'], -(-idle // 10) * x['idle_rate'])
    total = x['session_fee'] + energy + idle_fee
    return {'energy': energy, 'idle': idle_fee, 'total': x['session_fee'] + max(x['min_fee'], energy + idle_fee)}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 93, 'charge_end': 112, 'unplug': 312, 'wh': 46598, 'price_per_kwh': 35, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 2000, 'session_fee': 0, 'min_fee': 500}, {'energy': 1631, 'idle': 1900, 'total': 3531}), ({'plug_in': 548, 'charge_end': 701, 'unplug': 706, 'wh': 9990, 'price_per_kwh': 29, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 3000, 'session_fee': 150, 'min_fee': 500}, {'energy': 290, 'idle': 0, 'total': 500}), ({'plug_in': 502, 'charge_end': 683, 'unplug': 698, 'wh': 5462, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 300}, {'energy': 246, 'idle': 50, 'total': 300}), ({'plug_in': 119, 'charge_end': 199, 'unplug': 215, 'wh': 5114, 'price_per_kwh': 29, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 3000, 'session_fee': 100, 'min_fee': 500}, {'energy': 149, 'idle': 100, 'total': 500}), ({'plug_in': 74, 'charge_end': 111, 'unplug': 171, 'wh': 4221, 'price_per_kwh': 29, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 3000, 'session_fee': 150, 'min_fee': 500}, {'energy': 123, 'idle': 200, 'total': 500}), ({'plug_in': 585, 'charge_end': 800, 'unplug': 810, 'wh': 39441, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 2000, 'session_fee': 0, 'min_fee': 500}, {'energy': 1381, 'idle': 0, 'total': 1381}), ({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024})], [({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024}), ({'plug_in': 4, 'charge_end': 296, 'unplug': 312, 'wh': 3717, 'price_per_kwh': 52, 'idle_grace': 10, 'idle_rate': 40, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 500}, {'energy': 194, 'idle': 40, 'total': 500}), ({'plug_in': 73, 'charge_end': 83, 'unplug': 283, 'wh': 4230, 'price_per_kwh': 35, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 100, 'min_fee': 200}, {'energy': 149, 'idle': 1000, 'total': 1249}), ({'plug_in': 115, 'charge_end': 331, 'unplug': 346, 'wh': 4709, 'price_per_kwh': 52, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 3000, 'session_fee': 150, 'min_fee': 200}, {'energy': 245, 'idle': 0, 'total': 395}), ({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 490, 'charge_end': 569, 'unplug': 569, 'wh': 4974, 'price_per_kwh': 52, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 3000, 'session_fee': 100, 'min_fee': 300}, {'energy': 259, 'idle': 0, 'total': 359}), ({'plug_in': 157, 'charge_end': 214, 'unplug': 274, 'wh': 2276, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 500}, {'energy': 103, 'idle': 250, 'total': 503}), ({'plug_in': 230, 'charge_end': 290, 'unplug': 306, 'wh': 27281, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 3000, 'session_fee': 150, 'min_fee': 300}, {'energy': 1228, 'idle': 100, 'total': 1478})], [({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 361, 'charge_end': 626, 'unplug': 626, 'wh': 29818, 'price_per_kwh': 52, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 150, 'min_fee': 300}, {'energy': 1551, 'idle': 0, 'total': 1701}), ({'plug_in': 58, 'charge_end': 244, 'unplug': 260, 'wh': 4184, 'price_per_kwh': 45, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 3000, 'session_fee': 100, 'min_fee': 300}, {'energy': 189, 'idle': 100, 'total': 389}), ({'plug_in': 34, 'charge_end': 215, 'unplug': 215, 'wh': 13150, 'price_per_kwh': 35, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 100, 'min_fee': 500}, {'energy': 461, 'idle': 0, 'total': 561}), ({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024}), ({'plug_in': 437, 'charge_end': 628, 'unplug': 628, 'wh': 6615, 'price_per_kwh': 45, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 298, 'idle': 0, 'total': 398}), ({'plug_in': 86, 'charge_end': 283, 'unplug': 288, 'wh': 13385, 'price_per_kwh': 52, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 697, 'idle': 0, 'total': 697}), ({'plug_in': 433, 'charge_end': 493, 'unplug': 893, 'wh': 1131, 'price_per_kwh': 45, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 2000, 'session_fee': 0, 'min_fee': 200}, {'energy': 51, 'idle': 1560, 'total': 1611})], [({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024}), ({'plug_in': 63, 'charge_end': 346, 'unplug': 406, 'wh': 5005, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 3000, 'session_fee': 150, 'min_fee': 500}, {'energy': 176, 'idle': 250, 'total': 576}), ({'plug_in': 197, 'charge_end': 253, 'unplug': 263, 'wh': 7897, 'price_per_kwh': 45, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 3000, 'session_fee': 100, 'min_fee': 500}, {'energy': 356, 'idle': 0, 'total': 500}), ({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 484, 'charge_end': 672, 'unplug': 682, 'wh': 3159, 'price_per_kwh': 52, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 3000, 'session_fee': 150, 'min_fee': 200}, {'energy': 165, 'idle': 0, 'total': 315}), ({'plug_in': 540, 'charge_end': 691, 'unplug': 691, 'wh': 40240, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 3000, 'session_fee': 150, 'min_fee': 300}, {'energy': 1409, 'idle': 0, 'total': 1559}), ({'plug_in': 530, 'charge_end': 706, 'unplug': 722, 'wh': 19196, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 200}, {'energy': 557, 'idle': 100, 'total': 757}), ({'plug_in': 103, 'charge_end': 177, 'unplug': 377, 'wh': 8629, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 40, 'idle_cap': 3000, 'session_fee': 0, 'min_fee': 500}, {'energy': 389, 'idle': 760, 'total': 1149})], [({'plug_in': 537, 'charge_end': 679, 'unplug': 704, 'wh': 2203, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 64, 'idle': 200, 'total': 364}), ({'plug_in': 358, 'charge_end': 474, 'unplug': 484, 'wh': 14178, 'price_per_kwh': 29, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 2000, 'session_fee': 150, 'min_fee': 500}, {'energy': 412, 'idle': 0, 'total': 562}), ({'plug_in': 193, 'charge_end': 361, 'unplug': 386, 'wh': 58152, 'price_per_kwh': 52, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 300}, {'energy': 3024, 'idle': 40, 'total': 3064}), ({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 80, 'charge_end': 341, 'unplug': 346, 'wh': 6794, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 500}, {'energy': 238, 'idle': 0, 'total': 500}), ({'plug_in': 473, 'charge_end': 503, 'unplug': 519, 'wh': 7069, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 3000, 'session_fee': 0, 'min_fee': 500}, {'energy': 319, 'idle': 100, 'total': 500}), ({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024}), ({'plug_in': 411, 'charge_end': 481, 'unplug': 541, 'wh': 51535, 'price_per_kwh': 52, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 3000, 'session_fee': 150, 'min_fee': 500}, {'energy': 2680, 'idle': 250, 'total': 3080})]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    energy = -(-x['wh'] * x['price_per_kwh'] // 1000)
    idle = max(0, x['unplug'] - x['charge_end'] - x['idle_grace'])
    idle_fee = min(x['idle_cap'], -(-idle // 10) * x['idle_rate'])
    total = x['session_fee'] + energy + idle_fee
    return {'energy': energy, 'idle': idle_fee, 'total': max(x['min_fee'], energy) + x['session_fee'] + idle_fee}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 93, 'charge_end': 112, 'unplug': 312, 'wh': 46598, 'price_per_kwh': 35, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 2000, 'session_fee': 0, 'min_fee': 500}, {'energy': 1631, 'idle': 1900, 'total': 3531}), ({'plug_in': 548, 'charge_end': 701, 'unplug': 706, 'wh': 9990, 'price_per_kwh': 29, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 3000, 'session_fee': 150, 'min_fee': 500}, {'energy': 290, 'idle': 0, 'total': 500}), ({'plug_in': 502, 'charge_end': 683, 'unplug': 698, 'wh': 5462, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 300}, {'energy': 246, 'idle': 50, 'total': 300}), ({'plug_in': 119, 'charge_end': 199, 'unplug': 215, 'wh': 5114, 'price_per_kwh': 29, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 3000, 'session_fee': 100, 'min_fee': 500}, {'energy': 149, 'idle': 100, 'total': 500}), ({'plug_in': 74, 'charge_end': 111, 'unplug': 171, 'wh': 4221, 'price_per_kwh': 29, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 3000, 'session_fee': 150, 'min_fee': 500}, {'energy': 123, 'idle': 200, 'total': 500}), ({'plug_in': 585, 'charge_end': 800, 'unplug': 810, 'wh': 39441, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 2000, 'session_fee': 0, 'min_fee': 500}, {'energy': 1381, 'idle': 0, 'total': 1381}), ({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024})], [({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024}), ({'plug_in': 4, 'charge_end': 296, 'unplug': 312, 'wh': 3717, 'price_per_kwh': 52, 'idle_grace': 10, 'idle_rate': 40, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 500}, {'energy': 194, 'idle': 40, 'total': 500}), ({'plug_in': 73, 'charge_end': 83, 'unplug': 283, 'wh': 4230, 'price_per_kwh': 35, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 100, 'min_fee': 200}, {'energy': 149, 'idle': 1000, 'total': 1249}), ({'plug_in': 115, 'charge_end': 331, 'unplug': 346, 'wh': 4709, 'price_per_kwh': 52, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 3000, 'session_fee': 150, 'min_fee': 200}, {'energy': 245, 'idle': 0, 'total': 395}), ({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 490, 'charge_end': 569, 'unplug': 569, 'wh': 4974, 'price_per_kwh': 52, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 3000, 'session_fee': 100, 'min_fee': 300}, {'energy': 259, 'idle': 0, 'total': 359}), ({'plug_in': 157, 'charge_end': 214, 'unplug': 274, 'wh': 2276, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 50, 'idle_cap': 1000, 'session_fee': 150, 'min_fee': 500}, {'energy': 103, 'idle': 250, 'total': 503}), ({'plug_in': 230, 'charge_end': 290, 'unplug': 306, 'wh': 27281, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 3000, 'session_fee': 150, 'min_fee': 300}, {'energy': 1228, 'idle': 100, 'total': 1478})], [({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 361, 'charge_end': 626, 'unplug': 626, 'wh': 29818, 'price_per_kwh': 52, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 150, 'min_fee': 300}, {'energy': 1551, 'idle': 0, 'total': 1701}), ({'plug_in': 58, 'charge_end': 244, 'unplug': 260, 'wh': 4184, 'price_per_kwh': 45, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 3000, 'session_fee': 100, 'min_fee': 300}, {'energy': 189, 'idle': 100, 'total': 389}), ({'plug_in': 34, 'charge_end': 215, 'unplug': 215, 'wh': 13150, 'price_per_kwh': 35, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 100, 'min_fee': 500}, {'energy': 461, 'idle': 0, 'total': 561}), ({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024}), ({'plug_in': 437, 'charge_end': 628, 'unplug': 628, 'wh': 6615, 'price_per_kwh': 45, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 298, 'idle': 0, 'total': 398}), ({'plug_in': 86, 'charge_end': 283, 'unplug': 288, 'wh': 13385, 'price_per_kwh': 52, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 697, 'idle': 0, 'total': 697}), ({'plug_in': 433, 'charge_end': 493, 'unplug': 893, 'wh': 1131, 'price_per_kwh': 45, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 2000, 'session_fee': 0, 'min_fee': 200}, {'energy': 51, 'idle': 1560, 'total': 1611})], [({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024}), ({'plug_in': 63, 'charge_end': 346, 'unplug': 406, 'wh': 5005, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 3000, 'session_fee': 150, 'min_fee': 500}, {'energy': 176, 'idle': 250, 'total': 576}), ({'plug_in': 197, 'charge_end': 253, 'unplug': 263, 'wh': 7897, 'price_per_kwh': 45, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 3000, 'session_fee': 100, 'min_fee': 500}, {'energy': 356, 'idle': 0, 'total': 500}), ({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 484, 'charge_end': 672, 'unplug': 682, 'wh': 3159, 'price_per_kwh': 52, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 3000, 'session_fee': 150, 'min_fee': 200}, {'energy': 165, 'idle': 0, 'total': 315}), ({'plug_in': 540, 'charge_end': 691, 'unplug': 691, 'wh': 40240, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 3000, 'session_fee': 150, 'min_fee': 300}, {'energy': 1409, 'idle': 0, 'total': 1559}), ({'plug_in': 530, 'charge_end': 706, 'unplug': 722, 'wh': 19196, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 200}, {'energy': 557, 'idle': 100, 'total': 757}), ({'plug_in': 103, 'charge_end': 177, 'unplug': 377, 'wh': 8629, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 40, 'idle_cap': 3000, 'session_fee': 0, 'min_fee': 500}, {'energy': 389, 'idle': 760, 'total': 1149})], [({'plug_in': 537, 'charge_end': 679, 'unplug': 704, 'wh': 2203, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 64, 'idle': 200, 'total': 364}), ({'plug_in': 358, 'charge_end': 474, 'unplug': 484, 'wh': 14178, 'price_per_kwh': 29, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 2000, 'session_fee': 150, 'min_fee': 500}, {'energy': 412, 'idle': 0, 'total': 562}), ({'plug_in': 193, 'charge_end': 361, 'unplug': 386, 'wh': 58152, 'price_per_kwh': 52, 'idle_grace': 15, 'idle_rate': 40, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 300}, {'energy': 3024, 'idle': 40, 'total': 3064}), ({'plug_in': 0, 'charge_end': 90, 'unplug': 106, 'wh': 12500, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 300}, {'energy': 438, 'idle': 50, 'total': 588}), ({'plug_in': 80, 'charge_end': 341, 'unplug': 346, 'wh': 6794, 'price_per_kwh': 35, 'idle_grace': 15, 'idle_rate': 100, 'idle_cap': 2000, 'session_fee': 100, 'min_fee': 500}, {'energy': 238, 'idle': 0, 'total': 500}), ({'plug_in': 473, 'charge_end': 503, 'unplug': 519, 'wh': 7069, 'price_per_kwh': 45, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 3000, 'session_fee': 0, 'min_fee': 500}, {'energy': 319, 'idle': 100, 'total': 500}), ({'plug_in': 30, 'charge_end': 45, 'unplug': 400, 'wh': 800, 'price_per_kwh': 29, 'idle_grace': 10, 'idle_rate': 100, 'idle_cap': 1000, 'session_fee': 0, 'min_fee': 500}, {'energy': 24, 'idle': 1000, 'total': 1024}), ({'plug_in': 411, 'charge_end': 481, 'unplug': 541, 'wh': 51535, 'price_per_kwh': 52, 'idle_grace': 15, 'idle_rate': 50, 'idle_cap': 3000, 'session_fee': 150, 'min_fee': 500}, {'energy': 2680, 'idle': 250, 'total': 3080})]]
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)

prompt:
EV charging session and idle fee returns a wrong result when the minimum applies only to the energy charge.

Input {plug_in, charge_end, unplug (minutes), wh, price_per_kwh, idle_grace, idle_rate (per started 10 min), idle_cap, session_fee, min_fee}. Energy = ceil(wh*price/1000). Idle minutes = max(0, unplug - charge_end - grace); idle fee = min(idle_cap, started 10-minute blocks * idle_rate). Total = max(min_fee, session_fee + energy + idle). Return {energy, idle, total}.

split: open-access


prompt:
Open-road gantry trip building returns a wrong result when duplicates are only detected between consecutive reads.

Input {reads: [[minute, gantry, direction]] unordered, dedupe, max_gap, price per gantry, trip_cap}. Reads are sorted; a read of the same gantry within dedupe minutes (inclusive) of the last kept read of that gantry is dropped. Kept reads join the current trip when the direction matches and the gap from the trip's latest read is <= max_gap, else start a new trip. Each trip pays min(trip_cap, sum of its gantry prices). Return [trips, total].

split: open-access


prompt:
Open-road gantry trip building returns a wrong result when dropped duplicates re-anchor the duplicate window.

Input {reads: [[minute, gantry, direction]] unordered, dedupe, max_gap, price per gantry, trip_cap}. Reads are sorted; a read of the same gantry within dedupe minutes (inclusive) of the last kept read of that gantry is dropped. Kept reads join the current trip when the direction matches and the gap from the trip's latest read is <= max_gap, else start a new trip. Each trip pays min(trip_cap, sum of its gantry prices). Return [trips, total].

split: open-access


prompt:
Open-road gantry trip building returns a wrong result when the trip gap is measured from the first read of the trip.

Input {reads: [[minute, gantry, direction]] unordered, dedupe, max_gap, price per gantry, trip_cap}. Reads are sorted; a read of the same gantry within dedupe minutes (inclusive) of the last kept read of that gantry is dropped. Kept reads join the current trip when the direction matches and the gap from the trip's latest read is <= max_gap, else start a new trip. Each trip pays min(trip_cap, sum of its gantry prices). Return [trips, total].

split: open-access


prompt:
Open-road gantry trip building returns a wrong result when direction changes do not start a new trip.

Input {reads: [[minute, gantry, direction]] unordered, dedupe, max_gap, price per gantry, trip_cap}. Reads are sorted; a read of the same gantry within dedupe minutes (inclusive) of the last kept read of that gantry is dropped. Kept reads join the current trip when the direction matches and the gap from the trip's latest read is <= max_gap, else start a new trip. Each trip pays min(trip_cap, sum of its gantry prices). Return [trips, total].

split: open-access


prompt:
Open-road gantry trip building returns a wrong result when a gap exactly equal to the maximum splits the trip.

Input {reads: [[minute, gantry, direction]] unordered, dedupe, max_gap, price per gantry, trip_cap}. Reads are sorted; a read of the same gantry within dedupe minutes (inclusive) of the last kept read of that gantry is dropped. Kept reads join the current trip when the direction matches and the gap from the trip's latest read is <= max_gap, else start a new trip. Each trip pays min(trip_cap, sum of its gantry prices). Return [trips, total].

split: open-access


prompt:
Open-road gantry trip building returns a wrong result when the cap is applied to the whole statement.

Input {reads: [[minute, gantry, direction]] unordered, dedupe, max_gap, price per gantry, trip_cap}. Reads are sorted; a read of the same gantry within dedupe minutes (inclusive) of the last kept read of that gantry is dropped. Kept reads join the current trip when the direction matches and the gap from the trip's latest read is <= max_gap, else start a new trip. Each trip pays min(trip_cap, sum of its gantry prices). Return [trips, total].

split: open-access


prompt:
Open-road gantry trip building returns a wrong result when reads are sorted by gantry.

Input {reads: [[minute, gantry, direction]] unordered, dedupe, max_gap, price per gantry, trip_cap}. Reads are sorted; a read of the same gantry within dedupe minutes (inclusive) of the last kept read of that gantry is dropped. Kept reads join the current trip when the direction matches and the gap from the trip's latest read is <= max_gap, else start a new trip. Each trip pays min(trip_cap, sum of its gantry prices). Return [trips, total].

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
N = 1
observations = []
def solve(x):
    occ = x['occupancy']
    if len(occ) < x['min_samples']:
        return x['rate']
    avg = sum(occ) // len(occ)
    r = x['rate']
    if avg > x['hi']:
        r += x['step']
    elif avg < x['lo']:
        r -= x['step']
    return max(x['min_rate'], min(x['max_rate'], r))
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'rate': 500, 'occupancy': [40, 81, 81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 700, 'min_samples': 3}, 500), ({'rate': 575, 'occupancy': [], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 600, 'min_samples': 3}, 575), ({'rate': 300, 'occupancy': [80, 80], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300), ({'rate': 300, 'occupancy': [60, 60, 60], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300), ({'rate': 325, 'occupancy': [80, 81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 700, 'min_samples': 2}, 350), ({'rate': 300, 'occupancy': [80, 81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 325), ({'rate': 375, 'occupancy': [80, 81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 700, 'min_samples': 2}, 400), ({'rate': 575, 'occupancy': [60, 59], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 700, 'min_samples': 2}, 550)], [({'rate': 300, 'occupancy': [], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 700, 'min_samples': 3}, 300), ({'rate': 725, 'occupancy': [], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 725), ({'rate': 325, 'occupancy': [81, 80], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 350), ({'rate': 300, 'occupancy': [80, 80], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300), ({'rate': 200, 'occupancy': [81, 80, 59, 60, 60, 86], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 700, 'min_samples': 2}, 200), ({'rate': 300, 'occupancy': [60, 59], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 275), ({'rate': 300, 'occupancy': [80, 81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 325), ({'rate': 75, 'occupancy': [80, 81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 100)], [({'rate': 300, 'occupancy': [80, 81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 325), ({'rate': 800, 'occupancy': [70, 70, 70], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 3}, 600), ({'rate': 150, 'occupancy': [81, 80, 81, 80, 80, 80], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 700, 'min_samples': 2}, 200), ({'rate': 300, 'occupancy': [60, 60, 60], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300), ({'rate': 300, 'occupancy': [90, 90], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 325), ({'rate': 375, 'occupancy': [59, 60], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 600, 'min_samples': 2}, 350), ({'rate': 350, 'occupancy': [81, 80, 80, 80], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 700, 'min_samples': 3}, 400), ({'rate': 500, 'occupancy': [59, 60], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 450)], [({'rate': 425, 'occupancy': [81, 80], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 600, 'min_samples': 2}, 475), ({'rate': 450, 'occupancy': [81, 94, 81, 67, 81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 600, 'min_samples': 2}, 475), ({'rate': 300, 'occupancy': [60, 59], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 275), ({'rate': 300, 'occupancy': [90, 90], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 325), ({'rate': 175, 'occupancy': [], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 700, 'min_samples': 2}, 175), ({'rate': 225, 'occupancy': [80, 80, 81, 80], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 700, 'min_samples': 3}, 250), ({'rate': 800, 'occupancy': [70, 70, 70], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 3}, 600), ({'rate': 125, 'occupancy': [59, 60, 60], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 700, 'min_samples': 3}, 100)], [({'rate': 500, 'occupancy': [81, 80], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 525), ({'rate': 300, 'occupancy': [90, 90], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 325), ({'rate': 300, 'occupancy': [80, 80], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300), ({'rate': 150, 'occupancy': [81, 80], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 600, 'min_samples': 2}, 200), ({'rate': 275, 'occupancy': [59, 60], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 250), ({'rate': 650, 'occupancy': [80, 80, 81, 81], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 700, 'min_samples': 2}, 700), ({'rate': 475, 'occupancy': [60, 80, 81], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 475), ({'rate': 300, 'occupancy': [60, 59], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 275)]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
N = 1
observations = []
def solve(x):
    occ = x['occupancy']
    if len(occ) < x['min_samples']:
        return x['rate']
    avg = round(sum(occ) / len(occ))
    r = x['rate']
    if avg > x['hi']:
        r += x['step']
    elif avg < x['lo']:
        r -= x['step']
    return max(x['min_rate'], min(x['max_rate'], r))
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'rate': 500, 'occupancy': [40, 81, 81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 700, 'min_samples': 3}, 500), ({'rate': 575, 'occupancy': [], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 600, 'min_samples': 3}, 575), ({'rate': 300, 'occupancy': [80, 80], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300), ({'rate': 300, 'occupancy': [60, 60, 60], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300), ({'rate': 325, 'occupancy': [80, 81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 700, 'min_samples': 2}, 350), ({'rate': 300, 'occupancy': [80, 81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 325), ({'rate': 375, 'occupancy': [80, 81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 700, 'min_samples': 2}, 400), ({'rate': 575, 'occupancy': [60, 59], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 700, 'min_samples': 2}, 550)], [({'rate': 300, 'occupancy': [], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 700, 'min_samples': 3}, 300), ({'rate': 725, 'occupancy': [], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 725), ({'rate': 325, 'occupancy': [81, 80], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 350), ({'rate': 300, 'occupancy': [80, 80], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300), ({'rate': 200, 'occupancy': [81, 80, 59, 60, 60, 86], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 700, 'min_samples': 2}, 200), ({'rate': 300, 'occupancy': [60, 59], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 275), ({'rate': 300, 'occupancy': [80, 81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 325), ({'rate': 75, 'occupancy': [80, 81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 100)], [({'rate': 300, 'occupancy': [80, 81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 325), ({'rate': 800, 'occupancy': [70, 70, 70], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 3}, 600), ({'rate': 150, 'occupancy': [81, 80, 81, 80, 80, 80], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 700, 'min_samples': 2}, 200), ({'rate': 300, 'occupancy': [60, 60, 60], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300), ({'rate': 300, 'occupancy': [90, 90], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 325), ({'rate': 375, 'occupancy': [59, 60], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 600, 'min_samples': 2}, 350), ({'rate': 350, 'occupancy': [81, 80, 80, 80], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 700, 'min_samples': 3}, 400), ({'rate': 500, 'occupancy': [59, 60], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 450)], [({'rate': 425, 'occupancy': [81, 80], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 600, 'min_samples': 2}, 475), ({'rate': 450, 'occupancy': [81, 94, 81, 67, 81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 600, 'min_samples': 2}, 475), ({'rate': 300, 'occupancy': [60, 59], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 275), ({'rate': 300, 'occupancy': [90, 90], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 325), ({'rate': 175, 'occupancy': [], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 700, 'min_samples': 2}, 175), ({'rate': 225, 'occupancy': [80, 80, 81, 80], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 700, 'min_samples': 3}, 250), ({'rate': 800, 'occupancy': [70, 70, 70], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 3}, 600), ({'rate': 125, 'occupancy': [59, 60, 60], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 700, 'min_samples': 3}, 100)], [({'rate': 500, 'occupancy': [81, 80], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 525), ({'rate': 300, 'occupancy': [90, 90], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 325), ({'rate': 300, 'occupancy': [80, 80], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300), ({'rate': 150, 'occupancy': [81, 80], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 600, 'min_samples': 2}, 200), ({'rate': 275, 'occupancy': [59, 60], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 250), ({'rate': 650, 'occupancy': [80, 80, 81, 81], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 700, 'min_samples': 2}, 700), ({'rate': 475, 'occupancy': [60, 80, 81], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 475), ({'rate': 300, 'occupancy': [60, 59], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 275)]]
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)

prompt:
Demand-responsive meter rate adjustment returns a wrong result when the mean occupancy is truncated.

Input {rate, occupancy: hourly percentages, hi, lo, step, min_rate, max_rate, min_samples}. With fewer than min_samples samples the rate is unchanged. Otherwise the exact mean occupancy above hi raises the rate by step, below lo lowers it by step; the result is always clamped to [min_rate, max_rate].

split: open-access


prompt:
Demand-responsive meter rate adjustment returns a wrong result when the upper band uses the peak hour.

Input {rate, occupancy: hourly percentages, hi, lo, step, min_rate, max_rate, min_samples}. With fewer than min_samples samples the rate is unchanged. Otherwise the exact mean occupancy above hi raises the rate by step, below lo lowers it by step; the result is always clamped to [min_rate, max_rate].

split: open-access


prompt:
Demand-responsive meter rate adjustment returns a wrong result when the lower band uses the quietest hour.

Input {rate, occupancy: hourly percentages, hi, lo, step, min_rate, max_rate, min_samples}. With fewer than min_samples samples the rate is unchanged. Otherwise the exact mean occupancy above hi raises the rate by step, below lo lowers it by step; the result is always clamped to [min_rate, max_rate].

split: open-access


source:
"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
N = 1
observations = []
def solve(x):
    occ = x['occupancy']
    if len(occ) < x['min_samples']:
        return x['rate']
    avg = Fraction(sum(occ), len(occ))
    r = x['rate']
    if avg > x['hi']:
        r += x['step']
    elif avg < x['lo']:
        r -= x['step']
    return max(x['min_rate'], min(x['max_rate'], r)) if r != x['rate'] else x['rate']
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'rate': 300, 'occupancy': [80, 80], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300), ({'rate': 800, 'occupancy': [70, 70, 70], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 3}, 600), ({'rate': 25, 'occupancy': [59, 81, 60, 80, 81, 81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 50), ({'rate': 300, 'occupancy': [80, 81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 325), ({'rate': 50, 'occupancy': [80, 60, 81, 80], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 700, 'min_samples': 2}, 100), ({'rate': 75, 'occupancy': [60, 59, 81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 700, 'min_samples': 2}, 100), ({'rate': 350, 'occupancy': [81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 700, 'min_samples': 2}, 350), ({'rate': 550, 'occupancy': [59, 59, 80, 90, 81], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 600, 'min_samples': 3}, 550)], [({'rate': 125, 'occupancy': [59, 87], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 700, 'min_samples': 3}, 125), ({'rate': 25, 'occupancy': [80, 45, 59, 59, 59, 60], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 600, 'min_samples': 3}, 50), ({'rate': 800, 'occupancy': [60, 80, 60, 60], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 600, 'min_samples': 3}, 600), ({'rate': 75, 'occupancy': [60, 59], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 600, 'min_samples': 2}, 100), ({'rate': 800, 'occupancy': [70, 70, 70], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 3}, 600), ({'rate': 300, 'occupancy': [80, 80], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300), ({'rate': 300, 'occupancy': [60, 60, 60], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300), ({'rate': 50, 'occupancy': [80, 81, 81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 700, 'min_samples': 2}, 100)], [({'rate': 200, 'occupancy': [80], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 600, 'min_samples': 2}, 200), ({'rate': 75, 'occupancy': [96, 60, 81, 59, 59, 60], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 600, 'min_samples': 3}, 100), ({'rate': 300, 'occupancy': [80, 81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 325), ({'rate': 300, 'occupancy': [80, 80], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300), ({'rate': 25, 'occupancy': [54, 42, 60, 60], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 600, 'min_samples': 3}, 50), ({'rate': 300, 'occupancy': [60, 59], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 275), ({'rate': 650, 'occupancy': [80, 59, 60, 81, 59, 81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 600, 'min_samples': 2}, 600), ({'rate': 75, 'occupancy': [81, 80, 80, 81, 60], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 600, 'min_samples': 2}, 100)], [({'rate': 275, 'occupancy': [54, 59, 81, 60], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 600, 'min_samples': 3}, 275), ({'rate': 625, 'occupancy': [80, 85, 80, 60, 74], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 3}, 600), ({'rate': 25, 'occupancy': [80, 80, 60, 74, 80], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 700, 'min_samples': 2}, 50), ({'rate': 75, 'occupancy': [81, 72], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 600, 'min_samples': 2}, 100), ({'rate': 25, 'occupancy': [52, 81, 60, 60, 60], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 600, 'min_samples': 2}, 100), ({'rate': 300, 'occupancy': [80, 81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 325), ({'rate': 300, 'occupancy': [80, 80], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300), ({'rate': 300, 'occupancy': [90, 90], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 325)], [({'rate': 300, 'occupancy': [60, 59], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 275), ({'rate': 800, 'occupancy': [70, 70, 70], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 3}, 600), ({'rate': 300, 'occupancy': [80, 81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 325), ({'rate': 650, 'occupancy': [68, 80, 80, 75, 59], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 3}, 600), ({'rate': 25, 'occupancy': [60, 59], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 600, 'min_samples': 2}, 100), ({'rate': 475, 'occupancy': [80, 81, 81], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 700, 'min_samples': 2}, 525), ({'rate': 25, 'occupancy': [59, 60, 59, 60, 81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 700, 'min_samples': 2}, 50), ({'rate': 25, 'occupancy': [81, 81, 81, 59, 59], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 600, 'min_samples': 2}, 100)]]
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)

prompt:
Demand-responsive meter rate adjustment returns a wrong result when unchanged rates are not clamped.

Input {rate, occupancy: hourly percentages, hi, lo, step, min_rate, max_rate, min_samples}. With fewer than min_samples samples the rate is unchanged. Otherwise the exact mean occupancy above hi raises the rate by step, below lo lowers it by step; the result is always clamped to [min_rate, max_rate].

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
N = 1
observations = []
def solve(x):
    occ = x['occupancy']
    if not occ:
        return x['rate']
    avg = Fraction(sum(occ), len(occ))
    r = x['rate']
    if avg > x['hi']:
        r += x['step']
    elif avg < x['lo']:
        r -= x['step']
    return max(x['min_rate'], min(x['max_rate'], r))
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'rate': 300, 'occupancy': [60, 59], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 275), ({'rate': 225, 'occupancy': [59], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 600, 'min_samples': 2}, 225), ({'rate': 125, 'occupancy': [], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 700, 'min_samples': 2}, 125), ({'rate': 300, 'occupancy': [60, 60, 60], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300), ({'rate': 400, 'occupancy': [81, 81], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 700, 'min_samples': 2}, 450), ({'rate': 800, 'occupancy': [80], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 800), ({'rate': 800, 'occupancy': [81, 81], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 700, 'min_samples': 3}, 800), ({'rate': 300, 'occupancy': [80, 80], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300)], [({'rate': 300, 'occupancy': [80, 80], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300), ({'rate': 300, 'occupancy': [60, 60, 60], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300), ({'rate': 400, 'occupancy': [80, 60, 60, 63, 99, 81], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 400), ({'rate': 300, 'occupancy': [90, 90], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 325), ({'rate': 50, 'occupancy': [80, 81], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 600, 'min_samples': 3}, 50), ({'rate': 350, 'occupancy': [59, 60], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 600, 'min_samples': 2}, 325), ({'rate': 75, 'occupancy': [59], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 700, 'min_samples': 2}, 75), ({'rate': 775, 'occupancy': [59, 80], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 600, 'min_samples': 3}, 775)], [({'rate': 300, 'occupancy': [60, 60, 60], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300), ({'rate': 125, 'occupancy': [81], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 700, 'min_samples': 3}, 125), ({'rate': 725, 'occupancy': [], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 700, 'min_samples': 3}, 725), ({'rate': 300, 'occupancy': [60, 59], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 275), ({'rate': 400, 'occupancy': [59], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 600, 'min_samples': 3}, 400), ({'rate': 525, 'occupancy': [60, 59, 80, 81, 66], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 700, 'min_samples': 3}, 525), ({'rate': 175, 'occupancy': [81], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 700, 'min_samples': 3}, 175), ({'rate': 300, 'occupancy': [90, 90], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 325)], [({'rate': 300, 'occupancy': [60, 60, 60], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300), ({'rate': 150, 'occupancy': [81], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 700, 'min_samples': 3}, 150), ({'rate': 775, 'occupancy': [97, 60, 81], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 600, 'min_samples': 3}, 600), ({'rate': 650, 'occupancy': [59], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 600, 'min_samples': 3}, 650), ({'rate': 300, 'occupancy': [80, 80], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300), ({'rate': 300, 'occupancy': [60, 59], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 275), ({'rate': 725, 'occupancy': [59], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 700, 'min_samples': 2}, 725), ({'rate': 325, 'occupancy': [83, 60], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 600, 'min_samples': 3}, 325)], [({'rate': 425, 'occupancy': [59], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 600, 'min_samples': 3}, 425), ({'rate': 800, 'occupancy': [70, 70, 70], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 3}, 600), ({'rate': 475, 'occupancy': [59, 71, 81, 59, 80], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 700, 'min_samples': 2}, 475), ({'rate': 200, 'occupancy': [59], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 700, 'min_samples': 2}, 200), ({'rate': 375, 'occupancy': [60, 81, 81], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 600, 'min_samples': 2}, 375), ({'rate': 350, 'occupancy': [81, 59, 80], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 700, 'min_samples': 2}, 350), ({'rate': 300, 'occupancy': [80, 81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 325), ({'rate': 25, 'occupancy': [61], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 700, 'min_samples': 2}, 25)]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
N = 1
observations = []
def solve(x):
    occ = x['occupancy']
    if len(occ) <= x['min_samples']:
        return x['rate']
    avg = Fraction(sum(occ), len(occ))
    r = x['rate']
    if avg > x['hi']:
        r += x['step']
    elif avg < x['lo']:
        r -= x['step']
    return max(x['min_rate'], min(x['max_rate'], r))
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[({'rate': 300, 'occupancy': [60, 59], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 275), ({'rate': 225, 'occupancy': [59], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 600, 'min_samples': 2}, 225), ({'rate': 125, 'occupancy': [], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 700, 'min_samples': 2}, 125), ({'rate': 300, 'occupancy': [60, 60, 60], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300), ({'rate': 400, 'occupancy': [81, 81], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 700, 'min_samples': 2}, 450), ({'rate': 800, 'occupancy': [80], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 800), ({'rate': 800, 'occupancy': [81, 81], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 700, 'min_samples': 3}, 800), ({'rate': 300, 'occupancy': [80, 80], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300)], [({'rate': 300, 'occupancy': [80, 80], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300), ({'rate': 300, 'occupancy': [60, 60, 60], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300), ({'rate': 400, 'occupancy': [80, 60, 60, 63, 99, 81], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 400), ({'rate': 300, 'occupancy': [90, 90], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 325), ({'rate': 50, 'occupancy': [80, 81], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 600, 'min_samples': 3}, 50), ({'rate': 350, 'occupancy': [59, 60], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 600, 'min_samples': 2}, 325), ({'rate': 75, 'occupancy': [59], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 700, 'min_samples': 2}, 75), ({'rate': 775, 'occupancy': [59, 80], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 600, 'min_samples': 3}, 775)], [({'rate': 300, 'occupancy': [60, 60, 60], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300), ({'rate': 125, 'occupancy': [81], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 700, 'min_samples': 3}, 125), ({'rate': 725, 'occupancy': [], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 700, 'min_samples': 3}, 725), ({'rate': 300, 'occupancy': [60, 59], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 275), ({'rate': 400, 'occupancy': [59], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 600, 'min_samples': 3}, 400), ({'rate': 525, 'occupancy': [60, 59, 80, 81, 66], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 700, 'min_samples': 3}, 525), ({'rate': 175, 'occupancy': [81], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 700, 'min_samples': 3}, 175), ({'rate': 300, 'occupancy': [90, 90], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 325)], [({'rate': 300, 'occupancy': [60, 60, 60], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300), ({'rate': 150, 'occupancy': [81], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 700, 'min_samples': 3}, 150), ({'rate': 775, 'occupancy': [97, 60, 81], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 600, 'min_samples': 3}, 600), ({'rate': 650, 'occupancy': [59], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 600, 'min_samples': 3}, 650), ({'rate': 300, 'occupancy': [80, 80], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 300), ({'rate': 300, 'occupancy': [60, 59], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 275), ({'rate': 725, 'occupancy': [59], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 700, 'min_samples': 2}, 725), ({'rate': 325, 'occupancy': [83, 60], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 600, 'min_samples': 3}, 325)], [({'rate': 425, 'occupancy': [59], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 100, 'max_rate': 600, 'min_samples': 3}, 425), ({'rate': 800, 'occupancy': [70, 70, 70], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 3}, 600), ({'rate': 475, 'occupancy': [59, 71, 81, 59, 80], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 50, 'max_rate': 700, 'min_samples': 2}, 475), ({'rate': 200, 'occupancy': [59], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 700, 'min_samples': 2}, 200), ({'rate': 375, 'occupancy': [60, 81, 81], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 600, 'min_samples': 2}, 375), ({'rate': 350, 'occupancy': [81, 59, 80], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 700, 'min_samples': 2}, 350), ({'rate': 300, 'occupancy': [80, 81], 'hi': 80, 'lo': 60, 'step': 25, 'min_rate': 50, 'max_rate': 600, 'min_samples': 2}, 325), ({'rate': 25, 'occupancy': [61], 'hi': 80, 'lo': 60, 'step': 50, 'min_rate': 100, 'max_rate': 700, 'min_samples': 2}, 25)]]
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)

prompt:
Demand-responsive meter rate adjustment returns a wrong result when the sample guard only rejects empty data.

Input {rate, occupancy: hourly percentages, hi, lo, step, min_rate, max_rate, min_samples}. With fewer than min_samples samples the rate is unchanged. Otherwise the exact mean occupancy above hi raises the rate by step, below lo lowers it by step; the result is always clamped to [min_rate, max_rate].

split: open-access


prompt:
Airport parking weekly cap returns a wrong result when a partial day is counted as a full day before the weekly split.

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.

split: open-access


prompt:
Airport parking weekly cap returns a wrong result when the partial day is capped at the weekly rate.

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.

split: open-access


prompt:
Airport parking weekly cap returns a wrong result when the remainder is added outside the weekly cap.

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.

split: open-access