FA-92731 / HVAC thermostat control / Open access
Cycle length is computed with float division · case 01
With 7 or 9 cycles per hour the heater only cycles once, at minute 0, and then stays off.
ROOT CAUSE
The cycle length 60 / cph is a non-integer, so minute % period never returns to 0.
VERIFIED REPAIR
Use an integer cycle length of 60 // cph minutes.
Unsuccessful approach: Rounding 60 / cph gives the wrong cycle length for some settings.
Case contract
Time-proportioning heating thermostat with a cycles-per-hour setting, sampled per minute. The cycle length is 60 // cph minutes. At each cycle start the error (setpoint - temp) is clamped to 0..band and the on time is error/band of the cycle rounded half up; an on time of 1 minute is extended to the 2-minute minimum, and an off time of 1 minute is eliminated (full on). The output is on for the first on-time minutes of the cycle. Return the heat output 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(cph, band, setpoint, temps):
period = 60 / cph
out = []
on_left = 0
for minute, temp in enumerate(temps):
if minute % period == 0:
err = setpoint - temp
num = max(0, min(err, band)) * period
on = (2 * num + band) // (2 * band)
if 0 < on < 2:
on = 2
if 0 < period - on < 2:
on = period
on_left = on
out.append(on_left > 0)
if on_left > 0:
on_left -= 1
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: seven cycles per hour',
[7,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
685,
685,
685,
685,
685,
685,
685,
685,
685,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
False,
False,
True,
True,
False]],
['regression: scenario 3',
[7,
30,
700,
[693,
691,
695,
691,
695,
698,
697,
700,
702,
704,
706,
708,
709,
707,
706,
702,
702,
701,
698,
701,
700,
704,
703,
702,
702,
699,
695,
694,
696,
699,
696,
692,
694,
693,
694,
697,
700]],
[True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
False,
False,
False]],
['control: three cycles',
[5,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681]],
[True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]],
['control: tiny error',
[6,
30,
700,
[696, 696, 696, 696, 696, 696, 696, 696, 696, 696, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698]],
[True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False]],
['control: above setpoint',
[4,
10,
700,
[705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False]],
['control: scenario 1',
[4,
10,
700,
[673,
669,
665,
669,
667,
665,
664,
662,
659,
662,
661,
659,
660,
656,
659,
660,
656,
652,
654,
652,
656,
657,
653,
653,
653,
653,
654,
653,
650,
650,
650,
650,
651,
654,
651,
650,
650,
650,
650]],
[True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]],
['control: scenario 2',
[6,
30,
700,
[697,
695,
691,
695,
691,
692,
693,
692,
690,
690,
690,
687,
684,
683,
687,
688,
688,
691,
690,
692,
693,
689,
692]],
[True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False,
True,
True,
False]],
['control: scenario 4',
[4,
10,
700,
[680,
684,
685,
683,
684,
685,
686,
682,
681,
679,
677,
681,
680,
681,
677,
681,
680,
682,
682,
678,
677,
673,
672,
676,
673,
670,
669,
665,
662]],
[True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]]],
[['regression: scenario 5',
[9,
10,
700,
[684,
682,
680,
682,
681,
682,
686,
685,
684,
682,
679,
682,
686,
688,
688,
689,
689,
689,
693,
689,
685,
682,
681,
682,
684,
685]],
[True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False,
True,
True]],
['regression: scenario 4',
[9,
30,
700,
[705,
708,
704,
703,
700,
701,
701,
702,
699,
698,
698,
697,
698,
702,
699,
700,
701,
697,
700,
697,
694,
695,
696]],
[False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False]],
['control: three cycles',
[5,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681]],
[True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]],
['regression: seven cycles per hour',
[7,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
685,
685,
685,
685,
685,
685,
685,
685,
685,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
False,
False,
True,
True,
False]],
['control: tiny error',
[6,
30,
700,
[696, 696, 696, 696, 696, 696, 696, 696, 696, 696, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698]],
[True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False]],
['control: above setpoint',
[4,
10,
700,
[705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False]],
['control: scenario 1',
[6,
30,
700,
[690,
689,
690,
691,
689,
685,
682,
686,
682,
680,
684,
687,
690,
693,
692,
689,
688,
685,
683,
685,
687,
683,
684,
688,
691,
689,
686,
683,
679,
679,
682,
680,
680,
684]],
[True,
True,
True,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True]],
['control: scenario 2',
[6,
10,
700,
[686,
687,
685,
682,
682,
678,
681,
677,
676,
673,
674,
676,
672,
670,
669,
673,
674,
676,
675,
673,
675,
672,
673,
674,
670,
672]],
[True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]]],
[['regression: scenario 2',
[9,
20,
700,
[702,
703,
707,
703,
700,
697,
699,
698,
696,
693,
696,
695,
694,
690,
692,
695,
697,
700,
698,
699,
701,
704,
708,
712,
710,
709,
713,
709,
710,
714,
711,
711,
707,
706,
706]],
[False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
False,
False,
False,
False,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False]],
['regression: scenario 3',
[7,
30,
700,
[701,
704,
708,
708,
709,
711,
707,
709,
710,
706,
707,
703,
701,
697,
697,
698,
698,
701,
700,
699,
699,
695,
696,
700,
698,
701,
700]],
[False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
False,
False,
False,
False,
False,
False,
True,
True,
False]],
['control: three cycles',
[5,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681]],
[True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]],
['regression: seven cycles per hour',
[7,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
685,
685,
685,
685,
685,
685,
685,
685,
685,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
False,
False,
True,
True,
False]],
['control: tiny error',
[6,
30,
700,
[696, 696, 696, 696, 696, 696, 696, 696, 696, 696, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698]],
[True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False]],
['control: above setpoint',
[4,
10,
700,
[705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False]],
['regression: scenario 1',
[7,
20,
700,
[688,
691,
689,
691,
692,
691,
687,
691,
692,
691,
695,
695,
692,
689,
688,
684,
682,
681,
679,
678,
682,
682,
680,
682,
686,
689,
687,
687,
690,
686,
687,
691]],
[True,
True,
True,
True,
True,
False,
False,
False,
True,
True,
True,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False]],
['control: scenario 4',
[4,
30,
700,
[675,
676,
675,
674,
673,
676,
674,
672,
673,
672,
674,
677,
674,
671,
668,
664,
668,
667,
668,
670,
668,
670,
672]],
[True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True]]],
[['regression: scenario 8',
[7,
30,
700,
[680,
684,
686,
690,
693,
690,
694,
694,
695,
695,
691,
694,
694,
696,
699,
700,
701,
702,
706,
709,
710,
713,
715,
713,
715,
715,
715,
715,
712]],
[True,
True,
True,
True,
True,
False,
False,
False,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False]],
['regression: scenario 25',
[8,
20,
700,
[686,
685,
683,
680,
677,
673,
671,
669,
666,
666,
666,
664,
664,
664,
667,
663,
663,
662,
661,
663,
667,
666,
663,
664,
663,
665,
668,
664,
667,
670,
669,
670,
667,
666,
664,
667,
670,
666,
670,
669]],
[True,
True,
True,
True,
True,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]],
['control: three cycles',
[5,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681]],
[True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]],
['regression: seven cycles per hour',
[7,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
685,
685,
685,
685,
685,
685,
685,
685,
685,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
False,
False,
True,
True,
False]],
['control: tiny error',
[6,
30,
700,
[696, 696, 696, 696, 696, 696, 696, 696, 696, 696, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698]],
[True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False]],
['control: above setpoint',
[4,
10,
700,
[705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False]],
['control: scenario 1',
[6,
10,
700,
[702,
699,
703,
707,
704,
708,
705,
701,
698,
700,
703,
703,
700,
697,
696,
697,
697,
701,
703,
703,
704,
705,
708,
704,
706,
705,
702,
706,
707,
704,
708,
707,
703,
706,
707,
703,
703,
706,
707,
706]],
[False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False]],
['control: scenario 2',
[3,
20,
700,
[682, 683, 684, 687, 687, 686, 682, 683, 680, 676, 680, 683, 679, 675, 674, 671, 671, 672, 670, 672]],
[True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False]]],
[['regression: scenario 11',
[9,
10,
700,
[681,
685,
683,
685,
683,
682,
681,
682,
686,
688,
685,
688,
686,
684,
686,
688,
690,
688,
692,
696,
697,
695,
694,
692,
696,
694,
698,
702,
703,
703,
700,
698,
700,
696,
699,
698]],
[True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False]],
['regression: scenario 12',
[7,
30,
700,
[696,
694,
690,
693,
689,
689,
691,
693,
689,
687,
685,
682,
686,
689,
688,
692,
689,
689,
689,
689,
692,
694,
696,
697,
698,
698,
695,
698,
699,
702,
706,
708,
710,
714,
715]],
[True,
True,
False,
False,
False,
False,
False,
False,
True,
True,
True,
False,
False,
False,
False,
False,
True,
True,
True,
False,
False,
False,
False,
False,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False]],
['control: three cycles',
[5,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681]],
[True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]],
['regression: seven cycles per hour',
[7,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
685,
685,
685,
685,
685,
685,
685,
685,
685,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
False,
False,
True,
True,
False]],
['control: tiny error',
[6,
30,
700,
[696, 696, 696, 696, 696, 696, 696, 696, 696, 696, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698]],
[True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False]],
['control: above setpoint',
[4,
10,
700,
[705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False]],
['control: scenario 1',
[5,
10,
700,
[698,
700,
702,
701,
700,
700,
699,
697,
694,
696,
698,
694,
697,
697,
694,
698,
700,
698,
699,
700,
703,
707,
708,
706,
708,
712,
710,
706,
702,
700,
696,
696,
692]],
[True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False]],
['control: scenario 2',
[3,
10,
700,
[669,
665,
665,
665,
666,
665,
663,
665,
667,
665,
667,
663,
663,
667,
667,
668,
664,
664,
664,
663,
661,
661,
661,
664,
666,
664,
668]],
[True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]]]]
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: seven cycles per hour | [True, True, True, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] | [True, True, True, True, False, False, False, False, True, True, True, True, False, False, False, False, True, True, True, True, True, True, False, False, True, True, False] | Failed |
| regression: scenario 3 | [True, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False] | [True, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, True, False, False, False] | Failed |
| control: three cycles | [True, True, True, True, True, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, True, True, True, True, True, True, True, True, True, True, True] | [True, True, True, True, True, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, True, True, True, True, True, True, True, True, True, True, True] | Passed |
| control: tiny error | [True, True, False, False, False, False, False, False, False, False, True, True, False, False, False, False, False, False, False, False] | [True, True, False, False, False, False, False, False, False, False, True, True, False, False, False, False, False, False, False, False] | Passed |
| control: above setpoint | [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, True, True, True, True, True, True, True, False, False, False, False, False, False, False] | [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, True, True, True, True, True, True, True, False, False, False, False, False, False, False] | Passed |
| control: scenario 1 | [True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True] | [True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True] | Passed |
| control: scenario 2 | [True, True, False, False, False, False, False, False, False, False, True, True, True, False, False, False, False, False, False, False, True, True, False] | [True, True, False, False, False, False, False, False, False, False, True, True, True, False, False, False, False, False, False, False, True, True, False] | Passed |
| control: scenario 4 | [True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True] | [True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True] | Passed |
SHA-256 / 6b4477637c10dacb44f723382f6f9bdad1f593753e92e8c69670e31df267a9b7
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(cph, band, setpoint, temps):
period = round(60 / cph)
out = []
on_left = 0
for minute, temp in enumerate(temps):
if minute % period == 0:
err = setpoint - temp
num = max(0, min(err, band)) * period
on = (2 * num + band) // (2 * band)
if 0 < on < 2:
on = 2
if 0 < period - on < 2:
on = period
on_left = on
out.append(on_left > 0)
if on_left > 0:
on_left -= 1
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: seven cycles per hour',
[7,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
685,
685,
685,
685,
685,
685,
685,
685,
685,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
False,
False,
True,
True,
False]],
['regression: scenario 3',
[7,
30,
700,
[693,
691,
695,
691,
695,
698,
697,
700,
702,
704,
706,
708,
709,
707,
706,
702,
702,
701,
698,
701,
700,
704,
703,
702,
702,
699,
695,
694,
696,
699,
696,
692,
694,
693,
694,
697,
700]],
[True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
False,
False,
False]],
['control: three cycles',
[5,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681]],
[True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]],
['control: tiny error',
[6,
30,
700,
[696, 696, 696, 696, 696, 696, 696, 696, 696, 696, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698]],
[True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False]],
['control: above setpoint',
[4,
10,
700,
[705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False]],
['control: scenario 1',
[4,
10,
700,
[673,
669,
665,
669,
667,
665,
664,
662,
659,
662,
661,
659,
660,
656,
659,
660,
656,
652,
654,
652,
656,
657,
653,
653,
653,
653,
654,
653,
650,
650,
650,
650,
651,
654,
651,
650,
650,
650,
650]],
[True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]],
['control: scenario 2',
[6,
30,
700,
[697,
695,
691,
695,
691,
692,
693,
692,
690,
690,
690,
687,
684,
683,
687,
688,
688,
691,
690,
692,
693,
689,
692]],
[True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False,
True,
True,
False]],
['control: scenario 4',
[4,
10,
700,
[680,
684,
685,
683,
684,
685,
686,
682,
681,
679,
677,
681,
680,
681,
677,
681,
680,
682,
682,
678,
677,
673,
672,
676,
673,
670,
669,
665,
662]],
[True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]]],
[['regression: scenario 5',
[9,
10,
700,
[684,
682,
680,
682,
681,
682,
686,
685,
684,
682,
679,
682,
686,
688,
688,
689,
689,
689,
693,
689,
685,
682,
681,
682,
684,
685]],
[True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False,
True,
True]],
['regression: scenario 4',
[9,
30,
700,
[705,
708,
704,
703,
700,
701,
701,
702,
699,
698,
698,
697,
698,
702,
699,
700,
701,
697,
700,
697,
694,
695,
696]],
[False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False]],
['control: three cycles',
[5,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681]],
[True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]],
['regression: seven cycles per hour',
[7,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
685,
685,
685,
685,
685,
685,
685,
685,
685,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
False,
False,
True,
True,
False]],
['control: tiny error',
[6,
30,
700,
[696, 696, 696, 696, 696, 696, 696, 696, 696, 696, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698]],
[True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False]],
['control: above setpoint',
[4,
10,
700,
[705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False]],
['control: scenario 1',
[6,
30,
700,
[690,
689,
690,
691,
689,
685,
682,
686,
682,
680,
684,
687,
690,
693,
692,
689,
688,
685,
683,
685,
687,
683,
684,
688,
691,
689,
686,
683,
679,
679,
682,
680,
680,
684]],
[True,
True,
True,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True]],
['control: scenario 2',
[6,
10,
700,
[686,
687,
685,
682,
682,
678,
681,
677,
676,
673,
674,
676,
672,
670,
669,
673,
674,
676,
675,
673,
675,
672,
673,
674,
670,
672]],
[True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]]],
[['regression: scenario 2',
[9,
20,
700,
[702,
703,
707,
703,
700,
697,
699,
698,
696,
693,
696,
695,
694,
690,
692,
695,
697,
700,
698,
699,
701,
704,
708,
712,
710,
709,
713,
709,
710,
714,
711,
711,
707,
706,
706]],
[False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
False,
False,
False,
False,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False]],
['regression: scenario 3',
[7,
30,
700,
[701,
704,
708,
708,
709,
711,
707,
709,
710,
706,
707,
703,
701,
697,
697,
698,
698,
701,
700,
699,
699,
695,
696,
700,
698,
701,
700]],
[False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
False,
False,
False,
False,
False,
False,
True,
True,
False]],
['control: three cycles',
[5,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681]],
[True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]],
['regression: seven cycles per hour',
[7,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
685,
685,
685,
685,
685,
685,
685,
685,
685,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
False,
False,
True,
True,
False]],
['control: tiny error',
[6,
30,
700,
[696, 696, 696, 696, 696, 696, 696, 696, 696, 696, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698]],
[True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False]],
['control: above setpoint',
[4,
10,
700,
[705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False]],
['regression: scenario 1',
[7,
20,
700,
[688,
691,
689,
691,
692,
691,
687,
691,
692,
691,
695,
695,
692,
689,
688,
684,
682,
681,
679,
678,
682,
682,
680,
682,
686,
689,
687,
687,
690,
686,
687,
691]],
[True,
True,
True,
True,
True,
False,
False,
False,
True,
True,
True,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False]],
['control: scenario 4',
[4,
30,
700,
[675,
676,
675,
674,
673,
676,
674,
672,
673,
672,
674,
677,
674,
671,
668,
664,
668,
667,
668,
670,
668,
670,
672]],
[True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True]]],
[['regression: scenario 8',
[7,
30,
700,
[680,
684,
686,
690,
693,
690,
694,
694,
695,
695,
691,
694,
694,
696,
699,
700,
701,
702,
706,
709,
710,
713,
715,
713,
715,
715,
715,
715,
712]],
[True,
True,
True,
True,
True,
False,
False,
False,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False]],
['regression: scenario 25',
[8,
20,
700,
[686,
685,
683,
680,
677,
673,
671,
669,
666,
666,
666,
664,
664,
664,
667,
663,
663,
662,
661,
663,
667,
666,
663,
664,
663,
665,
668,
664,
667,
670,
669,
670,
667,
666,
664,
667,
670,
666,
670,
669]],
[True,
True,
True,
True,
True,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]],
['control: three cycles',
[5,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681]],
[True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]],
['regression: seven cycles per hour',
[7,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
685,
685,
685,
685,
685,
685,
685,
685,
685,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
False,
False,
True,
True,
False]],
['control: tiny error',
[6,
30,
700,
[696, 696, 696, 696, 696, 696, 696, 696, 696, 696, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698]],
[True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False]],
['control: above setpoint',
[4,
10,
700,
[705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False]],
['control: scenario 1',
[6,
10,
700,
[702,
699,
703,
707,
704,
708,
705,
701,
698,
700,
703,
703,
700,
697,
696,
697,
697,
701,
703,
703,
704,
705,
708,
704,
706,
705,
702,
706,
707,
704,
708,
707,
703,
706,
707,
703,
703,
706,
707,
706]],
[False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False]],
['control: scenario 2',
[3,
20,
700,
[682, 683, 684, 687, 687, 686, 682, 683, 680, 676, 680, 683, 679, 675, 674, 671, 671, 672, 670, 672]],
[True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False]]],
[['regression: scenario 11',
[9,
10,
700,
[681,
685,
683,
685,
683,
682,
681,
682,
686,
688,
685,
688,
686,
684,
686,
688,
690,
688,
692,
696,
697,
695,
694,
692,
696,
694,
698,
702,
703,
703,
700,
698,
700,
696,
699,
698]],
[True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False]],
['regression: scenario 12',
[7,
30,
700,
[696,
694,
690,
693,
689,
689,
691,
693,
689,
687,
685,
682,
686,
689,
688,
692,
689,
689,
689,
689,
692,
694,
696,
697,
698,
698,
695,
698,
699,
702,
706,
708,
710,
714,
715]],
[True,
True,
False,
False,
False,
False,
False,
False,
True,
True,
True,
False,
False,
False,
False,
False,
True,
True,
True,
False,
False,
False,
False,
False,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False]],
['control: three cycles',
[5,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681]],
[True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]],
['regression: seven cycles per hour',
[7,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
685,
685,
685,
685,
685,
685,
685,
685,
685,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
False,
False,
True,
True,
False]],
['control: tiny error',
[6,
30,
700,
[696, 696, 696, 696, 696, 696, 696, 696, 696, 696, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698]],
[True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False]],
['control: above setpoint',
[4,
10,
700,
[705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False]],
['control: scenario 1',
[5,
10,
700,
[698,
700,
702,
701,
700,
700,
699,
697,
694,
696,
698,
694,
697,
697,
694,
698,
700,
698,
699,
700,
703,
707,
708,
706,
708,
712,
710,
706,
702,
700,
696,
696,
692]],
[True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False]],
['control: scenario 2',
[3,
10,
700,
[669,
665,
665,
665,
666,
665,
663,
665,
667,
665,
667,
663,
663,
667,
667,
668,
664,
664,
664,
663,
661,
661,
661,
664,
666,
664,
668]],
[True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]]]]
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: seven cycles per hour | [True, True, True, True, True, False, False, False, False, True, True, True, True, True, True, True, False, False, True, True, False, False, False, False, False, False, False] | [True, True, True, True, False, False, False, False, True, True, True, True, False, False, False, False, True, True, True, True, True, True, False, False, True, True, False] | Failed |
| regression: scenario 3 | [True, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, True, False, False, False, False, False, False, False, True, True, False, False, False, False, False, False, False, False] | [True, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, True, False, False, False] | Failed |
| control: three cycles | [True, True, True, True, True, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, True, True, True, True, True, True, True, True, True, True, True] | [True, True, True, True, True, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, True, True, True, True, True, True, True, True, True, True, True] | Passed |
| control: tiny error | [True, True, False, False, False, False, False, False, False, False, True, True, False, False, False, False, False, False, False, False] | [True, True, False, False, False, False, False, False, False, False, True, True, False, False, False, False, False, False, False, False] | Passed |
| control: above setpoint | [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, True, True, True, True, True, True, True, False, False, False, False, False, False, False] | [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, True, True, True, True, True, True, True, False, False, False, False, False, False, False] | Passed |
| control: scenario 1 | [True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True] | [True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True] | Passed |
| control: scenario 2 | [True, True, False, False, False, False, False, False, False, False, True, True, True, False, False, False, False, False, False, False, True, True, False] | [True, True, False, False, False, False, False, False, False, False, True, True, True, False, False, False, False, False, False, False, True, True, False] | Passed |
| control: scenario 4 | [True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True] | [True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True] | Passed |
SHA-256 / 8dc57b3f2167f64dc74bfc6e43b47d5a2cc90a4ca5026f8e7b673e70f4a4bd85
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(cph, band, setpoint, temps):
period = 60 // cph
out = []
on_left = 0
for minute, temp in enumerate(temps):
if minute % period == 0:
err = setpoint - temp
num = max(0, min(err, band)) * period
on = (2 * num + band) // (2 * band)
if 0 < on < 2:
on = 2
if 0 < period - on < 2:
on = period
on_left = on
out.append(on_left > 0)
if on_left > 0:
on_left -= 1
return out
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression: seven cycles per hour',
[7,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
685,
685,
685,
685,
685,
685,
685,
685,
685,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
False,
False,
True,
True,
False]],
['regression: scenario 3',
[7,
30,
700,
[693,
691,
695,
691,
695,
698,
697,
700,
702,
704,
706,
708,
709,
707,
706,
702,
702,
701,
698,
701,
700,
704,
703,
702,
702,
699,
695,
694,
696,
699,
696,
692,
694,
693,
694,
697,
700]],
[True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
False,
False,
False]],
['control: three cycles',
[5,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681]],
[True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]],
['control: tiny error',
[6,
30,
700,
[696, 696, 696, 696, 696, 696, 696, 696, 696, 696, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698]],
[True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False]],
['control: above setpoint',
[4,
10,
700,
[705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False]],
['control: scenario 1',
[4,
10,
700,
[673,
669,
665,
669,
667,
665,
664,
662,
659,
662,
661,
659,
660,
656,
659,
660,
656,
652,
654,
652,
656,
657,
653,
653,
653,
653,
654,
653,
650,
650,
650,
650,
651,
654,
651,
650,
650,
650,
650]],
[True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]],
['control: scenario 2',
[6,
30,
700,
[697,
695,
691,
695,
691,
692,
693,
692,
690,
690,
690,
687,
684,
683,
687,
688,
688,
691,
690,
692,
693,
689,
692]],
[True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False,
True,
True,
False]],
['control: scenario 4',
[4,
10,
700,
[680,
684,
685,
683,
684,
685,
686,
682,
681,
679,
677,
681,
680,
681,
677,
681,
680,
682,
682,
678,
677,
673,
672,
676,
673,
670,
669,
665,
662]],
[True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]]],
[['regression: scenario 5',
[9,
10,
700,
[684,
682,
680,
682,
681,
682,
686,
685,
684,
682,
679,
682,
686,
688,
688,
689,
689,
689,
693,
689,
685,
682,
681,
682,
684,
685]],
[True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False,
True,
True]],
['regression: scenario 4',
[9,
30,
700,
[705,
708,
704,
703,
700,
701,
701,
702,
699,
698,
698,
697,
698,
702,
699,
700,
701,
697,
700,
697,
694,
695,
696]],
[False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False]],
['control: three cycles',
[5,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681]],
[True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]],
['regression: seven cycles per hour',
[7,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
685,
685,
685,
685,
685,
685,
685,
685,
685,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
False,
False,
True,
True,
False]],
['control: tiny error',
[6,
30,
700,
[696, 696, 696, 696, 696, 696, 696, 696, 696, 696, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698]],
[True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False]],
['control: above setpoint',
[4,
10,
700,
[705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False]],
['control: scenario 1',
[6,
30,
700,
[690,
689,
690,
691,
689,
685,
682,
686,
682,
680,
684,
687,
690,
693,
692,
689,
688,
685,
683,
685,
687,
683,
684,
688,
691,
689,
686,
683,
679,
679,
682,
680,
680,
684]],
[True,
True,
True,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True]],
['control: scenario 2',
[6,
10,
700,
[686,
687,
685,
682,
682,
678,
681,
677,
676,
673,
674,
676,
672,
670,
669,
673,
674,
676,
675,
673,
675,
672,
673,
674,
670,
672]],
[True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]]],
[['regression: scenario 2',
[9,
20,
700,
[702,
703,
707,
703,
700,
697,
699,
698,
696,
693,
696,
695,
694,
690,
692,
695,
697,
700,
698,
699,
701,
704,
708,
712,
710,
709,
713,
709,
710,
714,
711,
711,
707,
706,
706]],
[False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
False,
False,
False,
False,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False]],
['regression: scenario 3',
[7,
30,
700,
[701,
704,
708,
708,
709,
711,
707,
709,
710,
706,
707,
703,
701,
697,
697,
698,
698,
701,
700,
699,
699,
695,
696,
700,
698,
701,
700]],
[False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
False,
False,
False,
False,
False,
False,
True,
True,
False]],
['control: three cycles',
[5,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681]],
[True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]],
['regression: seven cycles per hour',
[7,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
685,
685,
685,
685,
685,
685,
685,
685,
685,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
False,
False,
True,
True,
False]],
['control: tiny error',
[6,
30,
700,
[696, 696, 696, 696, 696, 696, 696, 696, 696, 696, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698]],
[True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False]],
['control: above setpoint',
[4,
10,
700,
[705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False]],
['regression: scenario 1',
[7,
20,
700,
[688,
691,
689,
691,
692,
691,
687,
691,
692,
691,
695,
695,
692,
689,
688,
684,
682,
681,
679,
678,
682,
682,
680,
682,
686,
689,
687,
687,
690,
686,
687,
691]],
[True,
True,
True,
True,
True,
False,
False,
False,
True,
True,
True,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False]],
['control: scenario 4',
[4,
30,
700,
[675,
676,
675,
674,
673,
676,
674,
672,
673,
672,
674,
677,
674,
671,
668,
664,
668,
667,
668,
670,
668,
670,
672]],
[True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True]]],
[['regression: scenario 8',
[7,
30,
700,
[680,
684,
686,
690,
693,
690,
694,
694,
695,
695,
691,
694,
694,
696,
699,
700,
701,
702,
706,
709,
710,
713,
715,
713,
715,
715,
715,
715,
712]],
[True,
True,
True,
True,
True,
False,
False,
False,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False]],
['regression: scenario 25',
[8,
20,
700,
[686,
685,
683,
680,
677,
673,
671,
669,
666,
666,
666,
664,
664,
664,
667,
663,
663,
662,
661,
663,
667,
666,
663,
664,
663,
665,
668,
664,
667,
670,
669,
670,
667,
666,
664,
667,
670,
666,
670,
669]],
[True,
True,
True,
True,
True,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]],
['control: three cycles',
[5,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681]],
[True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]],
['regression: seven cycles per hour',
[7,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
685,
685,
685,
685,
685,
685,
685,
685,
685,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
False,
False,
True,
True,
False]],
['control: tiny error',
[6,
30,
700,
[696, 696, 696, 696, 696, 696, 696, 696, 696, 696, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698]],
[True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False]],
['control: above setpoint',
[4,
10,
700,
[705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False]],
['control: scenario 1',
[6,
10,
700,
[702,
699,
703,
707,
704,
708,
705,
701,
698,
700,
703,
703,
700,
697,
696,
697,
697,
701,
703,
703,
704,
705,
708,
704,
706,
705,
702,
706,
707,
704,
708,
707,
703,
706,
707,
703,
703,
706,
707,
706]],
[False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False]],
['control: scenario 2',
[3,
20,
700,
[682, 683, 684, 687, 687, 686, 682, 683, 680, 676, 680, 683, 679, 675, 674, 671, 671, 672, 670, 672]],
[True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False]]],
[['regression: scenario 11',
[9,
10,
700,
[681,
685,
683,
685,
683,
682,
681,
682,
686,
688,
685,
688,
686,
684,
686,
688,
690,
688,
692,
696,
697,
695,
694,
692,
696,
694,
698,
702,
703,
703,
700,
698,
700,
696,
699,
698]],
[True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False]],
['regression: scenario 12',
[7,
30,
700,
[696,
694,
690,
693,
689,
689,
691,
693,
689,
687,
685,
682,
686,
689,
688,
692,
689,
689,
689,
689,
692,
694,
696,
697,
698,
698,
695,
698,
699,
702,
706,
708,
710,
714,
715]],
[True,
True,
False,
False,
False,
False,
False,
False,
True,
True,
True,
False,
False,
False,
False,
False,
True,
True,
True,
False,
False,
False,
False,
False,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False]],
['control: three cycles',
[5,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
690,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
700,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681,
681]],
[True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]],
['regression: seven cycles per hour',
[7,
20,
700,
[690,
690,
690,
690,
690,
690,
690,
690,
690,
685,
685,
685,
685,
685,
685,
685,
685,
685,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
False,
False,
True,
True,
False]],
['control: tiny error',
[6,
30,
700,
[696, 696, 696, 696, 696, 696, 696, 696, 696, 696, 698, 698, 698, 698, 698, 698, 698, 698, 698, 698]],
[True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False]],
['control: above setpoint',
[4,
10,
700,
[705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
705,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695,
695]],
[False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False]],
['control: scenario 1',
[5,
10,
700,
[698,
700,
702,
701,
700,
700,
699,
697,
694,
696,
698,
694,
697,
697,
694,
698,
700,
698,
699,
700,
703,
707,
708,
706,
708,
712,
710,
706,
702,
700,
696,
696,
692]],
[True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
True,
True,
True,
True,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False,
False]],
['control: scenario 2',
[3,
10,
700,
[669,
665,
665,
665,
666,
665,
663,
665,
667,
665,
667,
663,
663,
667,
667,
668,
664,
664,
664,
663,
661,
661,
661,
664,
666,
664,
668]],
[True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True,
True]]]]
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: seven cycles per hour | [True, True, True, True, False, False, False, False, True, True, True, True, False, False, False, False, True, True, True, True, True, True, False, False, True, True, False] | [True, True, True, True, False, False, False, False, True, True, True, True, False, False, False, False, True, True, True, True, True, True, False, False, True, True, False] | Passed |
| regression: scenario 3 | [True, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, True, False, False, False] | [True, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, True, False, False, False] | Passed |
| control: three cycles | [True, True, True, True, True, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, True, True, True, True, True, True, True, True, True, True, True] | [True, True, True, True, True, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, True, True, True, True, True, True, True, True, True, True, True] | Passed |
| control: tiny error | [True, True, False, False, False, False, False, False, False, False, True, True, False, False, False, False, False, False, False, False] | [True, True, False, False, False, False, False, False, False, False, True, True, False, False, False, False, False, False, False, False] | Passed |
| control: above setpoint | [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, True, True, True, True, True, True, True, False, False, False, False, False, False, False] | [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, True, True, True, True, True, True, True, False, False, False, False, False, False, False] | Passed |
| control: scenario 1 | [True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True] | [True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True] | Passed |
| control: scenario 2 | [True, True, False, False, False, False, False, False, False, False, True, True, True, False, False, False, False, False, False, False, True, True, False] | [True, True, False, False, False, False, False, False, False, False, True, True, True, False, False, False, False, False, False, False, True, True, False] | Passed |
| control: scenario 4 | [True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True] | [True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True] | Passed |
SHA-256 / 2163ea02ed66dcf1a133c071becd69c5461e878b14dd130a2bddf38f525919a7
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:48.521500+00:00.
Case digest / 7ea5cac1ea2de551ee811c7446b4569c15d9b58c64e97b2b487a26be58ade297