FA-92661 / HVAC thermostat control / Open access
Degree-minute integral is not clamped · case 01
After a long surplus the compressor takes a very long time to restart, and deep deficits wind up without bound.
ROOT CAUSE
The DM update has no floor or ceiling.
VERIFIED REPAIR
Clamp DM to [floor, 100] every minute.
Unsuccessful approach: Clamping only the floor still lets surplus wind up above 100.
Case contract
Hydronic heat pump degree-minute controller, one sample per minute of [supply_temp, target_supply] in whole F. Degree-minutes DM accumulate supply - target each minute and are clamped to [floor, 100]. The compressor starts when DM <= start_dm and stops when DM >= stop_dm. Auxiliary heat starts when DM <= aux_dm and stops when DM >= start_dm. Decisions use the DM value after this minute's update. Return [DM, compressor, aux] per minute.
Why this case matters
Residential and light-commercial thermostats make these decisions sample by sample; each defect changes equipment calls in a way that shows up as short cycling, comfort complaints or equipment stress.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(settings, samples):
dm = 0
comp = False
aux = False
out = []
for supply, target in samples:
dm = dm + supply - target
if comp and dm >= settings['stop_dm']:
comp = False
elif not comp and dm <= settings['start_dm']:
comp = True
if aux and dm >= settings['start_dm']:
aux = False
elif not aux and dm <= settings['aux_dm']:
aux = True
out.append([dm, comp, aux])
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: long surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40]]],
[[30, False, False],
[60, False, False],
[90, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[80, False, False],
[60, False, False],
[40, False, False],
[20, False, False],
[0, False, False]]],
['regression: scenario 1',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -400},
[[11, 40],
[50, 40],
[49, 40],
[53, 40],
[49, 40],
[71, 40],
[105, 40],
[100, 40],
[17, 40],
[13, 40],
[102, 40],
[102, 40],
[99, 40],
[105, 40],
[96, 40],
[50, 40],
[48, 40],
[46, 40],
[47, 40],
[50, 40],
[52, 40],
[48, 40],
[71, 40]]],
[[-29, False, False],
[-19, False, False],
[-10, False, False],
[3, False, False],
[12, False, False],
[43, False, False],
[100, False, False],
[100, False, False],
[77, False, False],
[50, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['control: deficit and recovery',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40]]],
[[-20, False, False],
[-40, False, False],
[-60, True, False],
[-80, True, False],
[-100, True, True],
[-120, True, True],
[-140, True, True],
[-120, True, True],
[-100, True, True],
[-80, True, True],
[-60, True, False],
[-40, True, False],
[-20, True, False],
[0, False, False]]],
['regression: deep deficit floor',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [80, 40], [80, 40], [80, 40], [80, 40]]],
[[-40, False, False],
[-80, True, False],
[-120, True, True],
[-150, True, True],
[-150, True, True],
[-150, True, True],
[-110, True, True],
[-70, True, True],
[-30, True, False],
[10, False, False]]],
['control: start then immediate surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [20, 40], [70, 40], [70, 40], [45, 40]]],
[[-40, False, False], [-60, True, False], [-30, True, False], [0, False, False], [5, False, False]]],
['regression: scenario 2',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -300, 'floor': -250},
[[67, 40],
[67, 40],
[73, 40],
[71, 40],
[11, 40],
[19, 40],
[69, 40],
[70, 40],
[65, 40],
[70, 40],
[66, 40],
[66, 40],
[71, 40],
[68, 40],
[70, 40],
[73, 40],
[74, 40],
[73, 40],
[65, 40],
[75, 40],
[104, 40]]],
[[27, False, False],
[54, False, False],
[87, False, False],
[100, False, False],
[71, False, False],
[50, False, False],
[79, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['regression: scenario 3',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -300, 'floor': -400},
[[71, 40],
[75, 40],
[72, 40],
[68, 40],
[75, 40],
[48, 40],
[45, 40],
[30, 40],
[18, 40],
[19, 40],
[12, 40],
[16, 40],
[10, 40],
[18, 40],
[18, 40],
[18, 40],
[72, 40],
[20, 40],
[20, 40],
[17, 40]]],
[[31, False, False],
[66, False, False],
[98, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[90, False, False],
[68, False, False],
[47, False, False],
[19, False, False],
[-5, False, False],
[-35, False, False],
[-57, False, False],
[-79, True, False],
[-101, True, False],
[-69, True, False],
[-89, True, False],
[-109, True, False],
[-132, True, False]]],
['regression: scenario 4',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -250},
[[27, 40],
[23, 40],
[28, 40],
[67, 40],
[96, 40],
[101, 40],
[18, 40],
[11, 40],
[16, 40],
[18, 40],
[13, 40],
[16, 40],
[18, 40],
[16, 40],
[17, 40],
[10, 40],
[15, 40]]],
[[-13, False, False],
[-30, False, False],
[-42, False, False],
[-15, False, False],
[41, False, False],
[100, False, False],
[78, False, False],
[49, False, False],
[25, False, False],
[3, False, False],
[-24, False, False],
[-48, False, False],
[-70, True, False],
[-94, True, False],
[-117, True, False],
[-147, True, False],
[-172, True, True]]]],
[['regression: deep deficit floor',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [80, 40], [80, 40], [80, 40], [80, 40]]],
[[-40, False, False],
[-80, True, False],
[-120, True, True],
[-150, True, True],
[-150, True, True],
[-150, True, True],
[-110, True, True],
[-70, True, True],
[-30, True, False],
[10, False, False]]],
['regression: scenario 1',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -300, 'floor': -250},
[[57, 40],
[101, 40],
[100, 40],
[98, 40],
[95, 40],
[100, 40],
[101, 40],
[103, 40],
[96, 40],
[97, 40],
[14, 40],
[17, 40],
[12, 40],
[20, 40],
[13, 40]]],
[[17, False, False],
[78, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[74, False, False],
[51, False, False],
[23, False, False],
[3, False, False],
[-24, False, False]]],
['control: deficit and recovery',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40]]],
[[-20, False, False],
[-40, False, False],
[-60, True, False],
[-80, True, False],
[-100, True, True],
[-120, True, True],
[-140, True, True],
[-120, True, True],
[-100, True, True],
[-80, True, True],
[-60, True, False],
[-40, True, False],
[-20, True, False],
[0, False, False]]],
['regression: long surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40]]],
[[30, False, False],
[60, False, False],
[90, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[80, False, False],
[60, False, False],
[40, False, False],
[20, False, False],
[0, False, False]]],
['control: start then immediate surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [20, 40], [70, 40], [70, 40], [45, 40]]],
[[-40, False, False], [-60, True, False], [-30, True, False], [0, False, False], [5, False, False]]],
['control: scenario 2',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -250},
[[10, 40],
[10, 40],
[19, 40],
[28, 40],
[26, 40],
[27, 40],
[28, 40],
[26, 40],
[75, 40],
[65, 40],
[73, 40],
[71, 40],
[71, 40],
[72, 40],
[11, 40],
[13, 40],
[19, 40],
[15, 40],
[27, 40],
[30, 40]]],
[[-30, False, False],
[-60, True, False],
[-81, True, False],
[-93, True, False],
[-107, True, False],
[-120, True, False],
[-132, True, False],
[-146, True, False],
[-111, True, False],
[-86, True, False],
[-53, True, False],
[-22, True, False],
[9, False, False],
[41, False, False],
[12, False, False],
[-15, False, False],
[-36, False, False],
[-61, True, False],
[-74, True, False],
[-84, True, False]]],
['regression: scenario 3',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -400},
[[13, 40],
[95, 40],
[100, 40],
[49, 40],
[97, 40],
[103, 40],
[97, 40],
[101, 40],
[99, 40],
[99, 40],
[105, 40],
[101, 40]]],
[[-27, False, False],
[28, False, False],
[88, False, False],
[97, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['regression: scenario 4',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -250},
[[21, 40],
[25, 40],
[46, 40],
[48, 40],
[21, 40],
[24, 40],
[26, 40],
[25, 40],
[25, 40],
[45, 40],
[49, 40],
[50, 40],
[50, 40],
[48, 40],
[45, 40],
[55, 40],
[20, 40],
[23, 40],
[103, 40],
[102, 40],
[73, 40],
[75, 40]]],
[[-19, False, False],
[-34, False, False],
[-28, False, False],
[-20, False, False],
[-39, False, False],
[-55, False, False],
[-69, True, False],
[-84, True, False],
[-99, True, False],
[-94, True, False],
[-85, True, False],
[-75, True, False],
[-65, True, False],
[-57, True, False],
[-52, True, False],
[-37, True, False],
[-57, True, False],
[-74, True, False],
[-11, True, False],
[51, False, False],
[84, False, False],
[100, False, False]]]],
[['regression: scenario 1',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -250},
[[14, 40],
[17, 40],
[19, 40],
[12, 40],
[16, 40],
[10, 40],
[16, 40],
[12, 40],
[16, 40],
[19, 40],
[16, 40],
[12, 40],
[20, 40],
[10, 40],
[20, 40],
[11, 40],
[20, 40]]],
[[-26, False, False],
[-49, False, False],
[-70, True, False],
[-98, True, False],
[-122, True, False],
[-152, True, True],
[-176, True, True],
[-204, True, True],
[-228, True, True],
[-249, True, True],
[-250, True, True],
[-250, True, True],
[-250, True, True],
[-250, True, True],
[-250, True, True],
[-250, True, True],
[-250, True, True]]],
['regression: scenario 3',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -300, 'floor': -250},
[[67, 40],
[23, 40],
[22, 40],
[25, 40],
[49, 40],
[10, 40],
[100, 40],
[95, 40],
[103, 40],
[100, 40],
[104, 40],
[14, 40],
[50, 40],
[48, 40],
[51, 40],
[48, 40],
[46, 40],
[53, 40],
[52, 40],
[47, 40],
[52, 40]]],
[[27, False, False],
[10, False, False],
[-8, False, False],
[-23, False, False],
[-14, False, False],
[-44, False, False],
[16, False, False],
[71, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[74, False, False],
[84, False, False],
[92, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['control: deficit and recovery',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40]]],
[[-20, False, False],
[-40, False, False],
[-60, True, False],
[-80, True, False],
[-100, True, True],
[-120, True, True],
[-140, True, True],
[-120, True, True],
[-100, True, True],
[-80, True, True],
[-60, True, False],
[-40, True, False],
[-20, True, False],
[0, False, False]]],
['regression: long surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40]]],
[[30, False, False],
[60, False, False],
[90, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[80, False, False],
[60, False, False],
[40, False, False],
[20, False, False],
[0, False, False]]],
['regression: deep deficit floor',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [80, 40], [80, 40], [80, 40], [80, 40]]],
[[-40, False, False],
[-80, True, False],
[-120, True, True],
[-150, True, True],
[-150, True, True],
[-150, True, True],
[-110, True, True],
[-70, True, True],
[-30, True, False],
[10, False, False]]],
['control: start then immediate surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [20, 40], [70, 40], [70, 40], [45, 40]]],
[[-40, False, False], [-60, True, False], [-30, True, False], [0, False, False], [5, False, False]]],
['regression: scenario 2',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -250},
[[68, 40],
[72, 40],
[75, 40],
[69, 40],
[70, 40],
[66, 40],
[65, 40],
[68, 40],
[75, 40],
[71, 40],
[70, 40],
[74, 40],
[68, 40],
[74, 40],
[68, 40],
[67, 40],
[69, 40],
[72, 40],
[68, 40],
[70, 40],
[75, 40],
[72, 40],
[75, 40],
[66, 40]]],
[[28, False, False],
[60, False, False],
[95, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['regression: scenario 4',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -400},
[[57, 40],
[54, 40],
[54, 40],
[50, 40],
[55, 40],
[52, 40],
[53, 40],
[50, 40],
[59, 40],
[50, 40],
[51, 40],
[57, 40],
[73, 40],
[67, 40],
[15, 40],
[71, 40],
[65, 40],
[74, 40]]],
[[17, False, False],
[31, False, False],
[45, False, False],
[55, False, False],
[70, False, False],
[82, False, False],
[95, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[75, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]]],
[['regression: scenario 2',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -300, 'floor': -400},
[[52, 40],
[102, 40],
[104, 40],
[97, 40],
[46, 40],
[49, 40],
[53, 40],
[53, 40],
[51, 40],
[50, 40],
[47, 40],
[52, 40]]],
[[12, False, False],
[74, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['regression: scenario 5',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -300, 'floor': -250},
[[103, 40],
[99, 40],
[104, 40],
[101, 40],
[48, 40],
[50, 40],
[46, 40],
[45, 40],
[45, 40],
[30, 40],
[24, 40],
[24, 40],
[98, 40],
[99, 40],
[98, 40],
[95, 40],
[101, 40],
[97, 40],
[99, 40],
[104, 40],
[99, 40],
[99, 40],
[49, 40],
[46, 40]]],
[[63, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[90, False, False],
[74, False, False],
[58, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['control: deficit and recovery',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40]]],
[[-20, False, False],
[-40, False, False],
[-60, True, False],
[-80, True, False],
[-100, True, True],
[-120, True, True],
[-140, True, True],
[-120, True, True],
[-100, True, True],
[-80, True, True],
[-60, True, False],
[-40, True, False],
[-20, True, False],
[0, False, False]]],
['regression: long surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40]]],
[[30, False, False],
[60, False, False],
[90, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[80, False, False],
[60, False, False],
[40, False, False],
[20, False, False],
[0, False, False]]],
['regression: deep deficit floor',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [80, 40], [80, 40], [80, 40], [80, 40]]],
[[-40, False, False],
[-80, True, False],
[-120, True, True],
[-150, True, True],
[-150, True, True],
[-150, True, True],
[-110, True, True],
[-70, True, True],
[-30, True, False],
[10, False, False]]],
['control: start then immediate surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [20, 40], [70, 40], [70, 40], [45, 40]]],
[[-40, False, False], [-60, True, False], [-30, True, False], [0, False, False], [5, False, False]]],
['regression: scenario 1',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -300, 'floor': -400},
[[55, 40],
[51, 40],
[74, 40],
[47, 40],
[27, 40],
[24, 40],
[105, 40],
[55, 40],
[46, 40],
[45, 40],
[55, 40],
[53, 40],
[101, 40],
[105, 40],
[95, 40],
[54, 40]]],
[[15, False, False],
[26, False, False],
[60, False, False],
[67, False, False],
[54, False, False],
[38, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['regression: scenario 3',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -400},
[[102, 40],
[98, 40],
[95, 40],
[51, 40],
[53, 40],
[52, 40],
[51, 40],
[53, 40],
[53, 40],
[52, 40],
[46, 40],
[53, 40],
[47, 40],
[46, 40],
[46, 40]]],
[[62, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]]],
[['regression: scenario 5',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -300, 'floor': -400},
[[16, 40],
[10, 40],
[17, 40],
[20, 40],
[11, 40],
[20, 40],
[104, 40],
[102, 40],
[103, 40],
[97, 40],
[101, 40],
[102, 40],
[95, 40],
[103, 40],
[99, 40],
[101, 40],
[17, 40],
[17, 40],
[14, 40],
[67, 40],
[72, 40],
[74, 40]]],
[[-24, False, False],
[-54, False, False],
[-77, True, False],
[-97, True, False],
[-126, True, False],
[-146, True, False],
[-82, True, False],
[-20, True, False],
[43, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[77, False, False],
[54, False, False],
[28, False, False],
[55, False, False],
[87, False, False],
[100, False, False]]],
['regression: scenario 11',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -300, 'floor': -250},
[[56, 40],
[54, 40],
[53, 40],
[100, 40],
[101, 40],
[104, 40],
[72, 40],
[69, 40],
[71, 40],
[65, 40],
[71, 40],
[73, 40],
[102, 40],
[47, 40],
[55, 40],
[47, 40],
[54, 40],
[49, 40],
[47, 40],
[52, 40],
[51, 40],
[54, 40],
[50, 40]]],
[[16, False, False],
[30, False, False],
[43, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['control: deficit and recovery',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40]]],
[[-20, False, False],
[-40, False, False],
[-60, True, False],
[-80, True, False],
[-100, True, True],
[-120, True, True],
[-140, True, True],
[-120, True, True],
[-100, True, True],
[-80, True, True],
[-60, True, False],
[-40, True, False],
[-20, True, False],
[0, False, False]]],
['regression: long surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40]]],
[[30, False, False],
[60, False, False],
[90, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[80, False, False],
[60, False, False],
[40, False, False],
[20, False, False],
[0, False, False]]],
['regression: deep deficit floor',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [80, 40], [80, 40], [80, 40], [80, 40]]],
[[-40, False, False],
[-80, True, False],
[-120, True, True],
[-150, True, True],
[-150, True, True],
[-150, True, True],
[-110, True, True],
[-70, True, True],
[-30, True, False],
[10, False, False]]],
['control: start then immediate surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [20, 40], [70, 40], [70, 40], [45, 40]]],
[[-40, False, False], [-60, True, False], [-30, True, False], [0, False, False], [5, False, False]]],
['regression: scenario 1',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -400},
[[67, 40],
[73, 40],
[101, 40],
[96, 40],
[104, 40],
[99, 40],
[101, 40],
[98, 40],
[95, 40],
[95, 40],
[65, 40],
[71, 40]]],
[[27, False, False],
[60, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['control: scenario 2',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -250},
[[20, 40], [25, 40], [21, 40], [22, 40], [26, 40], [25, 40], [26, 40], [24, 40], [73, 40], [71, 40]]],
[[-20, False, False],
[-35, False, False],
[-54, False, False],
[-72, True, False],
[-86, True, False],
[-101, True, False],
[-115, True, False],
[-131, True, False],
[-98, True, False],
[-67, True, False]]]]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: long surplus | [[30, False, False], [60, False, False], [90, False, False], [120, False, False], [150, False, False], [180, False, False], [160, False, False], [140, False, False], [120, False, False], [100, False, False], [80, False, False]] | [[30, False, False], [60, False, False], [90, False, False], [100, False, False], [100, False, False], [100, False, False], [80, False, False], [60, False, False], [40, False, False], [20, False, False], [0, False, False]] | Failed |
| regression: scenario 1 | [[-29, False, False], [-19, False, False], [-10, False, False], [3, False, False], [12, False, False], [43, False, False], [108, False, False], [168, False, False], [145, False, False], [118, False, False], [180, False, False], [242, False, False], [301, False, False], [366, False, False], [422, False, False], [432, False, False], [440, False, False], [446, False, False], [453, False, False], [463, False, False], [475, False, False], [483, False, False], [514, False, False]] | [[-29, False, False], [-19, False, False], [-10, False, False], [3, False, False], [12, False, False], [43, False, False], [100, False, False], [100, False, False], [77, False, False], [50, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False]] | Failed |
| control: deficit and recovery | [[-20, False, False], [-40, False, False], [-60, True, False], [-80, True, False], [-100, True, True], [-120, True, True], [-140, True, True], [-120, True, True], [-100, True, True], [-80, True, True], [-60, True, False], [-40, True, False], [-20, True, False], [0, False, False]] | [[-20, False, False], [-40, False, False], [-60, True, False], [-80, True, False], [-100, True, True], [-120, True, True], [-140, True, True], [-120, True, True], [-100, True, True], [-80, True, True], [-60, True, False], [-40, True, False], [-20, True, False], [0, False, False]] | Passed |
| regression: deep deficit floor | [[-40, False, False], [-80, True, False], [-120, True, True], [-160, True, True], [-200, True, True], [-240, True, True], [-200, True, True], [-160, True, True], [-120, True, True], [-80, True, True]] | [[-40, False, False], [-80, True, False], [-120, True, True], [-150, True, True], [-150, True, True], [-150, True, True], [-110, True, True], [-70, True, True], [-30, True, False], [10, False, False]] | Failed |
| control: start then immediate surplus | [[-40, False, False], [-60, True, False], [-30, True, False], [0, False, False], [5, False, False]] | [[-40, False, False], [-60, True, False], [-30, True, False], [0, False, False], [5, False, False]] | Passed |
| regression: scenario 2 | [[27, False, False], [54, False, False], [87, False, False], [118, False, False], [89, False, False], [68, False, False], [97, False, False], [127, False, False], [152, False, False], [182, False, False], [208, False, False], [234, False, False], [265, False, False], [293, False, False], [323, False, False], [356, False, False], [390, False, False], [423, False, False], [448, False, False], [483, False, False], [547, False, False]] | [[27, False, False], [54, False, False], [87, False, False], [100, False, False], [71, False, False], [50, False, False], [79, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False]] | Failed |
| regression: scenario 3 | [[31, False, False], [66, False, False], [98, False, False], [126, False, False], [161, False, False], [169, False, False], [174, False, False], [164, False, False], [142, False, False], [121, False, False], [93, False, False], [69, False, False], [39, False, False], [17, False, False], [-5, False, False], [-27, False, False], [5, False, False], [-15, False, False], [-35, False, False], [-58, False, False]] | [[31, False, False], [66, False, False], [98, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [90, False, False], [68, False, False], [47, False, False], [19, False, False], [-5, False, False], [-35, False, False], [-57, False, False], [-79, True, False], [-101, True, False], [-69, True, False], [-89, True, False], [-109, True, False], [-132, True, False]] | Failed |
| regression: scenario 4 | [[-13, False, False], [-30, False, False], [-42, False, False], [-15, False, False], [41, False, False], [102, False, False], [80, False, False], [51, False, False], [27, False, False], [5, False, False], [-22, False, False], [-46, False, False], [-68, True, False], [-92, True, False], [-115, True, False], [-145, True, False], [-170, True, True]] | [[-13, False, False], [-30, False, False], [-42, False, False], [-15, False, False], [41, False, False], [100, False, False], [78, False, False], [49, False, False], [25, False, False], [3, False, False], [-24, False, False], [-48, False, False], [-70, True, False], [-94, True, False], [-117, True, False], [-147, True, False], [-172, True, True]] | Failed |
SHA-256 / df0b880749ad54d3d0e46fedf8fa579e972a72a582bf6b1bdb114ecd57dee233
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(settings, samples):
dm = 0
comp = False
aux = False
out = []
for supply, target in samples:
dm = max(settings['floor'], dm + supply - target)
if comp and dm >= settings['stop_dm']:
comp = False
elif not comp and dm <= settings['start_dm']:
comp = True
if aux and dm >= settings['start_dm']:
aux = False
elif not aux and dm <= settings['aux_dm']:
aux = True
out.append([dm, comp, aux])
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: long surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40]]],
[[30, False, False],
[60, False, False],
[90, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[80, False, False],
[60, False, False],
[40, False, False],
[20, False, False],
[0, False, False]]],
['regression: scenario 1',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -400},
[[11, 40],
[50, 40],
[49, 40],
[53, 40],
[49, 40],
[71, 40],
[105, 40],
[100, 40],
[17, 40],
[13, 40],
[102, 40],
[102, 40],
[99, 40],
[105, 40],
[96, 40],
[50, 40],
[48, 40],
[46, 40],
[47, 40],
[50, 40],
[52, 40],
[48, 40],
[71, 40]]],
[[-29, False, False],
[-19, False, False],
[-10, False, False],
[3, False, False],
[12, False, False],
[43, False, False],
[100, False, False],
[100, False, False],
[77, False, False],
[50, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['control: deficit and recovery',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40]]],
[[-20, False, False],
[-40, False, False],
[-60, True, False],
[-80, True, False],
[-100, True, True],
[-120, True, True],
[-140, True, True],
[-120, True, True],
[-100, True, True],
[-80, True, True],
[-60, True, False],
[-40, True, False],
[-20, True, False],
[0, False, False]]],
['regression: deep deficit floor',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [80, 40], [80, 40], [80, 40], [80, 40]]],
[[-40, False, False],
[-80, True, False],
[-120, True, True],
[-150, True, True],
[-150, True, True],
[-150, True, True],
[-110, True, True],
[-70, True, True],
[-30, True, False],
[10, False, False]]],
['control: start then immediate surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [20, 40], [70, 40], [70, 40], [45, 40]]],
[[-40, False, False], [-60, True, False], [-30, True, False], [0, False, False], [5, False, False]]],
['regression: scenario 2',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -300, 'floor': -250},
[[67, 40],
[67, 40],
[73, 40],
[71, 40],
[11, 40],
[19, 40],
[69, 40],
[70, 40],
[65, 40],
[70, 40],
[66, 40],
[66, 40],
[71, 40],
[68, 40],
[70, 40],
[73, 40],
[74, 40],
[73, 40],
[65, 40],
[75, 40],
[104, 40]]],
[[27, False, False],
[54, False, False],
[87, False, False],
[100, False, False],
[71, False, False],
[50, False, False],
[79, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['regression: scenario 3',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -300, 'floor': -400},
[[71, 40],
[75, 40],
[72, 40],
[68, 40],
[75, 40],
[48, 40],
[45, 40],
[30, 40],
[18, 40],
[19, 40],
[12, 40],
[16, 40],
[10, 40],
[18, 40],
[18, 40],
[18, 40],
[72, 40],
[20, 40],
[20, 40],
[17, 40]]],
[[31, False, False],
[66, False, False],
[98, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[90, False, False],
[68, False, False],
[47, False, False],
[19, False, False],
[-5, False, False],
[-35, False, False],
[-57, False, False],
[-79, True, False],
[-101, True, False],
[-69, True, False],
[-89, True, False],
[-109, True, False],
[-132, True, False]]],
['regression: scenario 4',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -250},
[[27, 40],
[23, 40],
[28, 40],
[67, 40],
[96, 40],
[101, 40],
[18, 40],
[11, 40],
[16, 40],
[18, 40],
[13, 40],
[16, 40],
[18, 40],
[16, 40],
[17, 40],
[10, 40],
[15, 40]]],
[[-13, False, False],
[-30, False, False],
[-42, False, False],
[-15, False, False],
[41, False, False],
[100, False, False],
[78, False, False],
[49, False, False],
[25, False, False],
[3, False, False],
[-24, False, False],
[-48, False, False],
[-70, True, False],
[-94, True, False],
[-117, True, False],
[-147, True, False],
[-172, True, True]]]],
[['regression: deep deficit floor',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [80, 40], [80, 40], [80, 40], [80, 40]]],
[[-40, False, False],
[-80, True, False],
[-120, True, True],
[-150, True, True],
[-150, True, True],
[-150, True, True],
[-110, True, True],
[-70, True, True],
[-30, True, False],
[10, False, False]]],
['regression: scenario 1',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -300, 'floor': -250},
[[57, 40],
[101, 40],
[100, 40],
[98, 40],
[95, 40],
[100, 40],
[101, 40],
[103, 40],
[96, 40],
[97, 40],
[14, 40],
[17, 40],
[12, 40],
[20, 40],
[13, 40]]],
[[17, False, False],
[78, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[74, False, False],
[51, False, False],
[23, False, False],
[3, False, False],
[-24, False, False]]],
['control: deficit and recovery',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40]]],
[[-20, False, False],
[-40, False, False],
[-60, True, False],
[-80, True, False],
[-100, True, True],
[-120, True, True],
[-140, True, True],
[-120, True, True],
[-100, True, True],
[-80, True, True],
[-60, True, False],
[-40, True, False],
[-20, True, False],
[0, False, False]]],
['regression: long surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40]]],
[[30, False, False],
[60, False, False],
[90, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[80, False, False],
[60, False, False],
[40, False, False],
[20, False, False],
[0, False, False]]],
['control: start then immediate surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [20, 40], [70, 40], [70, 40], [45, 40]]],
[[-40, False, False], [-60, True, False], [-30, True, False], [0, False, False], [5, False, False]]],
['control: scenario 2',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -250},
[[10, 40],
[10, 40],
[19, 40],
[28, 40],
[26, 40],
[27, 40],
[28, 40],
[26, 40],
[75, 40],
[65, 40],
[73, 40],
[71, 40],
[71, 40],
[72, 40],
[11, 40],
[13, 40],
[19, 40],
[15, 40],
[27, 40],
[30, 40]]],
[[-30, False, False],
[-60, True, False],
[-81, True, False],
[-93, True, False],
[-107, True, False],
[-120, True, False],
[-132, True, False],
[-146, True, False],
[-111, True, False],
[-86, True, False],
[-53, True, False],
[-22, True, False],
[9, False, False],
[41, False, False],
[12, False, False],
[-15, False, False],
[-36, False, False],
[-61, True, False],
[-74, True, False],
[-84, True, False]]],
['regression: scenario 3',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -400},
[[13, 40],
[95, 40],
[100, 40],
[49, 40],
[97, 40],
[103, 40],
[97, 40],
[101, 40],
[99, 40],
[99, 40],
[105, 40],
[101, 40]]],
[[-27, False, False],
[28, False, False],
[88, False, False],
[97, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['regression: scenario 4',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -250},
[[21, 40],
[25, 40],
[46, 40],
[48, 40],
[21, 40],
[24, 40],
[26, 40],
[25, 40],
[25, 40],
[45, 40],
[49, 40],
[50, 40],
[50, 40],
[48, 40],
[45, 40],
[55, 40],
[20, 40],
[23, 40],
[103, 40],
[102, 40],
[73, 40],
[75, 40]]],
[[-19, False, False],
[-34, False, False],
[-28, False, False],
[-20, False, False],
[-39, False, False],
[-55, False, False],
[-69, True, False],
[-84, True, False],
[-99, True, False],
[-94, True, False],
[-85, True, False],
[-75, True, False],
[-65, True, False],
[-57, True, False],
[-52, True, False],
[-37, True, False],
[-57, True, False],
[-74, True, False],
[-11, True, False],
[51, False, False],
[84, False, False],
[100, False, False]]]],
[['regression: scenario 1',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -250},
[[14, 40],
[17, 40],
[19, 40],
[12, 40],
[16, 40],
[10, 40],
[16, 40],
[12, 40],
[16, 40],
[19, 40],
[16, 40],
[12, 40],
[20, 40],
[10, 40],
[20, 40],
[11, 40],
[20, 40]]],
[[-26, False, False],
[-49, False, False],
[-70, True, False],
[-98, True, False],
[-122, True, False],
[-152, True, True],
[-176, True, True],
[-204, True, True],
[-228, True, True],
[-249, True, True],
[-250, True, True],
[-250, True, True],
[-250, True, True],
[-250, True, True],
[-250, True, True],
[-250, True, True],
[-250, True, True]]],
['regression: scenario 3',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -300, 'floor': -250},
[[67, 40],
[23, 40],
[22, 40],
[25, 40],
[49, 40],
[10, 40],
[100, 40],
[95, 40],
[103, 40],
[100, 40],
[104, 40],
[14, 40],
[50, 40],
[48, 40],
[51, 40],
[48, 40],
[46, 40],
[53, 40],
[52, 40],
[47, 40],
[52, 40]]],
[[27, False, False],
[10, False, False],
[-8, False, False],
[-23, False, False],
[-14, False, False],
[-44, False, False],
[16, False, False],
[71, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[74, False, False],
[84, False, False],
[92, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['control: deficit and recovery',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40]]],
[[-20, False, False],
[-40, False, False],
[-60, True, False],
[-80, True, False],
[-100, True, True],
[-120, True, True],
[-140, True, True],
[-120, True, True],
[-100, True, True],
[-80, True, True],
[-60, True, False],
[-40, True, False],
[-20, True, False],
[0, False, False]]],
['regression: long surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40]]],
[[30, False, False],
[60, False, False],
[90, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[80, False, False],
[60, False, False],
[40, False, False],
[20, False, False],
[0, False, False]]],
['regression: deep deficit floor',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [80, 40], [80, 40], [80, 40], [80, 40]]],
[[-40, False, False],
[-80, True, False],
[-120, True, True],
[-150, True, True],
[-150, True, True],
[-150, True, True],
[-110, True, True],
[-70, True, True],
[-30, True, False],
[10, False, False]]],
['control: start then immediate surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [20, 40], [70, 40], [70, 40], [45, 40]]],
[[-40, False, False], [-60, True, False], [-30, True, False], [0, False, False], [5, False, False]]],
['regression: scenario 2',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -250},
[[68, 40],
[72, 40],
[75, 40],
[69, 40],
[70, 40],
[66, 40],
[65, 40],
[68, 40],
[75, 40],
[71, 40],
[70, 40],
[74, 40],
[68, 40],
[74, 40],
[68, 40],
[67, 40],
[69, 40],
[72, 40],
[68, 40],
[70, 40],
[75, 40],
[72, 40],
[75, 40],
[66, 40]]],
[[28, False, False],
[60, False, False],
[95, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['regression: scenario 4',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -400},
[[57, 40],
[54, 40],
[54, 40],
[50, 40],
[55, 40],
[52, 40],
[53, 40],
[50, 40],
[59, 40],
[50, 40],
[51, 40],
[57, 40],
[73, 40],
[67, 40],
[15, 40],
[71, 40],
[65, 40],
[74, 40]]],
[[17, False, False],
[31, False, False],
[45, False, False],
[55, False, False],
[70, False, False],
[82, False, False],
[95, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[75, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]]],
[['regression: scenario 2',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -300, 'floor': -400},
[[52, 40],
[102, 40],
[104, 40],
[97, 40],
[46, 40],
[49, 40],
[53, 40],
[53, 40],
[51, 40],
[50, 40],
[47, 40],
[52, 40]]],
[[12, False, False],
[74, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['regression: scenario 5',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -300, 'floor': -250},
[[103, 40],
[99, 40],
[104, 40],
[101, 40],
[48, 40],
[50, 40],
[46, 40],
[45, 40],
[45, 40],
[30, 40],
[24, 40],
[24, 40],
[98, 40],
[99, 40],
[98, 40],
[95, 40],
[101, 40],
[97, 40],
[99, 40],
[104, 40],
[99, 40],
[99, 40],
[49, 40],
[46, 40]]],
[[63, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[90, False, False],
[74, False, False],
[58, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['control: deficit and recovery',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40]]],
[[-20, False, False],
[-40, False, False],
[-60, True, False],
[-80, True, False],
[-100, True, True],
[-120, True, True],
[-140, True, True],
[-120, True, True],
[-100, True, True],
[-80, True, True],
[-60, True, False],
[-40, True, False],
[-20, True, False],
[0, False, False]]],
['regression: long surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40]]],
[[30, False, False],
[60, False, False],
[90, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[80, False, False],
[60, False, False],
[40, False, False],
[20, False, False],
[0, False, False]]],
['regression: deep deficit floor',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [80, 40], [80, 40], [80, 40], [80, 40]]],
[[-40, False, False],
[-80, True, False],
[-120, True, True],
[-150, True, True],
[-150, True, True],
[-150, True, True],
[-110, True, True],
[-70, True, True],
[-30, True, False],
[10, False, False]]],
['control: start then immediate surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [20, 40], [70, 40], [70, 40], [45, 40]]],
[[-40, False, False], [-60, True, False], [-30, True, False], [0, False, False], [5, False, False]]],
['regression: scenario 1',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -300, 'floor': -400},
[[55, 40],
[51, 40],
[74, 40],
[47, 40],
[27, 40],
[24, 40],
[105, 40],
[55, 40],
[46, 40],
[45, 40],
[55, 40],
[53, 40],
[101, 40],
[105, 40],
[95, 40],
[54, 40]]],
[[15, False, False],
[26, False, False],
[60, False, False],
[67, False, False],
[54, False, False],
[38, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['regression: scenario 3',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -400},
[[102, 40],
[98, 40],
[95, 40],
[51, 40],
[53, 40],
[52, 40],
[51, 40],
[53, 40],
[53, 40],
[52, 40],
[46, 40],
[53, 40],
[47, 40],
[46, 40],
[46, 40]]],
[[62, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]]],
[['regression: scenario 5',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -300, 'floor': -400},
[[16, 40],
[10, 40],
[17, 40],
[20, 40],
[11, 40],
[20, 40],
[104, 40],
[102, 40],
[103, 40],
[97, 40],
[101, 40],
[102, 40],
[95, 40],
[103, 40],
[99, 40],
[101, 40],
[17, 40],
[17, 40],
[14, 40],
[67, 40],
[72, 40],
[74, 40]]],
[[-24, False, False],
[-54, False, False],
[-77, True, False],
[-97, True, False],
[-126, True, False],
[-146, True, False],
[-82, True, False],
[-20, True, False],
[43, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[77, False, False],
[54, False, False],
[28, False, False],
[55, False, False],
[87, False, False],
[100, False, False]]],
['regression: scenario 11',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -300, 'floor': -250},
[[56, 40],
[54, 40],
[53, 40],
[100, 40],
[101, 40],
[104, 40],
[72, 40],
[69, 40],
[71, 40],
[65, 40],
[71, 40],
[73, 40],
[102, 40],
[47, 40],
[55, 40],
[47, 40],
[54, 40],
[49, 40],
[47, 40],
[52, 40],
[51, 40],
[54, 40],
[50, 40]]],
[[16, False, False],
[30, False, False],
[43, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['control: deficit and recovery',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40]]],
[[-20, False, False],
[-40, False, False],
[-60, True, False],
[-80, True, False],
[-100, True, True],
[-120, True, True],
[-140, True, True],
[-120, True, True],
[-100, True, True],
[-80, True, True],
[-60, True, False],
[-40, True, False],
[-20, True, False],
[0, False, False]]],
['regression: long surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40]]],
[[30, False, False],
[60, False, False],
[90, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[80, False, False],
[60, False, False],
[40, False, False],
[20, False, False],
[0, False, False]]],
['regression: deep deficit floor',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [80, 40], [80, 40], [80, 40], [80, 40]]],
[[-40, False, False],
[-80, True, False],
[-120, True, True],
[-150, True, True],
[-150, True, True],
[-150, True, True],
[-110, True, True],
[-70, True, True],
[-30, True, False],
[10, False, False]]],
['control: start then immediate surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [20, 40], [70, 40], [70, 40], [45, 40]]],
[[-40, False, False], [-60, True, False], [-30, True, False], [0, False, False], [5, False, False]]],
['regression: scenario 1',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -400},
[[67, 40],
[73, 40],
[101, 40],
[96, 40],
[104, 40],
[99, 40],
[101, 40],
[98, 40],
[95, 40],
[95, 40],
[65, 40],
[71, 40]]],
[[27, False, False],
[60, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['control: scenario 2',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -250},
[[20, 40], [25, 40], [21, 40], [22, 40], [26, 40], [25, 40], [26, 40], [24, 40], [73, 40], [71, 40]]],
[[-20, False, False],
[-35, False, False],
[-54, False, False],
[-72, True, False],
[-86, True, False],
[-101, True, False],
[-115, True, False],
[-131, True, False],
[-98, True, False],
[-67, True, False]]]]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: long surplus | [[30, False, False], [60, False, False], [90, False, False], [120, False, False], [150, False, False], [180, False, False], [160, False, False], [140, False, False], [120, False, False], [100, False, False], [80, False, False]] | [[30, False, False], [60, False, False], [90, False, False], [100, False, False], [100, False, False], [100, False, False], [80, False, False], [60, False, False], [40, False, False], [20, False, False], [0, False, False]] | Failed |
| regression: scenario 1 | [[-29, False, False], [-19, False, False], [-10, False, False], [3, False, False], [12, False, False], [43, False, False], [108, False, False], [168, False, False], [145, False, False], [118, False, False], [180, False, False], [242, False, False], [301, False, False], [366, False, False], [422, False, False], [432, False, False], [440, False, False], [446, False, False], [453, False, False], [463, False, False], [475, False, False], [483, False, False], [514, False, False]] | [[-29, False, False], [-19, False, False], [-10, False, False], [3, False, False], [12, False, False], [43, False, False], [100, False, False], [100, False, False], [77, False, False], [50, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False]] | Failed |
| control: deficit and recovery | [[-20, False, False], [-40, False, False], [-60, True, False], [-80, True, False], [-100, True, True], [-120, True, True], [-140, True, True], [-120, True, True], [-100, True, True], [-80, True, True], [-60, True, False], [-40, True, False], [-20, True, False], [0, False, False]] | [[-20, False, False], [-40, False, False], [-60, True, False], [-80, True, False], [-100, True, True], [-120, True, True], [-140, True, True], [-120, True, True], [-100, True, True], [-80, True, True], [-60, True, False], [-40, True, False], [-20, True, False], [0, False, False]] | Passed |
| regression: deep deficit floor | [[-40, False, False], [-80, True, False], [-120, True, True], [-150, True, True], [-150, True, True], [-150, True, True], [-110, True, True], [-70, True, True], [-30, True, False], [10, False, False]] | [[-40, False, False], [-80, True, False], [-120, True, True], [-150, True, True], [-150, True, True], [-150, True, True], [-110, True, True], [-70, True, True], [-30, True, False], [10, False, False]] | Passed |
| control: start then immediate surplus | [[-40, False, False], [-60, True, False], [-30, True, False], [0, False, False], [5, False, False]] | [[-40, False, False], [-60, True, False], [-30, True, False], [0, False, False], [5, False, False]] | Passed |
| regression: scenario 2 | [[27, False, False], [54, False, False], [87, False, False], [118, False, False], [89, False, False], [68, False, False], [97, False, False], [127, False, False], [152, False, False], [182, False, False], [208, False, False], [234, False, False], [265, False, False], [293, False, False], [323, False, False], [356, False, False], [390, False, False], [423, False, False], [448, False, False], [483, False, False], [547, False, False]] | [[27, False, False], [54, False, False], [87, False, False], [100, False, False], [71, False, False], [50, False, False], [79, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False]] | Failed |
| regression: scenario 3 | [[31, False, False], [66, False, False], [98, False, False], [126, False, False], [161, False, False], [169, False, False], [174, False, False], [164, False, False], [142, False, False], [121, False, False], [93, False, False], [69, False, False], [39, False, False], [17, False, False], [-5, False, False], [-27, False, False], [5, False, False], [-15, False, False], [-35, False, False], [-58, False, False]] | [[31, False, False], [66, False, False], [98, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [90, False, False], [68, False, False], [47, False, False], [19, False, False], [-5, False, False], [-35, False, False], [-57, False, False], [-79, True, False], [-101, True, False], [-69, True, False], [-89, True, False], [-109, True, False], [-132, True, False]] | Failed |
| regression: scenario 4 | [[-13, False, False], [-30, False, False], [-42, False, False], [-15, False, False], [41, False, False], [102, False, False], [80, False, False], [51, False, False], [27, False, False], [5, False, False], [-22, False, False], [-46, False, False], [-68, True, False], [-92, True, False], [-115, True, False], [-145, True, False], [-170, True, True]] | [[-13, False, False], [-30, False, False], [-42, False, False], [-15, False, False], [41, False, False], [100, False, False], [78, False, False], [49, False, False], [25, False, False], [3, False, False], [-24, False, False], [-48, False, False], [-70, True, False], [-94, True, False], [-117, True, False], [-147, True, False], [-172, True, True]] | Failed |
SHA-256 / 35f910b158d8940d3ed484f4cdfb062461beb5f064ca8d9fae280965d9f9f9a4
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(settings, samples):
dm = 0
comp = False
aux = False
out = []
for supply, target in samples:
dm = max(settings['floor'], min(100, dm + supply - target))
if comp and dm >= settings['stop_dm']:
comp = False
elif not comp and dm <= settings['start_dm']:
comp = True
if aux and dm >= settings['start_dm']:
aux = False
elif not aux and dm <= settings['aux_dm']:
aux = True
out.append([dm, comp, aux])
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: long surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40]]],
[[30, False, False],
[60, False, False],
[90, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[80, False, False],
[60, False, False],
[40, False, False],
[20, False, False],
[0, False, False]]],
['regression: scenario 1',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -400},
[[11, 40],
[50, 40],
[49, 40],
[53, 40],
[49, 40],
[71, 40],
[105, 40],
[100, 40],
[17, 40],
[13, 40],
[102, 40],
[102, 40],
[99, 40],
[105, 40],
[96, 40],
[50, 40],
[48, 40],
[46, 40],
[47, 40],
[50, 40],
[52, 40],
[48, 40],
[71, 40]]],
[[-29, False, False],
[-19, False, False],
[-10, False, False],
[3, False, False],
[12, False, False],
[43, False, False],
[100, False, False],
[100, False, False],
[77, False, False],
[50, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['control: deficit and recovery',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40]]],
[[-20, False, False],
[-40, False, False],
[-60, True, False],
[-80, True, False],
[-100, True, True],
[-120, True, True],
[-140, True, True],
[-120, True, True],
[-100, True, True],
[-80, True, True],
[-60, True, False],
[-40, True, False],
[-20, True, False],
[0, False, False]]],
['regression: deep deficit floor',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [80, 40], [80, 40], [80, 40], [80, 40]]],
[[-40, False, False],
[-80, True, False],
[-120, True, True],
[-150, True, True],
[-150, True, True],
[-150, True, True],
[-110, True, True],
[-70, True, True],
[-30, True, False],
[10, False, False]]],
['control: start then immediate surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [20, 40], [70, 40], [70, 40], [45, 40]]],
[[-40, False, False], [-60, True, False], [-30, True, False], [0, False, False], [5, False, False]]],
['regression: scenario 2',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -300, 'floor': -250},
[[67, 40],
[67, 40],
[73, 40],
[71, 40],
[11, 40],
[19, 40],
[69, 40],
[70, 40],
[65, 40],
[70, 40],
[66, 40],
[66, 40],
[71, 40],
[68, 40],
[70, 40],
[73, 40],
[74, 40],
[73, 40],
[65, 40],
[75, 40],
[104, 40]]],
[[27, False, False],
[54, False, False],
[87, False, False],
[100, False, False],
[71, False, False],
[50, False, False],
[79, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['regression: scenario 3',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -300, 'floor': -400},
[[71, 40],
[75, 40],
[72, 40],
[68, 40],
[75, 40],
[48, 40],
[45, 40],
[30, 40],
[18, 40],
[19, 40],
[12, 40],
[16, 40],
[10, 40],
[18, 40],
[18, 40],
[18, 40],
[72, 40],
[20, 40],
[20, 40],
[17, 40]]],
[[31, False, False],
[66, False, False],
[98, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[90, False, False],
[68, False, False],
[47, False, False],
[19, False, False],
[-5, False, False],
[-35, False, False],
[-57, False, False],
[-79, True, False],
[-101, True, False],
[-69, True, False],
[-89, True, False],
[-109, True, False],
[-132, True, False]]],
['regression: scenario 4',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -250},
[[27, 40],
[23, 40],
[28, 40],
[67, 40],
[96, 40],
[101, 40],
[18, 40],
[11, 40],
[16, 40],
[18, 40],
[13, 40],
[16, 40],
[18, 40],
[16, 40],
[17, 40],
[10, 40],
[15, 40]]],
[[-13, False, False],
[-30, False, False],
[-42, False, False],
[-15, False, False],
[41, False, False],
[100, False, False],
[78, False, False],
[49, False, False],
[25, False, False],
[3, False, False],
[-24, False, False],
[-48, False, False],
[-70, True, False],
[-94, True, False],
[-117, True, False],
[-147, True, False],
[-172, True, True]]]],
[['regression: deep deficit floor',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [80, 40], [80, 40], [80, 40], [80, 40]]],
[[-40, False, False],
[-80, True, False],
[-120, True, True],
[-150, True, True],
[-150, True, True],
[-150, True, True],
[-110, True, True],
[-70, True, True],
[-30, True, False],
[10, False, False]]],
['regression: scenario 1',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -300, 'floor': -250},
[[57, 40],
[101, 40],
[100, 40],
[98, 40],
[95, 40],
[100, 40],
[101, 40],
[103, 40],
[96, 40],
[97, 40],
[14, 40],
[17, 40],
[12, 40],
[20, 40],
[13, 40]]],
[[17, False, False],
[78, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[74, False, False],
[51, False, False],
[23, False, False],
[3, False, False],
[-24, False, False]]],
['control: deficit and recovery',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40]]],
[[-20, False, False],
[-40, False, False],
[-60, True, False],
[-80, True, False],
[-100, True, True],
[-120, True, True],
[-140, True, True],
[-120, True, True],
[-100, True, True],
[-80, True, True],
[-60, True, False],
[-40, True, False],
[-20, True, False],
[0, False, False]]],
['regression: long surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40]]],
[[30, False, False],
[60, False, False],
[90, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[80, False, False],
[60, False, False],
[40, False, False],
[20, False, False],
[0, False, False]]],
['control: start then immediate surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [20, 40], [70, 40], [70, 40], [45, 40]]],
[[-40, False, False], [-60, True, False], [-30, True, False], [0, False, False], [5, False, False]]],
['control: scenario 2',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -250},
[[10, 40],
[10, 40],
[19, 40],
[28, 40],
[26, 40],
[27, 40],
[28, 40],
[26, 40],
[75, 40],
[65, 40],
[73, 40],
[71, 40],
[71, 40],
[72, 40],
[11, 40],
[13, 40],
[19, 40],
[15, 40],
[27, 40],
[30, 40]]],
[[-30, False, False],
[-60, True, False],
[-81, True, False],
[-93, True, False],
[-107, True, False],
[-120, True, False],
[-132, True, False],
[-146, True, False],
[-111, True, False],
[-86, True, False],
[-53, True, False],
[-22, True, False],
[9, False, False],
[41, False, False],
[12, False, False],
[-15, False, False],
[-36, False, False],
[-61, True, False],
[-74, True, False],
[-84, True, False]]],
['regression: scenario 3',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -400},
[[13, 40],
[95, 40],
[100, 40],
[49, 40],
[97, 40],
[103, 40],
[97, 40],
[101, 40],
[99, 40],
[99, 40],
[105, 40],
[101, 40]]],
[[-27, False, False],
[28, False, False],
[88, False, False],
[97, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['regression: scenario 4',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -250},
[[21, 40],
[25, 40],
[46, 40],
[48, 40],
[21, 40],
[24, 40],
[26, 40],
[25, 40],
[25, 40],
[45, 40],
[49, 40],
[50, 40],
[50, 40],
[48, 40],
[45, 40],
[55, 40],
[20, 40],
[23, 40],
[103, 40],
[102, 40],
[73, 40],
[75, 40]]],
[[-19, False, False],
[-34, False, False],
[-28, False, False],
[-20, False, False],
[-39, False, False],
[-55, False, False],
[-69, True, False],
[-84, True, False],
[-99, True, False],
[-94, True, False],
[-85, True, False],
[-75, True, False],
[-65, True, False],
[-57, True, False],
[-52, True, False],
[-37, True, False],
[-57, True, False],
[-74, True, False],
[-11, True, False],
[51, False, False],
[84, False, False],
[100, False, False]]]],
[['regression: scenario 1',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -250},
[[14, 40],
[17, 40],
[19, 40],
[12, 40],
[16, 40],
[10, 40],
[16, 40],
[12, 40],
[16, 40],
[19, 40],
[16, 40],
[12, 40],
[20, 40],
[10, 40],
[20, 40],
[11, 40],
[20, 40]]],
[[-26, False, False],
[-49, False, False],
[-70, True, False],
[-98, True, False],
[-122, True, False],
[-152, True, True],
[-176, True, True],
[-204, True, True],
[-228, True, True],
[-249, True, True],
[-250, True, True],
[-250, True, True],
[-250, True, True],
[-250, True, True],
[-250, True, True],
[-250, True, True],
[-250, True, True]]],
['regression: scenario 3',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -300, 'floor': -250},
[[67, 40],
[23, 40],
[22, 40],
[25, 40],
[49, 40],
[10, 40],
[100, 40],
[95, 40],
[103, 40],
[100, 40],
[104, 40],
[14, 40],
[50, 40],
[48, 40],
[51, 40],
[48, 40],
[46, 40],
[53, 40],
[52, 40],
[47, 40],
[52, 40]]],
[[27, False, False],
[10, False, False],
[-8, False, False],
[-23, False, False],
[-14, False, False],
[-44, False, False],
[16, False, False],
[71, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[74, False, False],
[84, False, False],
[92, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['control: deficit and recovery',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40]]],
[[-20, False, False],
[-40, False, False],
[-60, True, False],
[-80, True, False],
[-100, True, True],
[-120, True, True],
[-140, True, True],
[-120, True, True],
[-100, True, True],
[-80, True, True],
[-60, True, False],
[-40, True, False],
[-20, True, False],
[0, False, False]]],
['regression: long surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40]]],
[[30, False, False],
[60, False, False],
[90, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[80, False, False],
[60, False, False],
[40, False, False],
[20, False, False],
[0, False, False]]],
['regression: deep deficit floor',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [80, 40], [80, 40], [80, 40], [80, 40]]],
[[-40, False, False],
[-80, True, False],
[-120, True, True],
[-150, True, True],
[-150, True, True],
[-150, True, True],
[-110, True, True],
[-70, True, True],
[-30, True, False],
[10, False, False]]],
['control: start then immediate surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [20, 40], [70, 40], [70, 40], [45, 40]]],
[[-40, False, False], [-60, True, False], [-30, True, False], [0, False, False], [5, False, False]]],
['regression: scenario 2',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -250},
[[68, 40],
[72, 40],
[75, 40],
[69, 40],
[70, 40],
[66, 40],
[65, 40],
[68, 40],
[75, 40],
[71, 40],
[70, 40],
[74, 40],
[68, 40],
[74, 40],
[68, 40],
[67, 40],
[69, 40],
[72, 40],
[68, 40],
[70, 40],
[75, 40],
[72, 40],
[75, 40],
[66, 40]]],
[[28, False, False],
[60, False, False],
[95, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['regression: scenario 4',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -400},
[[57, 40],
[54, 40],
[54, 40],
[50, 40],
[55, 40],
[52, 40],
[53, 40],
[50, 40],
[59, 40],
[50, 40],
[51, 40],
[57, 40],
[73, 40],
[67, 40],
[15, 40],
[71, 40],
[65, 40],
[74, 40]]],
[[17, False, False],
[31, False, False],
[45, False, False],
[55, False, False],
[70, False, False],
[82, False, False],
[95, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[75, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]]],
[['regression: scenario 2',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -300, 'floor': -400},
[[52, 40],
[102, 40],
[104, 40],
[97, 40],
[46, 40],
[49, 40],
[53, 40],
[53, 40],
[51, 40],
[50, 40],
[47, 40],
[52, 40]]],
[[12, False, False],
[74, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['regression: scenario 5',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -300, 'floor': -250},
[[103, 40],
[99, 40],
[104, 40],
[101, 40],
[48, 40],
[50, 40],
[46, 40],
[45, 40],
[45, 40],
[30, 40],
[24, 40],
[24, 40],
[98, 40],
[99, 40],
[98, 40],
[95, 40],
[101, 40],
[97, 40],
[99, 40],
[104, 40],
[99, 40],
[99, 40],
[49, 40],
[46, 40]]],
[[63, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[90, False, False],
[74, False, False],
[58, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['control: deficit and recovery',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40]]],
[[-20, False, False],
[-40, False, False],
[-60, True, False],
[-80, True, False],
[-100, True, True],
[-120, True, True],
[-140, True, True],
[-120, True, True],
[-100, True, True],
[-80, True, True],
[-60, True, False],
[-40, True, False],
[-20, True, False],
[0, False, False]]],
['regression: long surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40]]],
[[30, False, False],
[60, False, False],
[90, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[80, False, False],
[60, False, False],
[40, False, False],
[20, False, False],
[0, False, False]]],
['regression: deep deficit floor',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [80, 40], [80, 40], [80, 40], [80, 40]]],
[[-40, False, False],
[-80, True, False],
[-120, True, True],
[-150, True, True],
[-150, True, True],
[-150, True, True],
[-110, True, True],
[-70, True, True],
[-30, True, False],
[10, False, False]]],
['control: start then immediate surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [20, 40], [70, 40], [70, 40], [45, 40]]],
[[-40, False, False], [-60, True, False], [-30, True, False], [0, False, False], [5, False, False]]],
['regression: scenario 1',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -300, 'floor': -400},
[[55, 40],
[51, 40],
[74, 40],
[47, 40],
[27, 40],
[24, 40],
[105, 40],
[55, 40],
[46, 40],
[45, 40],
[55, 40],
[53, 40],
[101, 40],
[105, 40],
[95, 40],
[54, 40]]],
[[15, False, False],
[26, False, False],
[60, False, False],
[67, False, False],
[54, False, False],
[38, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['regression: scenario 3',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -400},
[[102, 40],
[98, 40],
[95, 40],
[51, 40],
[53, 40],
[52, 40],
[51, 40],
[53, 40],
[53, 40],
[52, 40],
[46, 40],
[53, 40],
[47, 40],
[46, 40],
[46, 40]]],
[[62, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]]],
[['regression: scenario 5',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -300, 'floor': -400},
[[16, 40],
[10, 40],
[17, 40],
[20, 40],
[11, 40],
[20, 40],
[104, 40],
[102, 40],
[103, 40],
[97, 40],
[101, 40],
[102, 40],
[95, 40],
[103, 40],
[99, 40],
[101, 40],
[17, 40],
[17, 40],
[14, 40],
[67, 40],
[72, 40],
[74, 40]]],
[[-24, False, False],
[-54, False, False],
[-77, True, False],
[-97, True, False],
[-126, True, False],
[-146, True, False],
[-82, True, False],
[-20, True, False],
[43, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[77, False, False],
[54, False, False],
[28, False, False],
[55, False, False],
[87, False, False],
[100, False, False]]],
['regression: scenario 11',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -300, 'floor': -250},
[[56, 40],
[54, 40],
[53, 40],
[100, 40],
[101, 40],
[104, 40],
[72, 40],
[69, 40],
[71, 40],
[65, 40],
[71, 40],
[73, 40],
[102, 40],
[47, 40],
[55, 40],
[47, 40],
[54, 40],
[49, 40],
[47, 40],
[52, 40],
[51, 40],
[54, 40],
[50, 40]]],
[[16, False, False],
[30, False, False],
[43, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['control: deficit and recovery',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40],
[60, 40]]],
[[-20, False, False],
[-40, False, False],
[-60, True, False],
[-80, True, False],
[-100, True, True],
[-120, True, True],
[-140, True, True],
[-120, True, True],
[-100, True, True],
[-80, True, True],
[-60, True, False],
[-40, True, False],
[-20, True, False],
[0, False, False]]],
['regression: long surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[70, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40],
[20, 40]]],
[[30, False, False],
[60, False, False],
[90, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[80, False, False],
[60, False, False],
[40, False, False],
[20, False, False],
[0, False, False]]],
['regression: deep deficit floor',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [0, 40], [80, 40], [80, 40], [80, 40], [80, 40]]],
[[-40, False, False],
[-80, True, False],
[-120, True, True],
[-150, True, True],
[-150, True, True],
[-150, True, True],
[-110, True, True],
[-70, True, True],
[-30, True, False],
[10, False, False]]],
['control: start then immediate surplus',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -100, 'floor': -150},
[[0, 40], [20, 40], [70, 40], [70, 40], [45, 40]]],
[[-40, False, False], [-60, True, False], [-30, True, False], [0, False, False], [5, False, False]]],
['regression: scenario 1',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -400},
[[67, 40],
[73, 40],
[101, 40],
[96, 40],
[104, 40],
[99, 40],
[101, 40],
[98, 40],
[95, 40],
[95, 40],
[65, 40],
[71, 40]]],
[[27, False, False],
[60, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False],
[100, False, False]]],
['control: scenario 2',
[{'start_dm': -60, 'stop_dm': 0, 'aux_dm': -150, 'floor': -250},
[[20, 40], [25, 40], [21, 40], [22, 40], [26, 40], [25, 40], [26, 40], [24, 40], [73, 40], [71, 40]]],
[[-20, False, False],
[-35, False, False],
[-54, False, False],
[-72, True, False],
[-86, True, False],
[-101, True, False],
[-115, True, False],
[-131, True, False],
[-98, True, False],
[-67, True, False]]]]]
for label, args, expected in fixtures[N-1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| regression: long surplus | [[30, False, False], [60, False, False], [90, False, False], [100, False, False], [100, False, False], [100, False, False], [80, False, False], [60, False, False], [40, False, False], [20, False, False], [0, False, False]] | [[30, False, False], [60, False, False], [90, False, False], [100, False, False], [100, False, False], [100, False, False], [80, False, False], [60, False, False], [40, False, False], [20, False, False], [0, False, False]] | Passed |
| regression: scenario 1 | [[-29, False, False], [-19, False, False], [-10, False, False], [3, False, False], [12, False, False], [43, False, False], [100, False, False], [100, False, False], [77, False, False], [50, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False]] | [[-29, False, False], [-19, False, False], [-10, False, False], [3, False, False], [12, False, False], [43, False, False], [100, False, False], [100, False, False], [77, False, False], [50, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False]] | Passed |
| control: deficit and recovery | [[-20, False, False], [-40, False, False], [-60, True, False], [-80, True, False], [-100, True, True], [-120, True, True], [-140, True, True], [-120, True, True], [-100, True, True], [-80, True, True], [-60, True, False], [-40, True, False], [-20, True, False], [0, False, False]] | [[-20, False, False], [-40, False, False], [-60, True, False], [-80, True, False], [-100, True, True], [-120, True, True], [-140, True, True], [-120, True, True], [-100, True, True], [-80, True, True], [-60, True, False], [-40, True, False], [-20, True, False], [0, False, False]] | Passed |
| regression: deep deficit floor | [[-40, False, False], [-80, True, False], [-120, True, True], [-150, True, True], [-150, True, True], [-150, True, True], [-110, True, True], [-70, True, True], [-30, True, False], [10, False, False]] | [[-40, False, False], [-80, True, False], [-120, True, True], [-150, True, True], [-150, True, True], [-150, True, True], [-110, True, True], [-70, True, True], [-30, True, False], [10, False, False]] | Passed |
| control: start then immediate surplus | [[-40, False, False], [-60, True, False], [-30, True, False], [0, False, False], [5, False, False]] | [[-40, False, False], [-60, True, False], [-30, True, False], [0, False, False], [5, False, False]] | Passed |
| regression: scenario 2 | [[27, False, False], [54, False, False], [87, False, False], [100, False, False], [71, False, False], [50, False, False], [79, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False]] | [[27, False, False], [54, False, False], [87, False, False], [100, False, False], [71, False, False], [50, False, False], [79, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False]] | Passed |
| regression: scenario 3 | [[31, False, False], [66, False, False], [98, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [90, False, False], [68, False, False], [47, False, False], [19, False, False], [-5, False, False], [-35, False, False], [-57, False, False], [-79, True, False], [-101, True, False], [-69, True, False], [-89, True, False], [-109, True, False], [-132, True, False]] | [[31, False, False], [66, False, False], [98, False, False], [100, False, False], [100, False, False], [100, False, False], [100, False, False], [90, False, False], [68, False, False], [47, False, False], [19, False, False], [-5, False, False], [-35, False, False], [-57, False, False], [-79, True, False], [-101, True, False], [-69, True, False], [-89, True, False], [-109, True, False], [-132, True, False]] | Passed |
| regression: scenario 4 | [[-13, False, False], [-30, False, False], [-42, False, False], [-15, False, False], [41, False, False], [100, False, False], [78, False, False], [49, False, False], [25, False, False], [3, False, False], [-24, False, False], [-48, False, False], [-70, True, False], [-94, True, False], [-117, True, False], [-147, True, False], [-172, True, True]] | [[-13, False, False], [-30, False, False], [-42, False, False], [-15, False, False], [41, False, False], [100, False, False], [78, False, False], [49, False, False], [25, False, False], [3, False, False], [-24, False, False], [-48, False, False], [-70, True, False], [-94, True, False], [-117, True, False], [-147, True, False], [-172, True, True]] | Passed |
SHA-256 / a6d709255e24d5f6f64f2ac079e095fb2c81108443801a54bae23b9a7a1cd450
Verification & scope
A deterministic bounded teaching model of one thermostat or HVAC controller decision evaluated per sample. Temperatures are integer tenths of a degree Fahrenheit unless stated otherwise. The contract is a stipulated toy convention, not a claim of conformance to any manufacturer, ASHRAE guideline or code. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:51:47.815585+00:00.
Case digest / 798a289a9e3df7557fec8e2ceceb48d028196bcfec312656354d4a307821a56d