FA-92826 / HVAC thermostat control / Open access
Mode run timer is not restarted on a forced switch · case 01
After the first forced changeover the system flips between heat and cool every minute.
ROOT CAUSE
The forced switch does not reset the mode start time.
VERIFIED REPAIR
Restart the run timer when switching modes.
Unsuccessful approach: Advancing the timer by max_run still ping-pongs when the switch happened late.
Case contract
Zoned single-unit system arbitration per minute; each sample maps zone -> heat, cool or None. When idle the system picks the mode with more calling zones (ties go to heat). A mode ends when no zone calls for it, and a new mode may be chosen in the same minute. If zones call for the opposite mode, the system switches once the current mode has run max_run minutes, restarting the run timer. Dampers open only for zones calling the active mode. Return [mode, sorted open zones] 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(max_run, samples):
mode = None
since = 0
out = []
for minute, calls in enumerate(samples):
heat = sorted(z for z, c in calls.items() if c == 'heat')
cool = sorted(z for z, c in calls.items() if c == 'cool')
want = {'heat': heat, 'cool': cool}
if mode is not None:
other = 'cool' if mode == 'heat' else 'heat'
if not want[mode]:
mode = None
elif want[other] and minute - since >= max_run:
mode = other
if mode is None and (heat or cool):
mode = 'heat' if len(heat) >= len(cool) else 'cool'
since = minute
out.append([mode, want[mode] if mode else []])
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: ping pong guard',
[2,
[{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'}]],
[['heat', ['a']],
['heat', ['a']],
['cool', ['b']],
['cool', ['b']],
['heat', ['a']],
['heat', ['a']],
['cool', ['b']]]],
['regression: scenario 3',
[2,
[{'z1': 'cool', 'z2': 'heat', 'z3': 'cool', 'z4': None},
{'z2': 'cool', 'z3': 'cool', 'z4': None},
{'z1': 'cool', 'z2': 'cool', 'z3': 'cool', 'z4': None},
{'z1': 'cool', 'z2': 'heat', 'z3': 'cool'},
{'z1': 'cool', 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z2': 'cool', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z3': 'cool', 'z4': None},
{'z1': 'cool', 'z3': 'heat', 'z4': None},
{'z1': 'cool', 'z2': None, 'z3': 'heat'},
{'z1': 'cool', 'z3': 'heat'}]],
[['cool', ['z1', 'z3']],
['cool', ['z2', 'z3']],
['cool', ['z1', 'z2', 'z3']],
['heat', ['z2']],
['heat', ['z2', 'z4']],
['cool', ['z1', 'z2', 'z3']],
['cool', ['z1', 'z3']],
['heat', ['z3']],
['heat', ['z3']],
['cool', ['z1']]]],
['control: majority then forced switch',
[3,
[{'a': 'heat', 'b': 'cool', 'c': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat'},
{}]],
[['cool', ['b', 'c']], ['cool', ['b']], ['cool', ['b']], ['heat', ['a']], ['heat', ['a']], [None, []]]],
['control: tie goes to heat',
[2, [{'a': 'heat', 'b': 'cool'}, {'a': 'heat', 'b': 'cool'}, {'b': 'cool'}]],
[['heat', ['a']], ['heat', ['a']], ['cool', ['b']]]],
['control: satisfied then opposite',
[5, [{'a': 'cool'}, {'a': 'cool', 'b': 'heat'}, {'b': 'heat'}, {'b': 'heat'}]],
[['cool', ['a']], ['cool', ['a']], ['heat', ['b']], ['heat', ['b']]]],
['control: first minute call',
[3, [{'a': 'cool'}, {'a': 'cool'}, {}]],
[['cool', ['a']], ['cool', ['a']], [None, []]]],
['regression: scenario 1',
[5,
[{'z1': 'cool', 'z3': None, 'z4': None},
{'z1': 'heat', 'z2': 'heat', 'z3': None, 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'cool', 'z3': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'cool', 'z3': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'cool', 'z3': None, 'z4': 'cool'},
{'z2': 'cool', 'z4': 'heat'},
{'z1': None, 'z2': 'cool', 'z3': 'heat', 'z4': 'heat'}]],
[['cool', ['z1']],
['cool', ['z4']],
['cool', ['z4']],
['cool', ['z4']],
['cool', ['z2', 'z3', 'z4']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z4']],
['heat', ['z3', 'z4']]]],
['regression: scenario 2',
[5,
[{'z1': 'cool', 'z2': None, 'z3': 'cool'},
{'z1': 'cool', 'z2': None, 'z3': 'cool'},
{'z1': 'cool', 'z3': 'cool'},
{'z1': 'cool', 'z2': None, 'z3': 'cool'},
{'z1': 'cool', 'z2': None, 'z3': 'cool'},
{'z1': 'cool', 'z3': 'heat', 'z4': None},
{'z1': 'cool', 'z2': None, 'z3': 'heat'},
{'z1': 'cool', 'z2': None, 'z3': 'heat'},
{'z1': 'heat'},
{'z1': 'heat', 'z2': None, 'z4': None},
{'z1': 'heat', 'z4': None},
{'z1': 'heat', 'z2': None, 'z4': None},
{'z1': 'heat', 'z3': 'heat', 'z4': None}]],
[['cool', ['z1', 'z3']],
['cool', ['z1', 'z3']],
['cool', ['z1', 'z3']],
['cool', ['z1', 'z3']],
['cool', ['z1', 'z3']],
['heat', ['z3']],
['heat', ['z3']],
['heat', ['z3']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z1', 'z3']]]]],
[['regression: scenario 2',
[3,
[{'z1': None, 'z2': 'cool', 'z3': 'heat', 'z4': 'heat'},
{'z3': 'heat', 'z4': 'heat'},
{'z1': None, 'z2': None, 'z3': 'cool', 'z4': 'cool'},
{'z3': 'cool'},
{'z2': None, 'z3': 'cool', 'z4': None},
{'z1': 'heat', 'z2': 'cool', 'z3': 'cool'},
{'z1': 'cool', 'z2': 'cool', 'z3': 'cool', 'z4': None},
{'z1': 'cool', 'z2': 'cool', 'z3': 'cool'},
{'z1': 'cool', 'z2': 'cool', 'z3': 'cool'},
{'z1': 'cool', 'z2': 'cool', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z2': 'cool', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z2': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z2': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'cool', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'cool', 'z3': 'cool', 'z4': 'heat'}]],
[['heat', ['z3', 'z4']],
['heat', ['z3', 'z4']],
['cool', ['z3', 'z4']],
['cool', ['z3']],
['cool', ['z3']],
['heat', ['z1']],
['cool', ['z1', 'z2', 'z3']],
['cool', ['z1', 'z2', 'z3']],
['cool', ['z1', 'z2', 'z3']],
['heat', ['z4']],
['heat', ['z4']],
['heat', ['z4']],
['cool', ['z1', 'z2']],
['cool', ['z2', 'z3']],
['cool', ['z2', 'z3']]]],
['regression: scenario 10',
[2,
[{'z1': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z2': None, 'z3': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z3': 'cool', 'z4': 'heat'},
{'z2': None, 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': None, 'z3': 'heat'},
{'z1': 'cool', 'z3': 'heat', 'z4': None},
{'z1': 'cool', 'z2': None, 'z3': 'heat', 'z4': None},
{'z1': 'cool', 'z3': 'heat', 'z4': 'cool'},
{'z1': 'cool', 'z2': None, 'z3': 'heat', 'z4': 'cool'},
{'z1': 'cool', 'z3': 'heat', 'z4': 'cool'},
{'z1': 'cool', 'z3': 'heat', 'z4': None},
{'z1': 'cool', 'z3': 'heat', 'z4': None},
{'z1': 'cool', 'z3': 'heat'},
{'z1': 'cool', 'z3': 'heat', 'z4': None}]],
[['heat', ['z4']],
['heat', ['z4']],
['cool', ['z1', 'z3']],
['cool', ['z1', 'z3']],
['heat', ['z4']],
['heat', ['z1', 'z4']],
['heat', ['z1', 'z3']],
['cool', ['z1']],
['cool', ['z1']],
['heat', ['z3']],
['heat', ['z3']],
['cool', ['z1', 'z4']],
['cool', ['z1']],
['heat', ['z3']],
['heat', ['z3']],
['cool', ['z1']]]],
['control: majority then forced switch',
[3,
[{'a': 'heat', 'b': 'cool', 'c': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat'},
{}]],
[['cool', ['b', 'c']], ['cool', ['b']], ['cool', ['b']], ['heat', ['a']], ['heat', ['a']], [None, []]]],
['control: tie goes to heat',
[2, [{'a': 'heat', 'b': 'cool'}, {'a': 'heat', 'b': 'cool'}, {'b': 'cool'}]],
[['heat', ['a']], ['heat', ['a']], ['cool', ['b']]]],
['regression: ping pong guard',
[2,
[{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'}]],
[['heat', ['a']],
['heat', ['a']],
['cool', ['b']],
['cool', ['b']],
['heat', ['a']],
['heat', ['a']],
['cool', ['b']]]],
['control: satisfied then opposite',
[5, [{'a': 'cool'}, {'a': 'cool', 'b': 'heat'}, {'b': 'heat'}, {'b': 'heat'}]],
[['cool', ['a']], ['cool', ['a']], ['heat', ['b']], ['heat', ['b']]]],
['control: first minute call',
[3, [{'a': 'cool'}, {'a': 'cool'}, {}]],
[['cool', ['a']], ['cool', ['a']], [None, []]]],
['control: scenario 1',
[3,
[{'z1': 'heat', 'z2': 'cool', 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': None, 'z3': 'heat', 'z4': 'heat'},
{'z1': None, 'z2': None, 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': None, 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': None, 'z3': 'heat', 'z4': 'cool'},
{'z1': 'heat', 'z2': None, 'z3': 'heat', 'z4': None},
{'z1': 'heat', 'z3': 'heat', 'z4': None},
{'z1': 'heat', 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': None, 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool'}]],
[['heat', ['z1', 'z3', 'z4']],
['heat', ['z1', 'z3', 'z4']],
['heat', ['z1', 'z3', 'z4']],
['heat', ['z3', 'z4']],
['heat', ['z1', 'z3', 'z4']],
['heat', ['z1', 'z3', 'z4']],
['cool', ['z4']],
['heat', ['z1', 'z3']],
['heat', ['z1', 'z3']],
['heat', ['z1', 'z3', 'z4']],
['heat', ['z1', 'z3', 'z4']],
['heat', ['z1', 'z2', 'z4']],
['heat', ['z1', 'z2']],
['heat', ['z1', 'z2', 'z3']],
['cool', ['z3']]]]],
[['regression: scenario 2',
[2,
[{'z1': 'heat', 'z3': 'cool', 'z4': 'cool'},
{'z1': 'cool', 'z2': None, 'z3': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z2': None, 'z3': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z4': 'heat'},
{'z1': None, 'z2': 'cool', 'z3': None, 'z4': 'heat'},
{'z1': None, 'z2': 'cool', 'z3': None, 'z4': 'heat'},
{'z2': 'cool', 'z4': 'heat'},
{'z3': None}]],
[['cool', ['z3', 'z4']],
['cool', ['z1', 'z3']],
['heat', ['z4']],
['heat', ['z4']],
['cool', ['z2']],
['cool', ['z2']],
['heat', ['z4']],
[None, []]]],
['regression: scenario 11',
[2,
[{'z1': 'heat', 'z2': 'heat', 'z3': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'cool', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': None, 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': None, 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z4': 'cool'}]],
[['heat', ['z1', 'z2', 'z3']],
['heat', ['z1', 'z2', 'z3']],
['heat', ['z1', 'z2', 'z3', 'z4']],
['heat', ['z1', 'z2', 'z3', 'z4']],
['heat', ['z1', 'z2', 'z3', 'z4']],
['cool', ['z3']],
['cool', ['z2', 'z3']],
['heat', ['z1']],
['heat', ['z1', 'z2']],
['cool', ['z4']],
['cool', ['z4']],
['heat', ['z1', 'z2']],
['heat', ['z1', 'z2']]]],
['control: majority then forced switch',
[3,
[{'a': 'heat', 'b': 'cool', 'c': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat'},
{}]],
[['cool', ['b', 'c']], ['cool', ['b']], ['cool', ['b']], ['heat', ['a']], ['heat', ['a']], [None, []]]],
['control: tie goes to heat',
[2, [{'a': 'heat', 'b': 'cool'}, {'a': 'heat', 'b': 'cool'}, {'b': 'cool'}]],
[['heat', ['a']], ['heat', ['a']], ['cool', ['b']]]],
['regression: ping pong guard',
[2,
[{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'}]],
[['heat', ['a']],
['heat', ['a']],
['cool', ['b']],
['cool', ['b']],
['heat', ['a']],
['heat', ['a']],
['cool', ['b']]]],
['control: satisfied then opposite',
[5, [{'a': 'cool'}, {'a': 'cool', 'b': 'heat'}, {'b': 'heat'}, {'b': 'heat'}]],
[['cool', ['a']], ['cool', ['a']], ['heat', ['b']], ['heat', ['b']]]],
['control: first minute call',
[3, [{'a': 'cool'}, {'a': 'cool'}, {}]],
[['cool', ['a']], ['cool', ['a']], [None, []]]],
['regression: scenario 1',
[3,
[{'z1': 'heat', 'z2': 'heat', 'z3': None, 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': None},
{'z1': 'heat', 'z2': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': None, 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': None, 'z4': None}]],
[['heat', ['z1', 'z2']],
['heat', ['z1', 'z2']],
['heat', ['z1', 'z2']],
['cool', ['z3', 'z4']],
['cool', ['z3']],
['cool', ['z3']],
['heat', ['z1', 'z2', 'z4']],
['heat', ['z1', 'z2']],
['heat', ['z1', 'z2']],
['cool', ['z4']],
['heat', ['z1', 'z2']]]]],
[['regression: scenario 4',
[5,
[{'z1': None, 'z2': None, 'z3': 'cool', 'z4': None},
{'z1': None, 'z3': 'cool'},
{'z3': 'cool'},
{'z3': 'cool'},
{'z2': None, 'z3': 'cool'},
{'z2': 'cool', 'z3': 'cool'},
{'z1': None, 'z2': 'cool', 'z3': 'heat'},
{'z2': 'cool', 'z3': 'heat'},
{'z1': None, 'z2': 'cool', 'z3': None},
{'z2': 'cool', 'z3': None}]],
[['cool', ['z3']],
['cool', ['z3']],
['cool', ['z3']],
['cool', ['z3']],
['cool', ['z3']],
['cool', ['z2', 'z3']],
['heat', ['z3']],
['heat', ['z3']],
['cool', ['z2']],
['cool', ['z2']]]],
['regression: scenario 23',
[3,
[{'z1': 'heat', 'z3': None, 'z4': 'cool'},
{'z1': 'heat', 'z3': None, 'z4': 'cool'},
{'z1': 'cool', 'z2': None, 'z3': None, 'z4': 'cool'},
{'z1': 'cool', 'z2': None, 'z3': None, 'z4': 'cool'},
{'z1': 'heat', 'z3': 'heat', 'z4': None},
{'z1': 'heat', 'z2': None, 'z4': None},
{'z1': 'heat', 'z2': None, 'z3': None, 'z4': None},
{'z1': 'heat', 'z2': 'heat', 'z3': None, 'z4': None},
{'z1': 'heat', 'z2': 'heat', 'z3': None, 'z4': None},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat', 'z4': None}]],
[['heat', ['z1']],
['heat', ['z1']],
['cool', ['z1', 'z4']],
['cool', ['z1', 'z4']],
['heat', ['z1', 'z3']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z1', 'z2']],
['heat', ['z1', 'z2']],
['cool', ['z3', 'z4']],
['cool', ['z3']],
['heat', ['z1', 'z2', 'z3']]]],
['control: majority then forced switch',
[3,
[{'a': 'heat', 'b': 'cool', 'c': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat'},
{}]],
[['cool', ['b', 'c']], ['cool', ['b']], ['cool', ['b']], ['heat', ['a']], ['heat', ['a']], [None, []]]],
['control: tie goes to heat',
[2, [{'a': 'heat', 'b': 'cool'}, {'a': 'heat', 'b': 'cool'}, {'b': 'cool'}]],
[['heat', ['a']], ['heat', ['a']], ['cool', ['b']]]],
['regression: ping pong guard',
[2,
[{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'}]],
[['heat', ['a']],
['heat', ['a']],
['cool', ['b']],
['cool', ['b']],
['heat', ['a']],
['heat', ['a']],
['cool', ['b']]]],
['control: satisfied then opposite',
[5, [{'a': 'cool'}, {'a': 'cool', 'b': 'heat'}, {'b': 'heat'}, {'b': 'heat'}]],
[['cool', ['a']], ['cool', ['a']], ['heat', ['b']], ['heat', ['b']]]],
['control: first minute call',
[3, [{'a': 'cool'}, {'a': 'cool'}, {}]],
[['cool', ['a']], ['cool', ['a']], [None, []]]],
['regression: scenario 1',
[5,
[{'z1': 'cool', 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': None, 'z3': 'cool', 'z4': 'heat'},
{'z1': None, 'z3': 'cool', 'z4': 'heat'},
{'z1': None, 'z2': None, 'z3': 'cool', 'z4': 'heat'},
{'z1': None, 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z2': 'heat', 'z4': 'heat'},
{'z1': None, 'z2': 'heat', 'z4': 'heat'},
{'z2': 'heat', 'z3': 'cool', 'z4': 'cool'},
{'z2': 'heat', 'z3': 'cool', 'z4': 'cool'},
{'z2': 'heat', 'z3': 'heat', 'z4': 'cool'}]],
[['heat', ['z2', 'z4']],
['heat', ['z2', 'z4']],
['heat', ['z4']],
['heat', ['z4']],
['heat', ['z4']],
['cool', ['z3']],
['cool', ['z1']],
['heat', ['z2', 'z4']],
['heat', ['z2']],
['heat', ['z2']],
['heat', ['z2', 'z3']]]]],
[['regression: scenario 4',
[5,
[{'z1': None, 'z3': None, 'z4': None},
{'z1': None, 'z3': None, 'z4': None},
{'z3': 'cool'},
{'z2': None, 'z3': 'cool', 'z4': None},
{'z1': None, 'z3': 'cool', 'z4': 'heat'},
{'z3': 'cool', 'z4': 'heat'},
{'z1': None, 'z2': None, 'z3': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': None, 'z3': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': None, 'z3': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': None, 'z3': 'cool'},
{'z1': 'heat', 'z2': None, 'z3': 'cool', 'z4': None},
{'z1': 'heat', 'z2': None, 'z3': 'cool'},
{'z1': 'heat', 'z2': None, 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': None, 'z3': 'heat', 'z4': 'heat'}]],
[[None, []],
[None, []],
['cool', ['z3']],
['cool', ['z3']],
['cool', ['z3']],
['cool', ['z3']],
['cool', ['z3', 'z4']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z1', 'z3', 'z4']],
['heat', ['z1', 'z3', 'z4']]]],
['regression: scenario 25',
[2,
[{'z1': 'cool', 'z2': 'heat', 'z3': 'heat', 'z4': 'cool'},
{'z1': 'cool', 'z2': 'heat', 'z3': 'heat', 'z4': None},
{'z2': 'heat', 'z3': 'heat'},
{'z1': None, 'z2': 'cool', 'z3': 'heat'},
{'z1': None, 'z2': 'cool', 'z3': 'heat'},
{'z1': 'cool', 'z2': 'cool'},
{'z1': 'cool', 'z2': 'cool', 'z3': None, 'z4': None},
{'z1': 'cool', 'z2': 'cool', 'z3': None, 'z4': None},
{'z1': 'cool', 'z2': 'cool', 'z3': None, 'z4': 'heat'},
{'z1': 'cool', 'z2': 'cool', 'z3': None},
{'z1': 'cool', 'z2': 'cool', 'z3': 'cool', 'z4': 'cool'},
{'z1': 'cool', 'z2': 'cool', 'z3': 'cool', 'z4': 'cool'},
{'z1': 'cool', 'z2': 'cool', 'z4': 'cool'},
{'z1': 'cool', 'z2': 'cool', 'z4': 'heat'}]],
[['heat', ['z2', 'z3']],
['heat', ['z2', 'z3']],
['heat', ['z2', 'z3']],
['cool', ['z2']],
['cool', ['z2']],
['cool', ['z1', 'z2']],
['cool', ['z1', 'z2']],
['cool', ['z1', 'z2']],
['heat', ['z4']],
['cool', ['z1', 'z2']],
['cool', ['z1', 'z2', 'z3', 'z4']],
['cool', ['z1', 'z2', 'z3', 'z4']],
['cool', ['z1', 'z2', 'z4']],
['heat', ['z4']]]],
['control: majority then forced switch',
[3,
[{'a': 'heat', 'b': 'cool', 'c': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat'},
{}]],
[['cool', ['b', 'c']], ['cool', ['b']], ['cool', ['b']], ['heat', ['a']], ['heat', ['a']], [None, []]]],
['control: tie goes to heat',
[2, [{'a': 'heat', 'b': 'cool'}, {'a': 'heat', 'b': 'cool'}, {'b': 'cool'}]],
[['heat', ['a']], ['heat', ['a']], ['cool', ['b']]]],
['regression: ping pong guard',
[2,
[{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'}]],
[['heat', ['a']],
['heat', ['a']],
['cool', ['b']],
['cool', ['b']],
['heat', ['a']],
['heat', ['a']],
['cool', ['b']]]],
['control: satisfied then opposite',
[5, [{'a': 'cool'}, {'a': 'cool', 'b': 'heat'}, {'b': 'heat'}, {'b': 'heat'}]],
[['cool', ['a']], ['cool', ['a']], ['heat', ['b']], ['heat', ['b']]]],
['control: first minute call',
[3, [{'a': 'cool'}, {'a': 'cool'}, {}]],
[['cool', ['a']], ['cool', ['a']], [None, []]]],
['regression: scenario 1',
[3,
[{'z1': 'heat', 'z2': 'heat', 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z2': 'heat'},
{'z2': 'heat', 'z4': 'heat'},
{'z1': None, 'z2': 'heat', 'z3': None, 'z4': 'heat'},
{'z2': 'heat', 'z3': None, 'z4': 'heat'}]],
[['heat', ['z1', 'z2', 'z3', 'z4']],
['heat', ['z1', 'z2', 'z3']],
['heat', ['z1', 'z2', 'z3', 'z4']],
['cool', ['z3']],
['cool', ['z3']],
['heat', ['z2']],
['heat', ['z2', 'z4']],
['heat', ['z2', 'z4']],
['heat', ['z2', 'z4']]]]]]
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: ping pong guard | [['heat', ['a']], ['heat', ['a']], ['cool', ['b']], ['heat', ['a']], ['cool', ['b']], ['heat', ['a']], ['cool', ['b']]] | [['heat', ['a']], ['heat', ['a']], ['cool', ['b']], ['cool', ['b']], ['heat', ['a']], ['heat', ['a']], ['cool', ['b']]] | Failed |
| regression: scenario 3 | [['cool', ['z1', 'z3']], ['cool', ['z2', 'z3']], ['cool', ['z1', 'z2', 'z3']], ['heat', ['z2']], ['cool', ['z1', 'z3']], ['heat', ['z4']], ['cool', ['z1', 'z3']], ['cool', ['z1']], ['heat', ['z3']], ['cool', ['z1']]] | [['cool', ['z1', 'z3']], ['cool', ['z2', 'z3']], ['cool', ['z1', 'z2', 'z3']], ['heat', ['z2']], ['heat', ['z2', 'z4']], ['cool', ['z1', 'z2', 'z3']], ['cool', ['z1', 'z3']], ['heat', ['z3']], ['heat', ['z3']], ['cool', ['z1']]] | Failed |
| control: majority then forced switch | [['cool', ['b', 'c']], ['cool', ['b']], ['cool', ['b']], ['heat', ['a']], ['heat', ['a']], [None, []]] | [['cool', ['b', 'c']], ['cool', ['b']], ['cool', ['b']], ['heat', ['a']], ['heat', ['a']], [None, []]] | Passed |
| control: tie goes to heat | [['heat', ['a']], ['heat', ['a']], ['cool', ['b']]] | [['heat', ['a']], ['heat', ['a']], ['cool', ['b']]] | Passed |
| control: satisfied then opposite | [['cool', ['a']], ['cool', ['a']], ['heat', ['b']], ['heat', ['b']]] | [['cool', ['a']], ['cool', ['a']], ['heat', ['b']], ['heat', ['b']]] | Passed |
| control: first minute call | [['cool', ['a']], ['cool', ['a']], [None, []]] | [['cool', ['a']], ['cool', ['a']], [None, []]] | Passed |
| regression: scenario 1 | [['cool', ['z1']], ['cool', ['z4']], ['cool', ['z4']], ['cool', ['z4']], ['cool', ['z2', 'z3', 'z4']], ['heat', ['z1']], ['cool', ['z2', 'z4']], ['heat', ['z1']], ['cool', ['z2']], ['heat', ['z3', 'z4']]] | [['cool', ['z1']], ['cool', ['z4']], ['cool', ['z4']], ['cool', ['z4']], ['cool', ['z2', 'z3', 'z4']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z4']], ['heat', ['z3', 'z4']]] | Failed |
| regression: scenario 2 | [['cool', ['z1', 'z3']], ['cool', ['z1', 'z3']], ['cool', ['z1', 'z3']], ['cool', ['z1', 'z3']], ['cool', ['z1', 'z3']], ['heat', ['z3']], ['cool', ['z1']], ['heat', ['z3']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z1', 'z3']]] | [['cool', ['z1', 'z3']], ['cool', ['z1', 'z3']], ['cool', ['z1', 'z3']], ['cool', ['z1', 'z3']], ['cool', ['z1', 'z3']], ['heat', ['z3']], ['heat', ['z3']], ['heat', ['z3']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z1', 'z3']]] | Failed |
SHA-256 / 0218eea7c5e7068125f377c4df05b907c9359e78a5077cacb05783971da77210
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(max_run, samples):
mode = None
since = 0
out = []
for minute, calls in enumerate(samples):
heat = sorted(z for z, c in calls.items() if c == 'heat')
cool = sorted(z for z, c in calls.items() if c == 'cool')
want = {'heat': heat, 'cool': cool}
if mode is not None:
other = 'cool' if mode == 'heat' else 'heat'
if not want[mode]:
mode = None
elif want[other] and minute - since >= max_run:
mode = other
since = since + max_run
if mode is None and (heat or cool):
mode = 'heat' if len(heat) >= len(cool) else 'cool'
since = minute
out.append([mode, want[mode] if mode else []])
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: ping pong guard',
[2,
[{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'}]],
[['heat', ['a']],
['heat', ['a']],
['cool', ['b']],
['cool', ['b']],
['heat', ['a']],
['heat', ['a']],
['cool', ['b']]]],
['regression: scenario 3',
[2,
[{'z1': 'cool', 'z2': 'heat', 'z3': 'cool', 'z4': None},
{'z2': 'cool', 'z3': 'cool', 'z4': None},
{'z1': 'cool', 'z2': 'cool', 'z3': 'cool', 'z4': None},
{'z1': 'cool', 'z2': 'heat', 'z3': 'cool'},
{'z1': 'cool', 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z2': 'cool', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z3': 'cool', 'z4': None},
{'z1': 'cool', 'z3': 'heat', 'z4': None},
{'z1': 'cool', 'z2': None, 'z3': 'heat'},
{'z1': 'cool', 'z3': 'heat'}]],
[['cool', ['z1', 'z3']],
['cool', ['z2', 'z3']],
['cool', ['z1', 'z2', 'z3']],
['heat', ['z2']],
['heat', ['z2', 'z4']],
['cool', ['z1', 'z2', 'z3']],
['cool', ['z1', 'z3']],
['heat', ['z3']],
['heat', ['z3']],
['cool', ['z1']]]],
['control: majority then forced switch',
[3,
[{'a': 'heat', 'b': 'cool', 'c': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat'},
{}]],
[['cool', ['b', 'c']], ['cool', ['b']], ['cool', ['b']], ['heat', ['a']], ['heat', ['a']], [None, []]]],
['control: tie goes to heat',
[2, [{'a': 'heat', 'b': 'cool'}, {'a': 'heat', 'b': 'cool'}, {'b': 'cool'}]],
[['heat', ['a']], ['heat', ['a']], ['cool', ['b']]]],
['control: satisfied then opposite',
[5, [{'a': 'cool'}, {'a': 'cool', 'b': 'heat'}, {'b': 'heat'}, {'b': 'heat'}]],
[['cool', ['a']], ['cool', ['a']], ['heat', ['b']], ['heat', ['b']]]],
['control: first minute call',
[3, [{'a': 'cool'}, {'a': 'cool'}, {}]],
[['cool', ['a']], ['cool', ['a']], [None, []]]],
['regression: scenario 1',
[5,
[{'z1': 'cool', 'z3': None, 'z4': None},
{'z1': 'heat', 'z2': 'heat', 'z3': None, 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'cool', 'z3': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'cool', 'z3': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'cool', 'z3': None, 'z4': 'cool'},
{'z2': 'cool', 'z4': 'heat'},
{'z1': None, 'z2': 'cool', 'z3': 'heat', 'z4': 'heat'}]],
[['cool', ['z1']],
['cool', ['z4']],
['cool', ['z4']],
['cool', ['z4']],
['cool', ['z2', 'z3', 'z4']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z4']],
['heat', ['z3', 'z4']]]],
['regression: scenario 2',
[5,
[{'z1': 'cool', 'z2': None, 'z3': 'cool'},
{'z1': 'cool', 'z2': None, 'z3': 'cool'},
{'z1': 'cool', 'z3': 'cool'},
{'z1': 'cool', 'z2': None, 'z3': 'cool'},
{'z1': 'cool', 'z2': None, 'z3': 'cool'},
{'z1': 'cool', 'z3': 'heat', 'z4': None},
{'z1': 'cool', 'z2': None, 'z3': 'heat'},
{'z1': 'cool', 'z2': None, 'z3': 'heat'},
{'z1': 'heat'},
{'z1': 'heat', 'z2': None, 'z4': None},
{'z1': 'heat', 'z4': None},
{'z1': 'heat', 'z2': None, 'z4': None},
{'z1': 'heat', 'z3': 'heat', 'z4': None}]],
[['cool', ['z1', 'z3']],
['cool', ['z1', 'z3']],
['cool', ['z1', 'z3']],
['cool', ['z1', 'z3']],
['cool', ['z1', 'z3']],
['heat', ['z3']],
['heat', ['z3']],
['heat', ['z3']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z1', 'z3']]]]],
[['regression: scenario 2',
[3,
[{'z1': None, 'z2': 'cool', 'z3': 'heat', 'z4': 'heat'},
{'z3': 'heat', 'z4': 'heat'},
{'z1': None, 'z2': None, 'z3': 'cool', 'z4': 'cool'},
{'z3': 'cool'},
{'z2': None, 'z3': 'cool', 'z4': None},
{'z1': 'heat', 'z2': 'cool', 'z3': 'cool'},
{'z1': 'cool', 'z2': 'cool', 'z3': 'cool', 'z4': None},
{'z1': 'cool', 'z2': 'cool', 'z3': 'cool'},
{'z1': 'cool', 'z2': 'cool', 'z3': 'cool'},
{'z1': 'cool', 'z2': 'cool', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z2': 'cool', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z2': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z2': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'cool', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'cool', 'z3': 'cool', 'z4': 'heat'}]],
[['heat', ['z3', 'z4']],
['heat', ['z3', 'z4']],
['cool', ['z3', 'z4']],
['cool', ['z3']],
['cool', ['z3']],
['heat', ['z1']],
['cool', ['z1', 'z2', 'z3']],
['cool', ['z1', 'z2', 'z3']],
['cool', ['z1', 'z2', 'z3']],
['heat', ['z4']],
['heat', ['z4']],
['heat', ['z4']],
['cool', ['z1', 'z2']],
['cool', ['z2', 'z3']],
['cool', ['z2', 'z3']]]],
['regression: scenario 10',
[2,
[{'z1': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z2': None, 'z3': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z3': 'cool', 'z4': 'heat'},
{'z2': None, 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': None, 'z3': 'heat'},
{'z1': 'cool', 'z3': 'heat', 'z4': None},
{'z1': 'cool', 'z2': None, 'z3': 'heat', 'z4': None},
{'z1': 'cool', 'z3': 'heat', 'z4': 'cool'},
{'z1': 'cool', 'z2': None, 'z3': 'heat', 'z4': 'cool'},
{'z1': 'cool', 'z3': 'heat', 'z4': 'cool'},
{'z1': 'cool', 'z3': 'heat', 'z4': None},
{'z1': 'cool', 'z3': 'heat', 'z4': None},
{'z1': 'cool', 'z3': 'heat'},
{'z1': 'cool', 'z3': 'heat', 'z4': None}]],
[['heat', ['z4']],
['heat', ['z4']],
['cool', ['z1', 'z3']],
['cool', ['z1', 'z3']],
['heat', ['z4']],
['heat', ['z1', 'z4']],
['heat', ['z1', 'z3']],
['cool', ['z1']],
['cool', ['z1']],
['heat', ['z3']],
['heat', ['z3']],
['cool', ['z1', 'z4']],
['cool', ['z1']],
['heat', ['z3']],
['heat', ['z3']],
['cool', ['z1']]]],
['control: majority then forced switch',
[3,
[{'a': 'heat', 'b': 'cool', 'c': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat'},
{}]],
[['cool', ['b', 'c']], ['cool', ['b']], ['cool', ['b']], ['heat', ['a']], ['heat', ['a']], [None, []]]],
['control: tie goes to heat',
[2, [{'a': 'heat', 'b': 'cool'}, {'a': 'heat', 'b': 'cool'}, {'b': 'cool'}]],
[['heat', ['a']], ['heat', ['a']], ['cool', ['b']]]],
['regression: ping pong guard',
[2,
[{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'}]],
[['heat', ['a']],
['heat', ['a']],
['cool', ['b']],
['cool', ['b']],
['heat', ['a']],
['heat', ['a']],
['cool', ['b']]]],
['control: satisfied then opposite',
[5, [{'a': 'cool'}, {'a': 'cool', 'b': 'heat'}, {'b': 'heat'}, {'b': 'heat'}]],
[['cool', ['a']], ['cool', ['a']], ['heat', ['b']], ['heat', ['b']]]],
['control: first minute call',
[3, [{'a': 'cool'}, {'a': 'cool'}, {}]],
[['cool', ['a']], ['cool', ['a']], [None, []]]],
['control: scenario 1',
[3,
[{'z1': 'heat', 'z2': 'cool', 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': None, 'z3': 'heat', 'z4': 'heat'},
{'z1': None, 'z2': None, 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': None, 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': None, 'z3': 'heat', 'z4': 'cool'},
{'z1': 'heat', 'z2': None, 'z3': 'heat', 'z4': None},
{'z1': 'heat', 'z3': 'heat', 'z4': None},
{'z1': 'heat', 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': None, 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool'}]],
[['heat', ['z1', 'z3', 'z4']],
['heat', ['z1', 'z3', 'z4']],
['heat', ['z1', 'z3', 'z4']],
['heat', ['z3', 'z4']],
['heat', ['z1', 'z3', 'z4']],
['heat', ['z1', 'z3', 'z4']],
['cool', ['z4']],
['heat', ['z1', 'z3']],
['heat', ['z1', 'z3']],
['heat', ['z1', 'z3', 'z4']],
['heat', ['z1', 'z3', 'z4']],
['heat', ['z1', 'z2', 'z4']],
['heat', ['z1', 'z2']],
['heat', ['z1', 'z2', 'z3']],
['cool', ['z3']]]]],
[['regression: scenario 2',
[2,
[{'z1': 'heat', 'z3': 'cool', 'z4': 'cool'},
{'z1': 'cool', 'z2': None, 'z3': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z2': None, 'z3': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z4': 'heat'},
{'z1': None, 'z2': 'cool', 'z3': None, 'z4': 'heat'},
{'z1': None, 'z2': 'cool', 'z3': None, 'z4': 'heat'},
{'z2': 'cool', 'z4': 'heat'},
{'z3': None}]],
[['cool', ['z3', 'z4']],
['cool', ['z1', 'z3']],
['heat', ['z4']],
['heat', ['z4']],
['cool', ['z2']],
['cool', ['z2']],
['heat', ['z4']],
[None, []]]],
['regression: scenario 11',
[2,
[{'z1': 'heat', 'z2': 'heat', 'z3': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'cool', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': None, 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': None, 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z4': 'cool'}]],
[['heat', ['z1', 'z2', 'z3']],
['heat', ['z1', 'z2', 'z3']],
['heat', ['z1', 'z2', 'z3', 'z4']],
['heat', ['z1', 'z2', 'z3', 'z4']],
['heat', ['z1', 'z2', 'z3', 'z4']],
['cool', ['z3']],
['cool', ['z2', 'z3']],
['heat', ['z1']],
['heat', ['z1', 'z2']],
['cool', ['z4']],
['cool', ['z4']],
['heat', ['z1', 'z2']],
['heat', ['z1', 'z2']]]],
['control: majority then forced switch',
[3,
[{'a': 'heat', 'b': 'cool', 'c': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat'},
{}]],
[['cool', ['b', 'c']], ['cool', ['b']], ['cool', ['b']], ['heat', ['a']], ['heat', ['a']], [None, []]]],
['control: tie goes to heat',
[2, [{'a': 'heat', 'b': 'cool'}, {'a': 'heat', 'b': 'cool'}, {'b': 'cool'}]],
[['heat', ['a']], ['heat', ['a']], ['cool', ['b']]]],
['regression: ping pong guard',
[2,
[{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'}]],
[['heat', ['a']],
['heat', ['a']],
['cool', ['b']],
['cool', ['b']],
['heat', ['a']],
['heat', ['a']],
['cool', ['b']]]],
['control: satisfied then opposite',
[5, [{'a': 'cool'}, {'a': 'cool', 'b': 'heat'}, {'b': 'heat'}, {'b': 'heat'}]],
[['cool', ['a']], ['cool', ['a']], ['heat', ['b']], ['heat', ['b']]]],
['control: first minute call',
[3, [{'a': 'cool'}, {'a': 'cool'}, {}]],
[['cool', ['a']], ['cool', ['a']], [None, []]]],
['regression: scenario 1',
[3,
[{'z1': 'heat', 'z2': 'heat', 'z3': None, 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': None},
{'z1': 'heat', 'z2': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': None, 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': None, 'z4': None}]],
[['heat', ['z1', 'z2']],
['heat', ['z1', 'z2']],
['heat', ['z1', 'z2']],
['cool', ['z3', 'z4']],
['cool', ['z3']],
['cool', ['z3']],
['heat', ['z1', 'z2', 'z4']],
['heat', ['z1', 'z2']],
['heat', ['z1', 'z2']],
['cool', ['z4']],
['heat', ['z1', 'z2']]]]],
[['regression: scenario 4',
[5,
[{'z1': None, 'z2': None, 'z3': 'cool', 'z4': None},
{'z1': None, 'z3': 'cool'},
{'z3': 'cool'},
{'z3': 'cool'},
{'z2': None, 'z3': 'cool'},
{'z2': 'cool', 'z3': 'cool'},
{'z1': None, 'z2': 'cool', 'z3': 'heat'},
{'z2': 'cool', 'z3': 'heat'},
{'z1': None, 'z2': 'cool', 'z3': None},
{'z2': 'cool', 'z3': None}]],
[['cool', ['z3']],
['cool', ['z3']],
['cool', ['z3']],
['cool', ['z3']],
['cool', ['z3']],
['cool', ['z2', 'z3']],
['heat', ['z3']],
['heat', ['z3']],
['cool', ['z2']],
['cool', ['z2']]]],
['regression: scenario 23',
[3,
[{'z1': 'heat', 'z3': None, 'z4': 'cool'},
{'z1': 'heat', 'z3': None, 'z4': 'cool'},
{'z1': 'cool', 'z2': None, 'z3': None, 'z4': 'cool'},
{'z1': 'cool', 'z2': None, 'z3': None, 'z4': 'cool'},
{'z1': 'heat', 'z3': 'heat', 'z4': None},
{'z1': 'heat', 'z2': None, 'z4': None},
{'z1': 'heat', 'z2': None, 'z3': None, 'z4': None},
{'z1': 'heat', 'z2': 'heat', 'z3': None, 'z4': None},
{'z1': 'heat', 'z2': 'heat', 'z3': None, 'z4': None},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat', 'z4': None}]],
[['heat', ['z1']],
['heat', ['z1']],
['cool', ['z1', 'z4']],
['cool', ['z1', 'z4']],
['heat', ['z1', 'z3']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z1', 'z2']],
['heat', ['z1', 'z2']],
['cool', ['z3', 'z4']],
['cool', ['z3']],
['heat', ['z1', 'z2', 'z3']]]],
['control: majority then forced switch',
[3,
[{'a': 'heat', 'b': 'cool', 'c': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat'},
{}]],
[['cool', ['b', 'c']], ['cool', ['b']], ['cool', ['b']], ['heat', ['a']], ['heat', ['a']], [None, []]]],
['control: tie goes to heat',
[2, [{'a': 'heat', 'b': 'cool'}, {'a': 'heat', 'b': 'cool'}, {'b': 'cool'}]],
[['heat', ['a']], ['heat', ['a']], ['cool', ['b']]]],
['regression: ping pong guard',
[2,
[{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'}]],
[['heat', ['a']],
['heat', ['a']],
['cool', ['b']],
['cool', ['b']],
['heat', ['a']],
['heat', ['a']],
['cool', ['b']]]],
['control: satisfied then opposite',
[5, [{'a': 'cool'}, {'a': 'cool', 'b': 'heat'}, {'b': 'heat'}, {'b': 'heat'}]],
[['cool', ['a']], ['cool', ['a']], ['heat', ['b']], ['heat', ['b']]]],
['control: first minute call',
[3, [{'a': 'cool'}, {'a': 'cool'}, {}]],
[['cool', ['a']], ['cool', ['a']], [None, []]]],
['regression: scenario 1',
[5,
[{'z1': 'cool', 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': None, 'z3': 'cool', 'z4': 'heat'},
{'z1': None, 'z3': 'cool', 'z4': 'heat'},
{'z1': None, 'z2': None, 'z3': 'cool', 'z4': 'heat'},
{'z1': None, 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z2': 'heat', 'z4': 'heat'},
{'z1': None, 'z2': 'heat', 'z4': 'heat'},
{'z2': 'heat', 'z3': 'cool', 'z4': 'cool'},
{'z2': 'heat', 'z3': 'cool', 'z4': 'cool'},
{'z2': 'heat', 'z3': 'heat', 'z4': 'cool'}]],
[['heat', ['z2', 'z4']],
['heat', ['z2', 'z4']],
['heat', ['z4']],
['heat', ['z4']],
['heat', ['z4']],
['cool', ['z3']],
['cool', ['z1']],
['heat', ['z2', 'z4']],
['heat', ['z2']],
['heat', ['z2']],
['heat', ['z2', 'z3']]]]],
[['regression: scenario 4',
[5,
[{'z1': None, 'z3': None, 'z4': None},
{'z1': None, 'z3': None, 'z4': None},
{'z3': 'cool'},
{'z2': None, 'z3': 'cool', 'z4': None},
{'z1': None, 'z3': 'cool', 'z4': 'heat'},
{'z3': 'cool', 'z4': 'heat'},
{'z1': None, 'z2': None, 'z3': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': None, 'z3': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': None, 'z3': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': None, 'z3': 'cool'},
{'z1': 'heat', 'z2': None, 'z3': 'cool', 'z4': None},
{'z1': 'heat', 'z2': None, 'z3': 'cool'},
{'z1': 'heat', 'z2': None, 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': None, 'z3': 'heat', 'z4': 'heat'}]],
[[None, []],
[None, []],
['cool', ['z3']],
['cool', ['z3']],
['cool', ['z3']],
['cool', ['z3']],
['cool', ['z3', 'z4']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z1', 'z3', 'z4']],
['heat', ['z1', 'z3', 'z4']]]],
['regression: scenario 25',
[2,
[{'z1': 'cool', 'z2': 'heat', 'z3': 'heat', 'z4': 'cool'},
{'z1': 'cool', 'z2': 'heat', 'z3': 'heat', 'z4': None},
{'z2': 'heat', 'z3': 'heat'},
{'z1': None, 'z2': 'cool', 'z3': 'heat'},
{'z1': None, 'z2': 'cool', 'z3': 'heat'},
{'z1': 'cool', 'z2': 'cool'},
{'z1': 'cool', 'z2': 'cool', 'z3': None, 'z4': None},
{'z1': 'cool', 'z2': 'cool', 'z3': None, 'z4': None},
{'z1': 'cool', 'z2': 'cool', 'z3': None, 'z4': 'heat'},
{'z1': 'cool', 'z2': 'cool', 'z3': None},
{'z1': 'cool', 'z2': 'cool', 'z3': 'cool', 'z4': 'cool'},
{'z1': 'cool', 'z2': 'cool', 'z3': 'cool', 'z4': 'cool'},
{'z1': 'cool', 'z2': 'cool', 'z4': 'cool'},
{'z1': 'cool', 'z2': 'cool', 'z4': 'heat'}]],
[['heat', ['z2', 'z3']],
['heat', ['z2', 'z3']],
['heat', ['z2', 'z3']],
['cool', ['z2']],
['cool', ['z2']],
['cool', ['z1', 'z2']],
['cool', ['z1', 'z2']],
['cool', ['z1', 'z2']],
['heat', ['z4']],
['cool', ['z1', 'z2']],
['cool', ['z1', 'z2', 'z3', 'z4']],
['cool', ['z1', 'z2', 'z3', 'z4']],
['cool', ['z1', 'z2', 'z4']],
['heat', ['z4']]]],
['control: majority then forced switch',
[3,
[{'a': 'heat', 'b': 'cool', 'c': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat'},
{}]],
[['cool', ['b', 'c']], ['cool', ['b']], ['cool', ['b']], ['heat', ['a']], ['heat', ['a']], [None, []]]],
['control: tie goes to heat',
[2, [{'a': 'heat', 'b': 'cool'}, {'a': 'heat', 'b': 'cool'}, {'b': 'cool'}]],
[['heat', ['a']], ['heat', ['a']], ['cool', ['b']]]],
['regression: ping pong guard',
[2,
[{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'}]],
[['heat', ['a']],
['heat', ['a']],
['cool', ['b']],
['cool', ['b']],
['heat', ['a']],
['heat', ['a']],
['cool', ['b']]]],
['control: satisfied then opposite',
[5, [{'a': 'cool'}, {'a': 'cool', 'b': 'heat'}, {'b': 'heat'}, {'b': 'heat'}]],
[['cool', ['a']], ['cool', ['a']], ['heat', ['b']], ['heat', ['b']]]],
['control: first minute call',
[3, [{'a': 'cool'}, {'a': 'cool'}, {}]],
[['cool', ['a']], ['cool', ['a']], [None, []]]],
['regression: scenario 1',
[3,
[{'z1': 'heat', 'z2': 'heat', 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z2': 'heat'},
{'z2': 'heat', 'z4': 'heat'},
{'z1': None, 'z2': 'heat', 'z3': None, 'z4': 'heat'},
{'z2': 'heat', 'z3': None, 'z4': 'heat'}]],
[['heat', ['z1', 'z2', 'z3', 'z4']],
['heat', ['z1', 'z2', 'z3']],
['heat', ['z1', 'z2', 'z3', 'z4']],
['cool', ['z3']],
['cool', ['z3']],
['heat', ['z2']],
['heat', ['z2', 'z4']],
['heat', ['z2', 'z4']],
['heat', ['z2', 'z4']]]]]]
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: ping pong guard | [['heat', ['a']], ['heat', ['a']], ['cool', ['b']], ['cool', ['b']], ['heat', ['a']], ['heat', ['a']], ['cool', ['b']]] | [['heat', ['a']], ['heat', ['a']], ['cool', ['b']], ['cool', ['b']], ['heat', ['a']], ['heat', ['a']], ['cool', ['b']]] | Passed |
| regression: scenario 3 | [['cool', ['z1', 'z3']], ['cool', ['z2', 'z3']], ['cool', ['z1', 'z2', 'z3']], ['heat', ['z2']], ['cool', ['z1', 'z3']], ['cool', ['z1', 'z2', 'z3']], ['cool', ['z1', 'z3']], ['heat', ['z3']], ['cool', ['z1']], ['cool', ['z1']]] | [['cool', ['z1', 'z3']], ['cool', ['z2', 'z3']], ['cool', ['z1', 'z2', 'z3']], ['heat', ['z2']], ['heat', ['z2', 'z4']], ['cool', ['z1', 'z2', 'z3']], ['cool', ['z1', 'z3']], ['heat', ['z3']], ['heat', ['z3']], ['cool', ['z1']]] | Failed |
| control: majority then forced switch | [['cool', ['b', 'c']], ['cool', ['b']], ['cool', ['b']], ['heat', ['a']], ['heat', ['a']], [None, []]] | [['cool', ['b', 'c']], ['cool', ['b']], ['cool', ['b']], ['heat', ['a']], ['heat', ['a']], [None, []]] | Passed |
| control: tie goes to heat | [['heat', ['a']], ['heat', ['a']], ['cool', ['b']]] | [['heat', ['a']], ['heat', ['a']], ['cool', ['b']]] | Passed |
| control: satisfied then opposite | [['cool', ['a']], ['cool', ['a']], ['heat', ['b']], ['heat', ['b']]] | [['cool', ['a']], ['cool', ['a']], ['heat', ['b']], ['heat', ['b']]] | Passed |
| control: first minute call | [['cool', ['a']], ['cool', ['a']], [None, []]] | [['cool', ['a']], ['cool', ['a']], [None, []]] | Passed |
| regression: scenario 1 | [['cool', ['z1']], ['cool', ['z4']], ['cool', ['z4']], ['cool', ['z4']], ['cool', ['z2', 'z3', 'z4']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z4']], ['heat', ['z3', 'z4']]] | [['cool', ['z1']], ['cool', ['z4']], ['cool', ['z4']], ['cool', ['z4']], ['cool', ['z2', 'z3', 'z4']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z4']], ['heat', ['z3', 'z4']]] | Passed |
| regression: scenario 2 | [['cool', ['z1', 'z3']], ['cool', ['z1', 'z3']], ['cool', ['z1', 'z3']], ['cool', ['z1', 'z3']], ['cool', ['z1', 'z3']], ['heat', ['z3']], ['heat', ['z3']], ['heat', ['z3']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z1', 'z3']]] | [['cool', ['z1', 'z3']], ['cool', ['z1', 'z3']], ['cool', ['z1', 'z3']], ['cool', ['z1', 'z3']], ['cool', ['z1', 'z3']], ['heat', ['z3']], ['heat', ['z3']], ['heat', ['z3']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z1', 'z3']]] | Passed |
SHA-256 / e298c29c3845813f53c3a5dfd097eab8048c899291f87f3a320f02a6e5f293ea
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(max_run, samples):
mode = None
since = 0
out = []
for minute, calls in enumerate(samples):
heat = sorted(z for z, c in calls.items() if c == 'heat')
cool = sorted(z for z, c in calls.items() if c == 'cool')
want = {'heat': heat, 'cool': cool}
if mode is not None:
other = 'cool' if mode == 'heat' else 'heat'
if not want[mode]:
mode = None
elif want[other] and minute - since >= max_run:
mode = other
since = minute
if mode is None and (heat or cool):
mode = 'heat' if len(heat) >= len(cool) else 'cool'
since = minute
out.append([mode, want[mode] if mode else []])
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: ping pong guard',
[2,
[{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'}]],
[['heat', ['a']],
['heat', ['a']],
['cool', ['b']],
['cool', ['b']],
['heat', ['a']],
['heat', ['a']],
['cool', ['b']]]],
['regression: scenario 3',
[2,
[{'z1': 'cool', 'z2': 'heat', 'z3': 'cool', 'z4': None},
{'z2': 'cool', 'z3': 'cool', 'z4': None},
{'z1': 'cool', 'z2': 'cool', 'z3': 'cool', 'z4': None},
{'z1': 'cool', 'z2': 'heat', 'z3': 'cool'},
{'z1': 'cool', 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z2': 'cool', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z3': 'cool', 'z4': None},
{'z1': 'cool', 'z3': 'heat', 'z4': None},
{'z1': 'cool', 'z2': None, 'z3': 'heat'},
{'z1': 'cool', 'z3': 'heat'}]],
[['cool', ['z1', 'z3']],
['cool', ['z2', 'z3']],
['cool', ['z1', 'z2', 'z3']],
['heat', ['z2']],
['heat', ['z2', 'z4']],
['cool', ['z1', 'z2', 'z3']],
['cool', ['z1', 'z3']],
['heat', ['z3']],
['heat', ['z3']],
['cool', ['z1']]]],
['control: majority then forced switch',
[3,
[{'a': 'heat', 'b': 'cool', 'c': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat'},
{}]],
[['cool', ['b', 'c']], ['cool', ['b']], ['cool', ['b']], ['heat', ['a']], ['heat', ['a']], [None, []]]],
['control: tie goes to heat',
[2, [{'a': 'heat', 'b': 'cool'}, {'a': 'heat', 'b': 'cool'}, {'b': 'cool'}]],
[['heat', ['a']], ['heat', ['a']], ['cool', ['b']]]],
['control: satisfied then opposite',
[5, [{'a': 'cool'}, {'a': 'cool', 'b': 'heat'}, {'b': 'heat'}, {'b': 'heat'}]],
[['cool', ['a']], ['cool', ['a']], ['heat', ['b']], ['heat', ['b']]]],
['control: first minute call',
[3, [{'a': 'cool'}, {'a': 'cool'}, {}]],
[['cool', ['a']], ['cool', ['a']], [None, []]]],
['regression: scenario 1',
[5,
[{'z1': 'cool', 'z3': None, 'z4': None},
{'z1': 'heat', 'z2': 'heat', 'z3': None, 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'cool', 'z3': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'cool', 'z3': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'cool', 'z3': None, 'z4': 'cool'},
{'z2': 'cool', 'z4': 'heat'},
{'z1': None, 'z2': 'cool', 'z3': 'heat', 'z4': 'heat'}]],
[['cool', ['z1']],
['cool', ['z4']],
['cool', ['z4']],
['cool', ['z4']],
['cool', ['z2', 'z3', 'z4']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z4']],
['heat', ['z3', 'z4']]]],
['regression: scenario 2',
[5,
[{'z1': 'cool', 'z2': None, 'z3': 'cool'},
{'z1': 'cool', 'z2': None, 'z3': 'cool'},
{'z1': 'cool', 'z3': 'cool'},
{'z1': 'cool', 'z2': None, 'z3': 'cool'},
{'z1': 'cool', 'z2': None, 'z3': 'cool'},
{'z1': 'cool', 'z3': 'heat', 'z4': None},
{'z1': 'cool', 'z2': None, 'z3': 'heat'},
{'z1': 'cool', 'z2': None, 'z3': 'heat'},
{'z1': 'heat'},
{'z1': 'heat', 'z2': None, 'z4': None},
{'z1': 'heat', 'z4': None},
{'z1': 'heat', 'z2': None, 'z4': None},
{'z1': 'heat', 'z3': 'heat', 'z4': None}]],
[['cool', ['z1', 'z3']],
['cool', ['z1', 'z3']],
['cool', ['z1', 'z3']],
['cool', ['z1', 'z3']],
['cool', ['z1', 'z3']],
['heat', ['z3']],
['heat', ['z3']],
['heat', ['z3']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z1', 'z3']]]]],
[['regression: scenario 2',
[3,
[{'z1': None, 'z2': 'cool', 'z3': 'heat', 'z4': 'heat'},
{'z3': 'heat', 'z4': 'heat'},
{'z1': None, 'z2': None, 'z3': 'cool', 'z4': 'cool'},
{'z3': 'cool'},
{'z2': None, 'z3': 'cool', 'z4': None},
{'z1': 'heat', 'z2': 'cool', 'z3': 'cool'},
{'z1': 'cool', 'z2': 'cool', 'z3': 'cool', 'z4': None},
{'z1': 'cool', 'z2': 'cool', 'z3': 'cool'},
{'z1': 'cool', 'z2': 'cool', 'z3': 'cool'},
{'z1': 'cool', 'z2': 'cool', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z2': 'cool', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z2': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z2': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'cool', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'cool', 'z3': 'cool', 'z4': 'heat'}]],
[['heat', ['z3', 'z4']],
['heat', ['z3', 'z4']],
['cool', ['z3', 'z4']],
['cool', ['z3']],
['cool', ['z3']],
['heat', ['z1']],
['cool', ['z1', 'z2', 'z3']],
['cool', ['z1', 'z2', 'z3']],
['cool', ['z1', 'z2', 'z3']],
['heat', ['z4']],
['heat', ['z4']],
['heat', ['z4']],
['cool', ['z1', 'z2']],
['cool', ['z2', 'z3']],
['cool', ['z2', 'z3']]]],
['regression: scenario 10',
[2,
[{'z1': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z2': None, 'z3': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z3': 'cool', 'z4': 'heat'},
{'z2': None, 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': None, 'z3': 'heat'},
{'z1': 'cool', 'z3': 'heat', 'z4': None},
{'z1': 'cool', 'z2': None, 'z3': 'heat', 'z4': None},
{'z1': 'cool', 'z3': 'heat', 'z4': 'cool'},
{'z1': 'cool', 'z2': None, 'z3': 'heat', 'z4': 'cool'},
{'z1': 'cool', 'z3': 'heat', 'z4': 'cool'},
{'z1': 'cool', 'z3': 'heat', 'z4': None},
{'z1': 'cool', 'z3': 'heat', 'z4': None},
{'z1': 'cool', 'z3': 'heat'},
{'z1': 'cool', 'z3': 'heat', 'z4': None}]],
[['heat', ['z4']],
['heat', ['z4']],
['cool', ['z1', 'z3']],
['cool', ['z1', 'z3']],
['heat', ['z4']],
['heat', ['z1', 'z4']],
['heat', ['z1', 'z3']],
['cool', ['z1']],
['cool', ['z1']],
['heat', ['z3']],
['heat', ['z3']],
['cool', ['z1', 'z4']],
['cool', ['z1']],
['heat', ['z3']],
['heat', ['z3']],
['cool', ['z1']]]],
['control: majority then forced switch',
[3,
[{'a': 'heat', 'b': 'cool', 'c': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat'},
{}]],
[['cool', ['b', 'c']], ['cool', ['b']], ['cool', ['b']], ['heat', ['a']], ['heat', ['a']], [None, []]]],
['control: tie goes to heat',
[2, [{'a': 'heat', 'b': 'cool'}, {'a': 'heat', 'b': 'cool'}, {'b': 'cool'}]],
[['heat', ['a']], ['heat', ['a']], ['cool', ['b']]]],
['regression: ping pong guard',
[2,
[{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'}]],
[['heat', ['a']],
['heat', ['a']],
['cool', ['b']],
['cool', ['b']],
['heat', ['a']],
['heat', ['a']],
['cool', ['b']]]],
['control: satisfied then opposite',
[5, [{'a': 'cool'}, {'a': 'cool', 'b': 'heat'}, {'b': 'heat'}, {'b': 'heat'}]],
[['cool', ['a']], ['cool', ['a']], ['heat', ['b']], ['heat', ['b']]]],
['control: first minute call',
[3, [{'a': 'cool'}, {'a': 'cool'}, {}]],
[['cool', ['a']], ['cool', ['a']], [None, []]]],
['control: scenario 1',
[3,
[{'z1': 'heat', 'z2': 'cool', 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': None, 'z3': 'heat', 'z4': 'heat'},
{'z1': None, 'z2': None, 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': None, 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': None, 'z3': 'heat', 'z4': 'cool'},
{'z1': 'heat', 'z2': None, 'z3': 'heat', 'z4': None},
{'z1': 'heat', 'z3': 'heat', 'z4': None},
{'z1': 'heat', 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': None, 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool'}]],
[['heat', ['z1', 'z3', 'z4']],
['heat', ['z1', 'z3', 'z4']],
['heat', ['z1', 'z3', 'z4']],
['heat', ['z3', 'z4']],
['heat', ['z1', 'z3', 'z4']],
['heat', ['z1', 'z3', 'z4']],
['cool', ['z4']],
['heat', ['z1', 'z3']],
['heat', ['z1', 'z3']],
['heat', ['z1', 'z3', 'z4']],
['heat', ['z1', 'z3', 'z4']],
['heat', ['z1', 'z2', 'z4']],
['heat', ['z1', 'z2']],
['heat', ['z1', 'z2', 'z3']],
['cool', ['z3']]]]],
[['regression: scenario 2',
[2,
[{'z1': 'heat', 'z3': 'cool', 'z4': 'cool'},
{'z1': 'cool', 'z2': None, 'z3': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z2': None, 'z3': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z4': 'heat'},
{'z1': None, 'z2': 'cool', 'z3': None, 'z4': 'heat'},
{'z1': None, 'z2': 'cool', 'z3': None, 'z4': 'heat'},
{'z2': 'cool', 'z4': 'heat'},
{'z3': None}]],
[['cool', ['z3', 'z4']],
['cool', ['z1', 'z3']],
['heat', ['z4']],
['heat', ['z4']],
['cool', ['z2']],
['cool', ['z2']],
['heat', ['z4']],
[None, []]]],
['regression: scenario 11',
[2,
[{'z1': 'heat', 'z2': 'heat', 'z3': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'cool', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': None, 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': None, 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z4': 'cool'}]],
[['heat', ['z1', 'z2', 'z3']],
['heat', ['z1', 'z2', 'z3']],
['heat', ['z1', 'z2', 'z3', 'z4']],
['heat', ['z1', 'z2', 'z3', 'z4']],
['heat', ['z1', 'z2', 'z3', 'z4']],
['cool', ['z3']],
['cool', ['z2', 'z3']],
['heat', ['z1']],
['heat', ['z1', 'z2']],
['cool', ['z4']],
['cool', ['z4']],
['heat', ['z1', 'z2']],
['heat', ['z1', 'z2']]]],
['control: majority then forced switch',
[3,
[{'a': 'heat', 'b': 'cool', 'c': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat'},
{}]],
[['cool', ['b', 'c']], ['cool', ['b']], ['cool', ['b']], ['heat', ['a']], ['heat', ['a']], [None, []]]],
['control: tie goes to heat',
[2, [{'a': 'heat', 'b': 'cool'}, {'a': 'heat', 'b': 'cool'}, {'b': 'cool'}]],
[['heat', ['a']], ['heat', ['a']], ['cool', ['b']]]],
['regression: ping pong guard',
[2,
[{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'}]],
[['heat', ['a']],
['heat', ['a']],
['cool', ['b']],
['cool', ['b']],
['heat', ['a']],
['heat', ['a']],
['cool', ['b']]]],
['control: satisfied then opposite',
[5, [{'a': 'cool'}, {'a': 'cool', 'b': 'heat'}, {'b': 'heat'}, {'b': 'heat'}]],
[['cool', ['a']], ['cool', ['a']], ['heat', ['b']], ['heat', ['b']]]],
['control: first minute call',
[3, [{'a': 'cool'}, {'a': 'cool'}, {}]],
[['cool', ['a']], ['cool', ['a']], [None, []]]],
['regression: scenario 1',
[3,
[{'z1': 'heat', 'z2': 'heat', 'z3': None, 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': None},
{'z1': 'heat', 'z2': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': None, 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': None, 'z4': None}]],
[['heat', ['z1', 'z2']],
['heat', ['z1', 'z2']],
['heat', ['z1', 'z2']],
['cool', ['z3', 'z4']],
['cool', ['z3']],
['cool', ['z3']],
['heat', ['z1', 'z2', 'z4']],
['heat', ['z1', 'z2']],
['heat', ['z1', 'z2']],
['cool', ['z4']],
['heat', ['z1', 'z2']]]]],
[['regression: scenario 4',
[5,
[{'z1': None, 'z2': None, 'z3': 'cool', 'z4': None},
{'z1': None, 'z3': 'cool'},
{'z3': 'cool'},
{'z3': 'cool'},
{'z2': None, 'z3': 'cool'},
{'z2': 'cool', 'z3': 'cool'},
{'z1': None, 'z2': 'cool', 'z3': 'heat'},
{'z2': 'cool', 'z3': 'heat'},
{'z1': None, 'z2': 'cool', 'z3': None},
{'z2': 'cool', 'z3': None}]],
[['cool', ['z3']],
['cool', ['z3']],
['cool', ['z3']],
['cool', ['z3']],
['cool', ['z3']],
['cool', ['z2', 'z3']],
['heat', ['z3']],
['heat', ['z3']],
['cool', ['z2']],
['cool', ['z2']]]],
['regression: scenario 23',
[3,
[{'z1': 'heat', 'z3': None, 'z4': 'cool'},
{'z1': 'heat', 'z3': None, 'z4': 'cool'},
{'z1': 'cool', 'z2': None, 'z3': None, 'z4': 'cool'},
{'z1': 'cool', 'z2': None, 'z3': None, 'z4': 'cool'},
{'z1': 'heat', 'z3': 'heat', 'z4': None},
{'z1': 'heat', 'z2': None, 'z4': None},
{'z1': 'heat', 'z2': None, 'z3': None, 'z4': None},
{'z1': 'heat', 'z2': 'heat', 'z3': None, 'z4': None},
{'z1': 'heat', 'z2': 'heat', 'z3': None, 'z4': None},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat', 'z4': None}]],
[['heat', ['z1']],
['heat', ['z1']],
['cool', ['z1', 'z4']],
['cool', ['z1', 'z4']],
['heat', ['z1', 'z3']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z1', 'z2']],
['heat', ['z1', 'z2']],
['cool', ['z3', 'z4']],
['cool', ['z3']],
['heat', ['z1', 'z2', 'z3']]]],
['control: majority then forced switch',
[3,
[{'a': 'heat', 'b': 'cool', 'c': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat'},
{}]],
[['cool', ['b', 'c']], ['cool', ['b']], ['cool', ['b']], ['heat', ['a']], ['heat', ['a']], [None, []]]],
['control: tie goes to heat',
[2, [{'a': 'heat', 'b': 'cool'}, {'a': 'heat', 'b': 'cool'}, {'b': 'cool'}]],
[['heat', ['a']], ['heat', ['a']], ['cool', ['b']]]],
['regression: ping pong guard',
[2,
[{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'}]],
[['heat', ['a']],
['heat', ['a']],
['cool', ['b']],
['cool', ['b']],
['heat', ['a']],
['heat', ['a']],
['cool', ['b']]]],
['control: satisfied then opposite',
[5, [{'a': 'cool'}, {'a': 'cool', 'b': 'heat'}, {'b': 'heat'}, {'b': 'heat'}]],
[['cool', ['a']], ['cool', ['a']], ['heat', ['b']], ['heat', ['b']]]],
['control: first minute call',
[3, [{'a': 'cool'}, {'a': 'cool'}, {}]],
[['cool', ['a']], ['cool', ['a']], [None, []]]],
['regression: scenario 1',
[5,
[{'z1': 'cool', 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': None, 'z3': 'cool', 'z4': 'heat'},
{'z1': None, 'z3': 'cool', 'z4': 'heat'},
{'z1': None, 'z2': None, 'z3': 'cool', 'z4': 'heat'},
{'z1': None, 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'cool', 'z2': 'heat', 'z4': 'heat'},
{'z1': None, 'z2': 'heat', 'z4': 'heat'},
{'z2': 'heat', 'z3': 'cool', 'z4': 'cool'},
{'z2': 'heat', 'z3': 'cool', 'z4': 'cool'},
{'z2': 'heat', 'z3': 'heat', 'z4': 'cool'}]],
[['heat', ['z2', 'z4']],
['heat', ['z2', 'z4']],
['heat', ['z4']],
['heat', ['z4']],
['heat', ['z4']],
['cool', ['z3']],
['cool', ['z1']],
['heat', ['z2', 'z4']],
['heat', ['z2']],
['heat', ['z2']],
['heat', ['z2', 'z3']]]]],
[['regression: scenario 4',
[5,
[{'z1': None, 'z3': None, 'z4': None},
{'z1': None, 'z3': None, 'z4': None},
{'z3': 'cool'},
{'z2': None, 'z3': 'cool', 'z4': None},
{'z1': None, 'z3': 'cool', 'z4': 'heat'},
{'z3': 'cool', 'z4': 'heat'},
{'z1': None, 'z2': None, 'z3': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': None, 'z3': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': None, 'z3': 'cool', 'z4': 'cool'},
{'z1': 'heat', 'z2': None, 'z3': 'cool'},
{'z1': 'heat', 'z2': None, 'z3': 'cool', 'z4': None},
{'z1': 'heat', 'z2': None, 'z3': 'cool'},
{'z1': 'heat', 'z2': None, 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': None, 'z3': 'heat', 'z4': 'heat'}]],
[[None, []],
[None, []],
['cool', ['z3']],
['cool', ['z3']],
['cool', ['z3']],
['cool', ['z3']],
['cool', ['z3', 'z4']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z1']],
['heat', ['z1', 'z3', 'z4']],
['heat', ['z1', 'z3', 'z4']]]],
['regression: scenario 25',
[2,
[{'z1': 'cool', 'z2': 'heat', 'z3': 'heat', 'z4': 'cool'},
{'z1': 'cool', 'z2': 'heat', 'z3': 'heat', 'z4': None},
{'z2': 'heat', 'z3': 'heat'},
{'z1': None, 'z2': 'cool', 'z3': 'heat'},
{'z1': None, 'z2': 'cool', 'z3': 'heat'},
{'z1': 'cool', 'z2': 'cool'},
{'z1': 'cool', 'z2': 'cool', 'z3': None, 'z4': None},
{'z1': 'cool', 'z2': 'cool', 'z3': None, 'z4': None},
{'z1': 'cool', 'z2': 'cool', 'z3': None, 'z4': 'heat'},
{'z1': 'cool', 'z2': 'cool', 'z3': None},
{'z1': 'cool', 'z2': 'cool', 'z3': 'cool', 'z4': 'cool'},
{'z1': 'cool', 'z2': 'cool', 'z3': 'cool', 'z4': 'cool'},
{'z1': 'cool', 'z2': 'cool', 'z4': 'cool'},
{'z1': 'cool', 'z2': 'cool', 'z4': 'heat'}]],
[['heat', ['z2', 'z3']],
['heat', ['z2', 'z3']],
['heat', ['z2', 'z3']],
['cool', ['z2']],
['cool', ['z2']],
['cool', ['z1', 'z2']],
['cool', ['z1', 'z2']],
['cool', ['z1', 'z2']],
['heat', ['z4']],
['cool', ['z1', 'z2']],
['cool', ['z1', 'z2', 'z3', 'z4']],
['cool', ['z1', 'z2', 'z3', 'z4']],
['cool', ['z1', 'z2', 'z4']],
['heat', ['z4']]]],
['control: majority then forced switch',
[3,
[{'a': 'heat', 'b': 'cool', 'c': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat'},
{}]],
[['cool', ['b', 'c']], ['cool', ['b']], ['cool', ['b']], ['heat', ['a']], ['heat', ['a']], [None, []]]],
['control: tie goes to heat',
[2, [{'a': 'heat', 'b': 'cool'}, {'a': 'heat', 'b': 'cool'}, {'b': 'cool'}]],
[['heat', ['a']], ['heat', ['a']], ['cool', ['b']]]],
['regression: ping pong guard',
[2,
[{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'},
{'a': 'heat', 'b': 'cool'}]],
[['heat', ['a']],
['heat', ['a']],
['cool', ['b']],
['cool', ['b']],
['heat', ['a']],
['heat', ['a']],
['cool', ['b']]]],
['control: satisfied then opposite',
[5, [{'a': 'cool'}, {'a': 'cool', 'b': 'heat'}, {'b': 'heat'}, {'b': 'heat'}]],
[['cool', ['a']], ['cool', ['a']], ['heat', ['b']], ['heat', ['b']]]],
['control: first minute call',
[3, [{'a': 'cool'}, {'a': 'cool'}, {}]],
[['cool', ['a']], ['cool', ['a']], [None, []]]],
['regression: scenario 1',
[3,
[{'z1': 'heat', 'z2': 'heat', 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'heat', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z1': 'heat', 'z2': 'heat', 'z3': 'cool', 'z4': 'heat'},
{'z2': 'heat'},
{'z2': 'heat', 'z4': 'heat'},
{'z1': None, 'z2': 'heat', 'z3': None, 'z4': 'heat'},
{'z2': 'heat', 'z3': None, 'z4': 'heat'}]],
[['heat', ['z1', 'z2', 'z3', 'z4']],
['heat', ['z1', 'z2', 'z3']],
['heat', ['z1', 'z2', 'z3', 'z4']],
['cool', ['z3']],
['cool', ['z3']],
['heat', ['z2']],
['heat', ['z2', 'z4']],
['heat', ['z2', 'z4']],
['heat', ['z2', 'z4']]]]]]
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: ping pong guard | [['heat', ['a']], ['heat', ['a']], ['cool', ['b']], ['cool', ['b']], ['heat', ['a']], ['heat', ['a']], ['cool', ['b']]] | [['heat', ['a']], ['heat', ['a']], ['cool', ['b']], ['cool', ['b']], ['heat', ['a']], ['heat', ['a']], ['cool', ['b']]] | Passed |
| regression: scenario 3 | [['cool', ['z1', 'z3']], ['cool', ['z2', 'z3']], ['cool', ['z1', 'z2', 'z3']], ['heat', ['z2']], ['heat', ['z2', 'z4']], ['cool', ['z1', 'z2', 'z3']], ['cool', ['z1', 'z3']], ['heat', ['z3']], ['heat', ['z3']], ['cool', ['z1']]] | [['cool', ['z1', 'z3']], ['cool', ['z2', 'z3']], ['cool', ['z1', 'z2', 'z3']], ['heat', ['z2']], ['heat', ['z2', 'z4']], ['cool', ['z1', 'z2', 'z3']], ['cool', ['z1', 'z3']], ['heat', ['z3']], ['heat', ['z3']], ['cool', ['z1']]] | Passed |
| control: majority then forced switch | [['cool', ['b', 'c']], ['cool', ['b']], ['cool', ['b']], ['heat', ['a']], ['heat', ['a']], [None, []]] | [['cool', ['b', 'c']], ['cool', ['b']], ['cool', ['b']], ['heat', ['a']], ['heat', ['a']], [None, []]] | Passed |
| control: tie goes to heat | [['heat', ['a']], ['heat', ['a']], ['cool', ['b']]] | [['heat', ['a']], ['heat', ['a']], ['cool', ['b']]] | Passed |
| control: satisfied then opposite | [['cool', ['a']], ['cool', ['a']], ['heat', ['b']], ['heat', ['b']]] | [['cool', ['a']], ['cool', ['a']], ['heat', ['b']], ['heat', ['b']]] | Passed |
| control: first minute call | [['cool', ['a']], ['cool', ['a']], [None, []]] | [['cool', ['a']], ['cool', ['a']], [None, []]] | Passed |
| regression: scenario 1 | [['cool', ['z1']], ['cool', ['z4']], ['cool', ['z4']], ['cool', ['z4']], ['cool', ['z2', 'z3', 'z4']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z4']], ['heat', ['z3', 'z4']]] | [['cool', ['z1']], ['cool', ['z4']], ['cool', ['z4']], ['cool', ['z4']], ['cool', ['z2', 'z3', 'z4']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z4']], ['heat', ['z3', 'z4']]] | Passed |
| regression: scenario 2 | [['cool', ['z1', 'z3']], ['cool', ['z1', 'z3']], ['cool', ['z1', 'z3']], ['cool', ['z1', 'z3']], ['cool', ['z1', 'z3']], ['heat', ['z3']], ['heat', ['z3']], ['heat', ['z3']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z1', 'z3']]] | [['cool', ['z1', 'z3']], ['cool', ['z1', 'z3']], ['cool', ['z1', 'z3']], ['cool', ['z1', 'z3']], ['cool', ['z1', 'z3']], ['heat', ['z3']], ['heat', ['z3']], ['heat', ['z3']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z1']], ['heat', ['z1', 'z3']]] | Passed |
SHA-256 / 2783d624deec0a8f640d4b9f20604da29c8798d3add51c5f8428cdb28025eaec
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:49.476808+00:00.
Case digest / 36be59241de1149122e8da81ff148220106fa543aa4de3a8cc9c4a73da656fc8