broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(x):
    inr = Fraction(str(x['inr']))
    lo, hi = Fraction(str(x['low'])), Fraction(str(x['high']))
    w = Fraction(str(x['weekly_mg']))
    action = 'ADJUST'
    if inr >= 5:
        action, w = 'HOLD', w * Fraction(85, 100)
    elif inr > hi:
        w = w * Fraction(90, 100)
    elif inr >= lo:
        action = 'CONTINUE'
    elif inr >= lo - Fraction(1, 2):
        w = w * Fraction(105, 100)
    else:
        w = w * Fraction(110, 100)
    units = math.floor(w * 2)
    base, extra = divmod(units, 7)
    plan = [(base + 1) / 2] * extra + [base / 2] * (7 - extra)
    return {'action': action, 'weekly_mg': units / 2, 'plan': plan}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('INR exactly 5 holds',
   {'inr': '5.0', 'weekly_mg': 31, 'low': 2, 'high': 3},
   {'action': 'HOLD', 'weekly_mg': 26.5, 'plan': [4.0, 4.0, 4.0, 4.0, 3.5, 3.5, 3.5]}),
  ('high target range above 3',
   {'inr': '5.2', 'weekly_mg': 35, 'low': '2.5', 'high': '3.5'},
   {'action': 'HOLD', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('INR at upper target continues',
   {'inr': '3.5', 'weekly_mg': 29, 'low': '2.5', 'high': '3.5'},
   {'action': 'CONTINUE', 'weekly_mg': 29.0, 'plan': [4.5, 4.5, 4.0, 4.0, 4.0, 4.0, 4.0]}),
  ('INR at lower target continues',
   {'inr': '2.0', 'weekly_mg': 31, 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 31.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.0]}),
  ('INR exactly half below target',
   {'inr': '1.5', 'weekly_mg': 22, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 23.0, 'plan': [3.5, 3.5, 3.5, 3.5, 3.0, 3.0, 3.0]}),
  ('INR well below target',
   {'inr': '1.2', 'weekly_mg': 26, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 28.5, 'plan': [4.5, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0]}),
  ('weekly rounding half-up',
   {'inr': '1.8', 'weekly_mg': 25, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 26.5, 'plan': [4.0, 4.0, 4.0, 4.0, 3.5, 3.5, 3.5]}),
  ('uneven weekly split',
   {'inr': '2.5', 'weekly_mg': '32.5', 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 32.5, 'plan': [5.0, 5.0, 4.5, 4.5, 4.5, 4.5, 4.5]})],
 [('INR exactly 5 holds',
   {'inr': '5.0', 'weekly_mg': 32, 'low': 2, 'high': 3},
   {'action': 'HOLD', 'weekly_mg': 27.0, 'plan': [4.0, 4.0, 4.0, 4.0, 4.0, 3.5, 3.5]}),
  ('high target range above 3',
   {'inr': '5.2', 'weekly_mg': 35, 'low': '2.5', 'high': '3.5'},
   {'action': 'HOLD', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('INR at upper target continues',
   {'inr': '3.5', 'weekly_mg': 30, 'low': '2.5', 'high': '3.5'},
   {'action': 'CONTINUE', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('INR at lower target continues',
   {'inr': '2.0', 'weekly_mg': 32, 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 32.0, 'plan': [5.0, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5]}),
  ('INR exactly half below target',
   {'inr': '1.5', 'weekly_mg': 24, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 25.0, 'plan': [4.0, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5]}),
  ('INR well below target',
   {'inr': '1.2', 'weekly_mg': 27, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 29.5, 'plan': [4.5, 4.5, 4.5, 4.0, 4.0, 4.0, 4.0]}),
  ('weekly rounding half-up',
   {'inr': '1.8', 'weekly_mg': 45, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 47.5, 'plan': [7.0, 7.0, 7.0, 7.0, 6.5, 6.5, 6.5]}),
  ('uneven weekly split',
   {'inr': '2.5', 'weekly_mg': '27.5', 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 27.5, 'plan': [4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 3.5]})],
 [('INR exactly 5 holds',
   {'inr': '5.0', 'weekly_mg': 33, 'low': 2, 'high': 3},
   {'action': 'HOLD', 'weekly_mg': 28.0, 'plan': [4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0]}),
  ('high target range above 3',
   {'inr': '5.2', 'weekly_mg': 35, 'low': '2.5', 'high': '3.5'},
   {'action': 'HOLD', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('INR at upper target continues',
   {'inr': '3.5', 'weekly_mg': 31, 'low': '2.5', 'high': '3.5'},
   {'action': 'CONTINUE', 'weekly_mg': 31.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.0]}),
  ('INR at lower target continues',
   {'inr': '2.0', 'weekly_mg': 33, 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 33.0, 'plan': [5.0, 5.0, 5.0, 4.5, 4.5, 4.5, 4.5]}),
  ('INR exactly half below target',
   {'inr': '1.5', 'weekly_mg': 26, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 27.5, 'plan': [4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 3.5]}),
  ('INR well below target',
   {'inr': '1.2', 'weekly_mg': 28, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 31.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.0]}),
  ('weekly rounding half-up',
   {'inr': '1.8', 'weekly_mg': 65, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 68.5, 'plan': [10.0, 10.0, 10.0, 10.0, 9.5, 9.5, 9.5]}),
  ('uneven weekly split',
   {'inr': '2.5', 'weekly_mg': '31', 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 31.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.0]})],
 [('INR exactly 5 holds',
   {'inr': '5.0', 'weekly_mg': 34, 'low': 2, 'high': 3},
   {'action': 'HOLD', 'weekly_mg': 29.0, 'plan': [4.5, 4.5, 4.0, 4.0, 4.0, 4.0, 4.0]}),
  ('high target range above 3',
   {'inr': '5.2', 'weekly_mg': 35, 'low': '2.5', 'high': '3.5'},
   {'action': 'HOLD', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('INR at upper target continues',
   {'inr': '3.5', 'weekly_mg': 32, 'low': '2.5', 'high': '3.5'},
   {'action': 'CONTINUE', 'weekly_mg': 32.0, 'plan': [5.0, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5]}),
  ('INR at lower target continues',
   {'inr': '2.0', 'weekly_mg': 34, 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 34.0, 'plan': [5.0, 5.0, 5.0, 5.0, 5.0, 4.5, 4.5]}),
  ('INR exactly half below target',
   {'inr': '1.5', 'weekly_mg': 28, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 29.5, 'plan': [4.5, 4.5, 4.5, 4.0, 4.0, 4.0, 4.0]}),
  ('INR well below target',
   {'inr': '1.2', 'weekly_mg': 29, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 32.0, 'plan': [5.0, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5]}),
  ('weekly rounding half-up',
   {'inr': '1.8', 'weekly_mg': 85, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 89.5, 'plan': [13.0, 13.0, 13.0, 13.0, 12.5, 12.5, 12.5]}),
  ('uneven weekly split',
   {'inr': '2.5', 'weekly_mg': '22.5', 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 22.5, 'plan': [3.5, 3.5, 3.5, 3.0, 3.0, 3.0, 3.0]})],
 [('INR exactly 5 holds',
   {'inr': '5.0', 'weekly_mg': 35, 'low': 2, 'high': 3},
   {'action': 'HOLD', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('high target range above 3',
   {'inr': '5.2', 'weekly_mg': 35, 'low': '2.5', 'high': '3.5'},
   {'action': 'HOLD', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('INR at upper target continues',
   {'inr': '3.5', 'weekly_mg': 33, 'low': '2.5', 'high': '3.5'},
   {'action': 'CONTINUE', 'weekly_mg': 33.0, 'plan': [5.0, 5.0, 5.0, 4.5, 4.5, 4.5, 4.5]}),
  ('INR at lower target continues',
   {'inr': '2.0', 'weekly_mg': 35, 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 35.0, 'plan': [5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0]}),
  ('INR exactly half below target',
   {'inr': '1.5', 'weekly_mg': 30, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 31.5, 'plan': [4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5]}),
  ('INR well below target',
   {'inr': '1.2', 'weekly_mg': 30, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 33.0, 'plan': [5.0, 5.0, 5.0, 4.5, 4.5, 4.5, 4.5]}),
  ('weekly rounding half-up',
   {'inr': '1.8', 'weekly_mg': 105, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 110.5, 'plan': [16.0, 16.0, 16.0, 16.0, 15.5, 15.5, 15.5]}),
  ('uneven weekly split',
   {'inr': '2.5', 'weekly_mg': '38', 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 38.0, 'plan': [5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.0]})]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(x):
    inr = Fraction(str(x['inr']))
    lo, hi = Fraction(str(x['low'])), Fraction(str(x['high']))
    w = Fraction(str(x['weekly_mg']))
    action = 'ADJUST'
    if inr >= 5:
        action, w = 'HOLD', w * Fraction(85, 100)
    elif inr > hi:
        w = w * Fraction(90, 100)
    elif inr >= lo:
        action = 'CONTINUE'
    elif inr >= lo - Fraction(1, 2):
        w = w * Fraction(105, 100)
    else:
        w = w * Fraction(110, 100)
    units = round(w * 2)
    base, extra = divmod(units, 7)
    plan = [(base + 1) / 2] * extra + [base / 2] * (7 - extra)
    return {'action': action, 'weekly_mg': units / 2, 'plan': plan}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('INR exactly 5 holds',
   {'inr': '5.0', 'weekly_mg': 31, 'low': 2, 'high': 3},
   {'action': 'HOLD', 'weekly_mg': 26.5, 'plan': [4.0, 4.0, 4.0, 4.0, 3.5, 3.5, 3.5]}),
  ('high target range above 3',
   {'inr': '5.2', 'weekly_mg': 35, 'low': '2.5', 'high': '3.5'},
   {'action': 'HOLD', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('INR at upper target continues',
   {'inr': '3.5', 'weekly_mg': 29, 'low': '2.5', 'high': '3.5'},
   {'action': 'CONTINUE', 'weekly_mg': 29.0, 'plan': [4.5, 4.5, 4.0, 4.0, 4.0, 4.0, 4.0]}),
  ('INR at lower target continues',
   {'inr': '2.0', 'weekly_mg': 31, 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 31.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.0]}),
  ('INR exactly half below target',
   {'inr': '1.5', 'weekly_mg': 22, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 23.0, 'plan': [3.5, 3.5, 3.5, 3.5, 3.0, 3.0, 3.0]}),
  ('INR well below target',
   {'inr': '1.2', 'weekly_mg': 26, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 28.5, 'plan': [4.5, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0]}),
  ('weekly rounding half-up',
   {'inr': '1.8', 'weekly_mg': 25, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 26.5, 'plan': [4.0, 4.0, 4.0, 4.0, 3.5, 3.5, 3.5]}),
  ('uneven weekly split',
   {'inr': '2.5', 'weekly_mg': '32.5', 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 32.5, 'plan': [5.0, 5.0, 4.5, 4.5, 4.5, 4.5, 4.5]})],
 [('INR exactly 5 holds',
   {'inr': '5.0', 'weekly_mg': 32, 'low': 2, 'high': 3},
   {'action': 'HOLD', 'weekly_mg': 27.0, 'plan': [4.0, 4.0, 4.0, 4.0, 4.0, 3.5, 3.5]}),
  ('high target range above 3',
   {'inr': '5.2', 'weekly_mg': 35, 'low': '2.5', 'high': '3.5'},
   {'action': 'HOLD', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('INR at upper target continues',
   {'inr': '3.5', 'weekly_mg': 30, 'low': '2.5', 'high': '3.5'},
   {'action': 'CONTINUE', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('INR at lower target continues',
   {'inr': '2.0', 'weekly_mg': 32, 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 32.0, 'plan': [5.0, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5]}),
  ('INR exactly half below target',
   {'inr': '1.5', 'weekly_mg': 24, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 25.0, 'plan': [4.0, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5]}),
  ('INR well below target',
   {'inr': '1.2', 'weekly_mg': 27, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 29.5, 'plan': [4.5, 4.5, 4.5, 4.0, 4.0, 4.0, 4.0]}),
  ('weekly rounding half-up',
   {'inr': '1.8', 'weekly_mg': 45, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 47.5, 'plan': [7.0, 7.0, 7.0, 7.0, 6.5, 6.5, 6.5]}),
  ('uneven weekly split',
   {'inr': '2.5', 'weekly_mg': '27.5', 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 27.5, 'plan': [4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 3.5]})],
 [('INR exactly 5 holds',
   {'inr': '5.0', 'weekly_mg': 33, 'low': 2, 'high': 3},
   {'action': 'HOLD', 'weekly_mg': 28.0, 'plan': [4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0]}),
  ('high target range above 3',
   {'inr': '5.2', 'weekly_mg': 35, 'low': '2.5', 'high': '3.5'},
   {'action': 'HOLD', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('INR at upper target continues',
   {'inr': '3.5', 'weekly_mg': 31, 'low': '2.5', 'high': '3.5'},
   {'action': 'CONTINUE', 'weekly_mg': 31.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.0]}),
  ('INR at lower target continues',
   {'inr': '2.0', 'weekly_mg': 33, 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 33.0, 'plan': [5.0, 5.0, 5.0, 4.5, 4.5, 4.5, 4.5]}),
  ('INR exactly half below target',
   {'inr': '1.5', 'weekly_mg': 26, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 27.5, 'plan': [4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 3.5]}),
  ('INR well below target',
   {'inr': '1.2', 'weekly_mg': 28, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 31.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.0]}),
  ('weekly rounding half-up',
   {'inr': '1.8', 'weekly_mg': 65, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 68.5, 'plan': [10.0, 10.0, 10.0, 10.0, 9.5, 9.5, 9.5]}),
  ('uneven weekly split',
   {'inr': '2.5', 'weekly_mg': '31', 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 31.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.0]})],
 [('INR exactly 5 holds',
   {'inr': '5.0', 'weekly_mg': 34, 'low': 2, 'high': 3},
   {'action': 'HOLD', 'weekly_mg': 29.0, 'plan': [4.5, 4.5, 4.0, 4.0, 4.0, 4.0, 4.0]}),
  ('high target range above 3',
   {'inr': '5.2', 'weekly_mg': 35, 'low': '2.5', 'high': '3.5'},
   {'action': 'HOLD', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('INR at upper target continues',
   {'inr': '3.5', 'weekly_mg': 32, 'low': '2.5', 'high': '3.5'},
   {'action': 'CONTINUE', 'weekly_mg': 32.0, 'plan': [5.0, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5]}),
  ('INR at lower target continues',
   {'inr': '2.0', 'weekly_mg': 34, 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 34.0, 'plan': [5.0, 5.0, 5.0, 5.0, 5.0, 4.5, 4.5]}),
  ('INR exactly half below target',
   {'inr': '1.5', 'weekly_mg': 28, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 29.5, 'plan': [4.5, 4.5, 4.5, 4.0, 4.0, 4.0, 4.0]}),
  ('INR well below target',
   {'inr': '1.2', 'weekly_mg': 29, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 32.0, 'plan': [5.0, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5]}),
  ('weekly rounding half-up',
   {'inr': '1.8', 'weekly_mg': 85, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 89.5, 'plan': [13.0, 13.0, 13.0, 13.0, 12.5, 12.5, 12.5]}),
  ('uneven weekly split',
   {'inr': '2.5', 'weekly_mg': '22.5', 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 22.5, 'plan': [3.5, 3.5, 3.5, 3.0, 3.0, 3.0, 3.0]})],
 [('INR exactly 5 holds',
   {'inr': '5.0', 'weekly_mg': 35, 'low': 2, 'high': 3},
   {'action': 'HOLD', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('high target range above 3',
   {'inr': '5.2', 'weekly_mg': 35, 'low': '2.5', 'high': '3.5'},
   {'action': 'HOLD', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('INR at upper target continues',
   {'inr': '3.5', 'weekly_mg': 33, 'low': '2.5', 'high': '3.5'},
   {'action': 'CONTINUE', 'weekly_mg': 33.0, 'plan': [5.0, 5.0, 5.0, 4.5, 4.5, 4.5, 4.5]}),
  ('INR at lower target continues',
   {'inr': '2.0', 'weekly_mg': 35, 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 35.0, 'plan': [5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0]}),
  ('INR exactly half below target',
   {'inr': '1.5', 'weekly_mg': 30, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 31.5, 'plan': [4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5]}),
  ('INR well below target',
   {'inr': '1.2', 'weekly_mg': 30, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 33.0, 'plan': [5.0, 5.0, 5.0, 4.5, 4.5, 4.5, 4.5]}),
  ('weekly rounding half-up',
   {'inr': '1.8', 'weekly_mg': 105, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 110.5, 'plan': [16.0, 16.0, 16.0, 16.0, 15.5, 15.5, 15.5]}),
  ('uneven weekly split',
   {'inr': '2.5', 'weekly_mg': '38', 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 38.0, 'plan': [5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.0]})]]
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)

prompt:
A 22.75 mg weekly requirement rounds down to 22.5 mg.

Input {inr, weekly_mg, low, high}. Toy table: inr >= 5 HOLD and weekly x0.85; high < inr < 5 x0.90; low <= inr <= high CONTINUE unchanged; low-0.5 <= inr < low x1.05; lower x1.10 (ADJUST otherwise). New weekly total rounds half-up to 0.5 mg; the plan spreads it over 7 days in 0.5 mg units as evenly as possible with the larger doses on the first days. Return {action, weekly_mg, plan}.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(x):
    inr = Fraction(str(x['inr']))
    lo, hi = Fraction(str(x['low'])), Fraction(str(x['high']))
    w = Fraction(str(x['weekly_mg']))
    action = 'ADJUST'
    if inr >= 5:
        action, w = 'HOLD', w * Fraction(85, 100)
    elif inr > hi:
        w = w * Fraction(90, 100)
    elif inr >= lo:
        action = 'CONTINUE'
    elif inr >= lo - Fraction(1, 2):
        w = w * Fraction(105, 100)
    else:
        w = w * Fraction(110, 100)
    units = math.floor(w * 2 + Fraction(1, 2))
    base, extra = divmod(units, 7)
    plan = [base / 2] * 7
    return {'action': action, 'weekly_mg': units / 2, 'plan': plan}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('INR exactly 5 holds',
   {'inr': '5.0', 'weekly_mg': 31, 'low': 2, 'high': 3},
   {'action': 'HOLD', 'weekly_mg': 26.5, 'plan': [4.0, 4.0, 4.0, 4.0, 3.5, 3.5, 3.5]}),
  ('high target range above 3',
   {'inr': '5.2', 'weekly_mg': 35, 'low': '2.5', 'high': '3.5'},
   {'action': 'HOLD', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('INR at upper target continues',
   {'inr': '3.5', 'weekly_mg': 29, 'low': '2.5', 'high': '3.5'},
   {'action': 'CONTINUE', 'weekly_mg': 29.0, 'plan': [4.5, 4.5, 4.0, 4.0, 4.0, 4.0, 4.0]}),
  ('INR at lower target continues',
   {'inr': '2.0', 'weekly_mg': 31, 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 31.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.0]}),
  ('INR exactly half below target',
   {'inr': '1.5', 'weekly_mg': 22, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 23.0, 'plan': [3.5, 3.5, 3.5, 3.5, 3.0, 3.0, 3.0]}),
  ('INR well below target',
   {'inr': '1.2', 'weekly_mg': 26, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 28.5, 'plan': [4.5, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0]}),
  ('weekly rounding half-up',
   {'inr': '1.8', 'weekly_mg': 25, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 26.5, 'plan': [4.0, 4.0, 4.0, 4.0, 3.5, 3.5, 3.5]}),
  ('uneven weekly split',
   {'inr': '2.5', 'weekly_mg': '32.5', 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 32.5, 'plan': [5.0, 5.0, 4.5, 4.5, 4.5, 4.5, 4.5]})],
 [('INR exactly 5 holds',
   {'inr': '5.0', 'weekly_mg': 32, 'low': 2, 'high': 3},
   {'action': 'HOLD', 'weekly_mg': 27.0, 'plan': [4.0, 4.0, 4.0, 4.0, 4.0, 3.5, 3.5]}),
  ('high target range above 3',
   {'inr': '5.2', 'weekly_mg': 35, 'low': '2.5', 'high': '3.5'},
   {'action': 'HOLD', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('INR at upper target continues',
   {'inr': '3.5', 'weekly_mg': 30, 'low': '2.5', 'high': '3.5'},
   {'action': 'CONTINUE', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('INR at lower target continues',
   {'inr': '2.0', 'weekly_mg': 32, 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 32.0, 'plan': [5.0, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5]}),
  ('INR exactly half below target',
   {'inr': '1.5', 'weekly_mg': 24, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 25.0, 'plan': [4.0, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5]}),
  ('INR well below target',
   {'inr': '1.2', 'weekly_mg': 27, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 29.5, 'plan': [4.5, 4.5, 4.5, 4.0, 4.0, 4.0, 4.0]}),
  ('weekly rounding half-up',
   {'inr': '1.8', 'weekly_mg': 45, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 47.5, 'plan': [7.0, 7.0, 7.0, 7.0, 6.5, 6.5, 6.5]}),
  ('uneven weekly split',
   {'inr': '2.5', 'weekly_mg': '27.5', 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 27.5, 'plan': [4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 3.5]})],
 [('INR exactly 5 holds',
   {'inr': '5.0', 'weekly_mg': 33, 'low': 2, 'high': 3},
   {'action': 'HOLD', 'weekly_mg': 28.0, 'plan': [4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0]}),
  ('high target range above 3',
   {'inr': '5.2', 'weekly_mg': 35, 'low': '2.5', 'high': '3.5'},
   {'action': 'HOLD', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('INR at upper target continues',
   {'inr': '3.5', 'weekly_mg': 31, 'low': '2.5', 'high': '3.5'},
   {'action': 'CONTINUE', 'weekly_mg': 31.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.0]}),
  ('INR at lower target continues',
   {'inr': '2.0', 'weekly_mg': 33, 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 33.0, 'plan': [5.0, 5.0, 5.0, 4.5, 4.5, 4.5, 4.5]}),
  ('INR exactly half below target',
   {'inr': '1.5', 'weekly_mg': 26, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 27.5, 'plan': [4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 3.5]}),
  ('INR well below target',
   {'inr': '1.2', 'weekly_mg': 28, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 31.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.0]}),
  ('weekly rounding half-up',
   {'inr': '1.8', 'weekly_mg': 65, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 68.5, 'plan': [10.0, 10.0, 10.0, 10.0, 9.5, 9.5, 9.5]}),
  ('uneven weekly split',
   {'inr': '2.5', 'weekly_mg': '31', 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 31.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.0]})],
 [('INR exactly 5 holds',
   {'inr': '5.0', 'weekly_mg': 34, 'low': 2, 'high': 3},
   {'action': 'HOLD', 'weekly_mg': 29.0, 'plan': [4.5, 4.5, 4.0, 4.0, 4.0, 4.0, 4.0]}),
  ('high target range above 3',
   {'inr': '5.2', 'weekly_mg': 35, 'low': '2.5', 'high': '3.5'},
   {'action': 'HOLD', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('INR at upper target continues',
   {'inr': '3.5', 'weekly_mg': 32, 'low': '2.5', 'high': '3.5'},
   {'action': 'CONTINUE', 'weekly_mg': 32.0, 'plan': [5.0, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5]}),
  ('INR at lower target continues',
   {'inr': '2.0', 'weekly_mg': 34, 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 34.0, 'plan': [5.0, 5.0, 5.0, 5.0, 5.0, 4.5, 4.5]}),
  ('INR exactly half below target',
   {'inr': '1.5', 'weekly_mg': 28, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 29.5, 'plan': [4.5, 4.5, 4.5, 4.0, 4.0, 4.0, 4.0]}),
  ('INR well below target',
   {'inr': '1.2', 'weekly_mg': 29, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 32.0, 'plan': [5.0, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5]}),
  ('weekly rounding half-up',
   {'inr': '1.8', 'weekly_mg': 85, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 89.5, 'plan': [13.0, 13.0, 13.0, 13.0, 12.5, 12.5, 12.5]}),
  ('uneven weekly split',
   {'inr': '2.5', 'weekly_mg': '22.5', 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 22.5, 'plan': [3.5, 3.5, 3.5, 3.0, 3.0, 3.0, 3.0]})],
 [('INR exactly 5 holds',
   {'inr': '5.0', 'weekly_mg': 35, 'low': 2, 'high': 3},
   {'action': 'HOLD', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('high target range above 3',
   {'inr': '5.2', 'weekly_mg': 35, 'low': '2.5', 'high': '3.5'},
   {'action': 'HOLD', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('INR at upper target continues',
   {'inr': '3.5', 'weekly_mg': 33, 'low': '2.5', 'high': '3.5'},
   {'action': 'CONTINUE', 'weekly_mg': 33.0, 'plan': [5.0, 5.0, 5.0, 4.5, 4.5, 4.5, 4.5]}),
  ('INR at lower target continues',
   {'inr': '2.0', 'weekly_mg': 35, 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 35.0, 'plan': [5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0]}),
  ('INR exactly half below target',
   {'inr': '1.5', 'weekly_mg': 30, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 31.5, 'plan': [4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5]}),
  ('INR well below target',
   {'inr': '1.2', 'weekly_mg': 30, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 33.0, 'plan': [5.0, 5.0, 5.0, 4.5, 4.5, 4.5, 4.5]}),
  ('weekly rounding half-up',
   {'inr': '1.8', 'weekly_mg': 105, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 110.5, 'plan': [16.0, 16.0, 16.0, 16.0, 15.5, 15.5, 15.5]}),
  ('uneven weekly split',
   {'inr': '2.5', 'weekly_mg': '38', 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 38.0, 'plan': [5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.0]})]]
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)

meaning: Fixture-count band, not measured model difficulty

deps: stdlib

source:
"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(x):
    inr = Fraction(str(x['inr']))
    lo, hi = Fraction(str(x['low'])), Fraction(str(x['high']))
    w = Fraction(str(x['weekly_mg']))
    action = 'ADJUST'
    if inr >= 5:
        action, w = 'HOLD', w * Fraction(85, 100)
    elif inr > hi:
        w = w * Fraction(90, 100)
    elif inr >= lo:
        action = 'CONTINUE'
    elif inr >= lo - Fraction(1, 2):
        w = w * Fraction(105, 100)
    else:
        w = w * Fraction(110, 100)
    units = math.floor(w * 2 + Fraction(1, 2))
    base, extra = divmod(units, 7)
    plan = [base / 2] * (7 - extra) + [(base + 1) / 2] * extra
    return {'action': action, 'weekly_mg': units / 2, 'plan': plan}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('INR exactly 5 holds',
   {'inr': '5.0', 'weekly_mg': 31, 'low': 2, 'high': 3},
   {'action': 'HOLD', 'weekly_mg': 26.5, 'plan': [4.0, 4.0, 4.0, 4.0, 3.5, 3.5, 3.5]}),
  ('high target range above 3',
   {'inr': '5.2', 'weekly_mg': 35, 'low': '2.5', 'high': '3.5'},
   {'action': 'HOLD', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('INR at upper target continues',
   {'inr': '3.5', 'weekly_mg': 29, 'low': '2.5', 'high': '3.5'},
   {'action': 'CONTINUE', 'weekly_mg': 29.0, 'plan': [4.5, 4.5, 4.0, 4.0, 4.0, 4.0, 4.0]}),
  ('INR at lower target continues',
   {'inr': '2.0', 'weekly_mg': 31, 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 31.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.0]}),
  ('INR exactly half below target',
   {'inr': '1.5', 'weekly_mg': 22, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 23.0, 'plan': [3.5, 3.5, 3.5, 3.5, 3.0, 3.0, 3.0]}),
  ('INR well below target',
   {'inr': '1.2', 'weekly_mg': 26, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 28.5, 'plan': [4.5, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0]}),
  ('weekly rounding half-up',
   {'inr': '1.8', 'weekly_mg': 25, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 26.5, 'plan': [4.0, 4.0, 4.0, 4.0, 3.5, 3.5, 3.5]}),
  ('uneven weekly split',
   {'inr': '2.5', 'weekly_mg': '32.5', 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 32.5, 'plan': [5.0, 5.0, 4.5, 4.5, 4.5, 4.5, 4.5]})],
 [('INR exactly 5 holds',
   {'inr': '5.0', 'weekly_mg': 32, 'low': 2, 'high': 3},
   {'action': 'HOLD', 'weekly_mg': 27.0, 'plan': [4.0, 4.0, 4.0, 4.0, 4.0, 3.5, 3.5]}),
  ('high target range above 3',
   {'inr': '5.2', 'weekly_mg': 35, 'low': '2.5', 'high': '3.5'},
   {'action': 'HOLD', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('INR at upper target continues',
   {'inr': '3.5', 'weekly_mg': 30, 'low': '2.5', 'high': '3.5'},
   {'action': 'CONTINUE', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('INR at lower target continues',
   {'inr': '2.0', 'weekly_mg': 32, 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 32.0, 'plan': [5.0, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5]}),
  ('INR exactly half below target',
   {'inr': '1.5', 'weekly_mg': 24, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 25.0, 'plan': [4.0, 3.5, 3.5, 3.5, 3.5, 3.5, 3.5]}),
  ('INR well below target',
   {'inr': '1.2', 'weekly_mg': 27, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 29.5, 'plan': [4.5, 4.5, 4.5, 4.0, 4.0, 4.0, 4.0]}),
  ('weekly rounding half-up',
   {'inr': '1.8', 'weekly_mg': 45, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 47.5, 'plan': [7.0, 7.0, 7.0, 7.0, 6.5, 6.5, 6.5]}),
  ('uneven weekly split',
   {'inr': '2.5', 'weekly_mg': '27.5', 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 27.5, 'plan': [4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 3.5]})],
 [('INR exactly 5 holds',
   {'inr': '5.0', 'weekly_mg': 33, 'low': 2, 'high': 3},
   {'action': 'HOLD', 'weekly_mg': 28.0, 'plan': [4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 4.0]}),
  ('high target range above 3',
   {'inr': '5.2', 'weekly_mg': 35, 'low': '2.5', 'high': '3.5'},
   {'action': 'HOLD', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('INR at upper target continues',
   {'inr': '3.5', 'weekly_mg': 31, 'low': '2.5', 'high': '3.5'},
   {'action': 'CONTINUE', 'weekly_mg': 31.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.0]}),
  ('INR at lower target continues',
   {'inr': '2.0', 'weekly_mg': 33, 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 33.0, 'plan': [5.0, 5.0, 5.0, 4.5, 4.5, 4.5, 4.5]}),
  ('INR exactly half below target',
   {'inr': '1.5', 'weekly_mg': 26, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 27.5, 'plan': [4.0, 4.0, 4.0, 4.0, 4.0, 4.0, 3.5]}),
  ('INR well below target',
   {'inr': '1.2', 'weekly_mg': 28, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 31.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.0]}),
  ('weekly rounding half-up',
   {'inr': '1.8', 'weekly_mg': 65, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 68.5, 'plan': [10.0, 10.0, 10.0, 10.0, 9.5, 9.5, 9.5]}),
  ('uneven weekly split',
   {'inr': '2.5', 'weekly_mg': '31', 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 31.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.0]})],
 [('INR exactly 5 holds',
   {'inr': '5.0', 'weekly_mg': 34, 'low': 2, 'high': 3},
   {'action': 'HOLD', 'weekly_mg': 29.0, 'plan': [4.5, 4.5, 4.0, 4.0, 4.0, 4.0, 4.0]}),
  ('high target range above 3',
   {'inr': '5.2', 'weekly_mg': 35, 'low': '2.5', 'high': '3.5'},
   {'action': 'HOLD', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('INR at upper target continues',
   {'inr': '3.5', 'weekly_mg': 32, 'low': '2.5', 'high': '3.5'},
   {'action': 'CONTINUE', 'weekly_mg': 32.0, 'plan': [5.0, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5]}),
  ('INR at lower target continues',
   {'inr': '2.0', 'weekly_mg': 34, 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 34.0, 'plan': [5.0, 5.0, 5.0, 5.0, 5.0, 4.5, 4.5]}),
  ('INR exactly half below target',
   {'inr': '1.5', 'weekly_mg': 28, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 29.5, 'plan': [4.5, 4.5, 4.5, 4.0, 4.0, 4.0, 4.0]}),
  ('INR well below target',
   {'inr': '1.2', 'weekly_mg': 29, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 32.0, 'plan': [5.0, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5]}),
  ('weekly rounding half-up',
   {'inr': '1.8', 'weekly_mg': 85, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 89.5, 'plan': [13.0, 13.0, 13.0, 13.0, 12.5, 12.5, 12.5]}),
  ('uneven weekly split',
   {'inr': '2.5', 'weekly_mg': '22.5', 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 22.5, 'plan': [3.5, 3.5, 3.5, 3.0, 3.0, 3.0, 3.0]})],
 [('INR exactly 5 holds',
   {'inr': '5.0', 'weekly_mg': 35, 'low': 2, 'high': 3},
   {'action': 'HOLD', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('high target range above 3',
   {'inr': '5.2', 'weekly_mg': 35, 'low': '2.5', 'high': '3.5'},
   {'action': 'HOLD', 'weekly_mg': 30.0, 'plan': [4.5, 4.5, 4.5, 4.5, 4.0, 4.0, 4.0]}),
  ('INR at upper target continues',
   {'inr': '3.5', 'weekly_mg': 33, 'low': '2.5', 'high': '3.5'},
   {'action': 'CONTINUE', 'weekly_mg': 33.0, 'plan': [5.0, 5.0, 5.0, 4.5, 4.5, 4.5, 4.5]}),
  ('INR at lower target continues',
   {'inr': '2.0', 'weekly_mg': 35, 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 35.0, 'plan': [5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0]}),
  ('INR exactly half below target',
   {'inr': '1.5', 'weekly_mg': 30, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 31.5, 'plan': [4.5, 4.5, 4.5, 4.5, 4.5, 4.5, 4.5]}),
  ('INR well below target',
   {'inr': '1.2', 'weekly_mg': 30, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 33.0, 'plan': [5.0, 5.0, 5.0, 4.5, 4.5, 4.5, 4.5]}),
  ('weekly rounding half-up',
   {'inr': '1.8', 'weekly_mg': 105, 'low': 2, 'high': 3},
   {'action': 'ADJUST', 'weekly_mg': 110.5, 'plan': [16.0, 16.0, 16.0, 16.0, 15.5, 15.5, 15.5]}),
  ('uneven weekly split',
   {'inr': '2.5', 'weekly_mg': '38', 'low': 2, 'high': 3},
   {'action': 'CONTINUE', 'weekly_mg': 38.0, 'plan': [5.5, 5.5, 5.5, 5.5, 5.5, 5.5, 5.0]})]]
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)

prompt:
The daily plan adds up to less than the weekly total.

Input {inr, weekly_mg, low, high}. Toy table: inr >= 5 HOLD and weekly x0.85; high < inr < 5 x0.90; low <= inr <= high CONTINUE unchanged; low-0.5 <= inr < low x1.05; lower x1.10 (ADJUST otherwise). New weekly total rounds half-up to 0.5 mg; the plan spreads it over 7 days in 0.5 mg units as evenly as possible with the larger doses on the first days. Return {action, weekly_mg, plan}.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(x):
    left = Fraction(x['bag_ml'])
    segs = x['segments']
    for i, (t0, rate) in enumerate(segs):
        t1 = segs[i + 1][0] if i + 1 < len(segs) else None
        if rate == 0:
            continue
        per_min = Fraction(rate)
        need = left / per_min
        if t1 is None or t0 + need <= t1:
            empty = t0 + need
            return {'empty_min': round(float(empty), 1), 'alarm_min': round(float(max(Fraction(0), empty - 30)), 1)}
        left -= per_min * (t1 - t0)
    return {'empty_min': None, 'alarm_min': None}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('single rate', {'bag_ml': 500, 'segments': [[0, 125]]}, {'empty_min': 240.0, 'alarm_min': 210.0}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 260]]},
   {'empty_min': 355.4, 'alarm_min': 325.4}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [150, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 110, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 31]]},
   {'empty_min': 272.9, 'alarm_min': 242.9}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 80]]},
   {'empty_min': 15.0, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 30]]},
   {'empty_min': 230.0, 'alarm_min': 200.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 11]]},
   {'empty_min': 5241.8, 'alarm_min': 5211.8})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 150]]}, {'empty_min': 200.0, 'alarm_min': 170.0}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 270]]},
   {'empty_min': 351.1, 'alarm_min': 321.1}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [180, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 120, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 32]]},
   {'empty_min': 266.2, 'alarm_min': 236.2}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 100]]},
   {'empty_min': 12.0, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 60]]},
   {'empty_min': 160.0, 'alarm_min': 130.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 12]]},
   {'empty_min': 4810.0, 'alarm_min': 4780.0})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 175]]}, {'empty_min': 171.4, 'alarm_min': 141.4}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 280]]},
   {'empty_min': 347.1, 'alarm_min': 317.1}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [210, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 130, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 33]]},
   {'empty_min': 260.0, 'alarm_min': 230.0}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 120]]},
   {'empty_min': 10.0, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 90]]},
   {'empty_min': 136.7, 'alarm_min': 106.7}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 13]]},
   {'empty_min': 4444.6, 'alarm_min': 4414.6})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 200]]}, {'empty_min': 150.0, 'alarm_min': 120.0}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 290]]},
   {'empty_min': 343.4, 'alarm_min': 313.4}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [240, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 140, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 34]]},
   {'empty_min': 254.1, 'alarm_min': 224.1}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 140]]},
   {'empty_min': 8.6, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 120]]},
   {'empty_min': 125.0, 'alarm_min': 95.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 14]]},
   {'empty_min': 4131.4, 'alarm_min': 4101.4})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 225]]}, {'empty_min': 133.3, 'alarm_min': 103.3}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 300]]},
   {'empty_min': 340.0, 'alarm_min': 310.0}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [270, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 150, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 35]]},
   {'empty_min': 248.6, 'alarm_min': 218.6}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 160]]},
   {'empty_min': 7.5, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 150]]},
   {'empty_min': 118.0, 'alarm_min': 88.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 15]]},
   {'empty_min': 3860.0, 'alarm_min': 3830.0})]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(x):
    left = Fraction(x['bag_ml'])
    segs = x['segments']
    for i, (t0, rate) in enumerate(segs):
        t1 = segs[i + 1][0] if i + 1 < len(segs) else None
        if rate == 0:
            continue
        per_min = Fraction(60, rate)
        need = left / per_min
        if t1 is None or t0 + need <= t1:
            empty = t0 + need
            return {'empty_min': round(float(empty), 1), 'alarm_min': round(float(max(Fraction(0), empty - 30)), 1)}
        left -= per_min * (t1 - t0)
    return {'empty_min': None, 'alarm_min': None}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('single rate', {'bag_ml': 500, 'segments': [[0, 125]]}, {'empty_min': 240.0, 'alarm_min': 210.0}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 260]]},
   {'empty_min': 355.4, 'alarm_min': 325.4}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [150, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 110, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 31]]},
   {'empty_min': 272.9, 'alarm_min': 242.9}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 80]]},
   {'empty_min': 15.0, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 30]]},
   {'empty_min': 230.0, 'alarm_min': 200.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 11]]},
   {'empty_min': 5241.8, 'alarm_min': 5211.8})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 150]]}, {'empty_min': 200.0, 'alarm_min': 170.0}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 270]]},
   {'empty_min': 351.1, 'alarm_min': 321.1}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [180, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 120, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 32]]},
   {'empty_min': 266.2, 'alarm_min': 236.2}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 100]]},
   {'empty_min': 12.0, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 60]]},
   {'empty_min': 160.0, 'alarm_min': 130.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 12]]},
   {'empty_min': 4810.0, 'alarm_min': 4780.0})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 175]]}, {'empty_min': 171.4, 'alarm_min': 141.4}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 280]]},
   {'empty_min': 347.1, 'alarm_min': 317.1}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [210, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 130, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 33]]},
   {'empty_min': 260.0, 'alarm_min': 230.0}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 120]]},
   {'empty_min': 10.0, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 90]]},
   {'empty_min': 136.7, 'alarm_min': 106.7}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 13]]},
   {'empty_min': 4444.6, 'alarm_min': 4414.6})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 200]]}, {'empty_min': 150.0, 'alarm_min': 120.0}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 290]]},
   {'empty_min': 343.4, 'alarm_min': 313.4}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [240, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 140, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 34]]},
   {'empty_min': 254.1, 'alarm_min': 224.1}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 140]]},
   {'empty_min': 8.6, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 120]]},
   {'empty_min': 125.0, 'alarm_min': 95.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 14]]},
   {'empty_min': 4131.4, 'alarm_min': 4101.4})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 225]]}, {'empty_min': 133.3, 'alarm_min': 103.3}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 300]]},
   {'empty_min': 340.0, 'alarm_min': 310.0}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [270, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 150, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 35]]},
   {'empty_min': 248.6, 'alarm_min': 218.6}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 160]]},
   {'empty_min': 7.5, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 150]]},
   {'empty_min': 118.0, 'alarm_min': 88.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 15]]},
   {'empty_min': 3860.0, 'alarm_min': 3830.0})]]
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)

prompt:
A 125 mL/h bag is predicted to empty in minutes.

Input {bag_ml, segments [[start_min, rate_ml_h], ...] ascending from 0}. Each segment runs until the next start; the last segment is open-ended. Paused segments (rate 0) consume nothing. Return {empty_min, alarm_min = max(0, empty-30)} rounded to 0.1 min, or both None when the bag never empties.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(x):
    left = Fraction(x['bag_ml'])
    segs = x['segments']
    for i, (t0, rate) in enumerate(segs):
        t1 = segs[i + 1][0] if i + 1 < len(segs) else None
        if rate == 0:
            continue
        per_min = Fraction(rate, 60)
        need = left / per_min
        if t1 is None or t0 + need < t1:
            empty = t0 + need
            return {'empty_min': round(float(empty), 1), 'alarm_min': round(float(max(Fraction(0), empty - 30)), 1)}
        left -= per_min * (t1 - t0)
    return {'empty_min': None, 'alarm_min': None}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('single rate', {'bag_ml': 500, 'segments': [[0, 125]]}, {'empty_min': 240.0, 'alarm_min': 210.0}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 260]]},
   {'empty_min': 355.4, 'alarm_min': 325.4}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [150, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 110, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 31]]},
   {'empty_min': 272.9, 'alarm_min': 242.9}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 80]]},
   {'empty_min': 15.0, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 30]]},
   {'empty_min': 230.0, 'alarm_min': 200.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 11]]},
   {'empty_min': 5241.8, 'alarm_min': 5211.8})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 150]]}, {'empty_min': 200.0, 'alarm_min': 170.0}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 270]]},
   {'empty_min': 351.1, 'alarm_min': 321.1}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [180, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 120, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 32]]},
   {'empty_min': 266.2, 'alarm_min': 236.2}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 100]]},
   {'empty_min': 12.0, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 60]]},
   {'empty_min': 160.0, 'alarm_min': 130.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 12]]},
   {'empty_min': 4810.0, 'alarm_min': 4780.0})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 175]]}, {'empty_min': 171.4, 'alarm_min': 141.4}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 280]]},
   {'empty_min': 347.1, 'alarm_min': 317.1}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [210, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 130, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 33]]},
   {'empty_min': 260.0, 'alarm_min': 230.0}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 120]]},
   {'empty_min': 10.0, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 90]]},
   {'empty_min': 136.7, 'alarm_min': 106.7}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 13]]},
   {'empty_min': 4444.6, 'alarm_min': 4414.6})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 200]]}, {'empty_min': 150.0, 'alarm_min': 120.0}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 290]]},
   {'empty_min': 343.4, 'alarm_min': 313.4}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [240, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 140, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 34]]},
   {'empty_min': 254.1, 'alarm_min': 224.1}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 140]]},
   {'empty_min': 8.6, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 120]]},
   {'empty_min': 125.0, 'alarm_min': 95.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 14]]},
   {'empty_min': 4131.4, 'alarm_min': 4101.4})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 225]]}, {'empty_min': 133.3, 'alarm_min': 103.3}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 300]]},
   {'empty_min': 340.0, 'alarm_min': 310.0}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [270, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 150, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 35]]},
   {'empty_min': 248.6, 'alarm_min': 218.6}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 160]]},
   {'empty_min': 7.5, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 150]]},
   {'empty_min': 118.0, 'alarm_min': 88.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 15]]},
   {'empty_min': 3860.0, 'alarm_min': 3830.0})]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(x):
    left = Fraction(x['bag_ml'])
    segs = x['segments']
    for i, (t0, rate) in enumerate(segs):
        t1 = segs[i + 1][0] if i + 1 < len(segs) else None
        if rate == 0:
            continue
        per_min = Fraction(rate, 60)
        need = left / per_min
        if t1 is None or need <= t1:
            empty = t0 + need
            return {'empty_min': round(float(empty), 1), 'alarm_min': round(float(max(Fraction(0), empty - 30)), 1)}
        left -= per_min * (t1 - t0)
    return {'empty_min': None, 'alarm_min': None}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('single rate', {'bag_ml': 500, 'segments': [[0, 125]]}, {'empty_min': 240.0, 'alarm_min': 210.0}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 260]]},
   {'empty_min': 355.4, 'alarm_min': 325.4}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [150, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 110, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 31]]},
   {'empty_min': 272.9, 'alarm_min': 242.9}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 80]]},
   {'empty_min': 15.0, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 30]]},
   {'empty_min': 230.0, 'alarm_min': 200.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 11]]},
   {'empty_min': 5241.8, 'alarm_min': 5211.8})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 150]]}, {'empty_min': 200.0, 'alarm_min': 170.0}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 270]]},
   {'empty_min': 351.1, 'alarm_min': 321.1}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [180, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 120, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 32]]},
   {'empty_min': 266.2, 'alarm_min': 236.2}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 100]]},
   {'empty_min': 12.0, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 60]]},
   {'empty_min': 160.0, 'alarm_min': 130.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 12]]},
   {'empty_min': 4810.0, 'alarm_min': 4780.0})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 175]]}, {'empty_min': 171.4, 'alarm_min': 141.4}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 280]]},
   {'empty_min': 347.1, 'alarm_min': 317.1}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [210, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 130, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 33]]},
   {'empty_min': 260.0, 'alarm_min': 230.0}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 120]]},
   {'empty_min': 10.0, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 90]]},
   {'empty_min': 136.7, 'alarm_min': 106.7}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 13]]},
   {'empty_min': 4444.6, 'alarm_min': 4414.6})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 200]]}, {'empty_min': 150.0, 'alarm_min': 120.0}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 290]]},
   {'empty_min': 343.4, 'alarm_min': 313.4}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [240, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 140, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 34]]},
   {'empty_min': 254.1, 'alarm_min': 224.1}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 140]]},
   {'empty_min': 8.6, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 120]]},
   {'empty_min': 125.0, 'alarm_min': 95.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 14]]},
   {'empty_min': 4131.4, 'alarm_min': 4101.4})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 225]]}, {'empty_min': 133.3, 'alarm_min': 103.3}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 300]]},
   {'empty_min': 340.0, 'alarm_min': 310.0}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [270, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 150, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 35]]},
   {'empty_min': 248.6, 'alarm_min': 218.6}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 160]]},
   {'empty_min': 7.5, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 150]]},
   {'empty_min': 118.0, 'alarm_min': 88.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 15]]},
   {'empty_min': 3860.0, 'alarm_min': 3830.0})]]
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)

prompt:
A bag that empties exactly when an infusion is paused is reported as never emptying.

Input {bag_ml, segments [[start_min, rate_ml_h], ...] ascending from 0}. Each segment runs until the next start; the last segment is open-ended. Paused segments (rate 0) consume nothing. Return {empty_min, alarm_min = max(0, empty-30)} rounded to 0.1 min, or both None when the bag never empties.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(x):
    left = Fraction(x['bag_ml'])
    segs = x['segments']
    for i, (t0, rate) in enumerate(segs):
        t1 = segs[i + 1][0] if i + 1 < len(segs) else None
        if rate == 0:
            continue
        per_min = Fraction(rate, 60)
        need = left / per_min
        if t1 is None or t0 + need <= t1:
            empty = t0 + need
            return {'empty_min': round(float(empty), 1), 'alarm_min': round(float(max(Fraction(0), empty - 30)), 1)}
        left -= per_min * t1
    return {'empty_min': None, 'alarm_min': None}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('single rate', {'bag_ml': 500, 'segments': [[0, 125]]}, {'empty_min': 240.0, 'alarm_min': 210.0}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 260]]},
   {'empty_min': 355.4, 'alarm_min': 325.4}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [150, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 110, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 31]]},
   {'empty_min': 272.9, 'alarm_min': 242.9}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 80]]},
   {'empty_min': 15.0, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 30]]},
   {'empty_min': 230.0, 'alarm_min': 200.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 11]]},
   {'empty_min': 5241.8, 'alarm_min': 5211.8})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 150]]}, {'empty_min': 200.0, 'alarm_min': 170.0}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 270]]},
   {'empty_min': 351.1, 'alarm_min': 321.1}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [180, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 120, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 32]]},
   {'empty_min': 266.2, 'alarm_min': 236.2}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 100]]},
   {'empty_min': 12.0, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 60]]},
   {'empty_min': 160.0, 'alarm_min': 130.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 12]]},
   {'empty_min': 4810.0, 'alarm_min': 4780.0})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 175]]}, {'empty_min': 171.4, 'alarm_min': 141.4}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 280]]},
   {'empty_min': 347.1, 'alarm_min': 317.1}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [210, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 130, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 33]]},
   {'empty_min': 260.0, 'alarm_min': 230.0}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 120]]},
   {'empty_min': 10.0, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 90]]},
   {'empty_min': 136.7, 'alarm_min': 106.7}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 13]]},
   {'empty_min': 4444.6, 'alarm_min': 4414.6})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 200]]}, {'empty_min': 150.0, 'alarm_min': 120.0}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 290]]},
   {'empty_min': 343.4, 'alarm_min': 313.4}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [240, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 140, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 34]]},
   {'empty_min': 254.1, 'alarm_min': 224.1}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 140]]},
   {'empty_min': 8.6, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 120]]},
   {'empty_min': 125.0, 'alarm_min': 95.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 14]]},
   {'empty_min': 4131.4, 'alarm_min': 4101.4})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 225]]}, {'empty_min': 133.3, 'alarm_min': 103.3}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 300]]},
   {'empty_min': 340.0, 'alarm_min': 310.0}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [270, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 150, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 35]]},
   {'empty_min': 248.6, 'alarm_min': 218.6}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 160]]},
   {'empty_min': 7.5, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 150]]},
   {'empty_min': 118.0, 'alarm_min': 88.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 15]]},
   {'empty_min': 3860.0, 'alarm_min': 3830.0})]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(x):
    left = Fraction(x['bag_ml'])
    segs = x['segments']
    for i, (t0, rate) in enumerate(segs):
        t1 = segs[i + 1][0] if i + 1 < len(segs) else None
        if rate == 0:
            continue
        per_min = Fraction(rate, 60)
        need = left / per_min
        if t1 is None or t0 + need <= t1:
            empty = t0 + need
            return {'empty_min': round(float(empty), 1), 'alarm_min': round(float(max(Fraction(0), empty - 30)), 1)}
        left -= per_min * (t1 - t0 - 1)
    return {'empty_min': None, 'alarm_min': None}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('single rate', {'bag_ml': 500, 'segments': [[0, 125]]}, {'empty_min': 240.0, 'alarm_min': 210.0}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 260]]},
   {'empty_min': 355.4, 'alarm_min': 325.4}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [150, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 110, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 31]]},
   {'empty_min': 272.9, 'alarm_min': 242.9}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 80]]},
   {'empty_min': 15.0, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 30]]},
   {'empty_min': 230.0, 'alarm_min': 200.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 11]]},
   {'empty_min': 5241.8, 'alarm_min': 5211.8})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 150]]}, {'empty_min': 200.0, 'alarm_min': 170.0}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 270]]},
   {'empty_min': 351.1, 'alarm_min': 321.1}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [180, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 120, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 32]]},
   {'empty_min': 266.2, 'alarm_min': 236.2}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 100]]},
   {'empty_min': 12.0, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 60]]},
   {'empty_min': 160.0, 'alarm_min': 130.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 12]]},
   {'empty_min': 4810.0, 'alarm_min': 4780.0})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 175]]}, {'empty_min': 171.4, 'alarm_min': 141.4}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 280]]},
   {'empty_min': 347.1, 'alarm_min': 317.1}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [210, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 130, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 33]]},
   {'empty_min': 260.0, 'alarm_min': 230.0}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 120]]},
   {'empty_min': 10.0, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 90]]},
   {'empty_min': 136.7, 'alarm_min': 106.7}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 13]]},
   {'empty_min': 4444.6, 'alarm_min': 4414.6})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 200]]}, {'empty_min': 150.0, 'alarm_min': 120.0}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 290]]},
   {'empty_min': 343.4, 'alarm_min': 313.4}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [240, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 140, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 34]]},
   {'empty_min': 254.1, 'alarm_min': 224.1}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 140]]},
   {'empty_min': 8.6, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 120]]},
   {'empty_min': 125.0, 'alarm_min': 95.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 14]]},
   {'empty_min': 4131.4, 'alarm_min': 4101.4})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 225]]}, {'empty_min': 133.3, 'alarm_min': 103.3}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 300]]},
   {'empty_min': 340.0, 'alarm_min': 310.0}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [270, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 150, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 35]]},
   {'empty_min': 248.6, 'alarm_min': 218.6}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 160]]},
   {'empty_min': 7.5, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 150]]},
   {'empty_min': 118.0, 'alarm_min': 88.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 15]]},
   {'empty_min': 3860.0, 'alarm_min': 3830.0})]]
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)

prompt:
After a rate change the remaining volume is understated and run-out is predicted too early.

Input {bag_ml, segments [[start_min, rate_ml_h], ...] ascending from 0}. Each segment runs until the next start; the last segment is open-ended. Paused segments (rate 0) consume nothing. Return {empty_min, alarm_min = max(0, empty-30)} rounded to 0.1 min, or both None when the bag never empties.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(x):
    left = Fraction(x['bag_ml'])
    segs = x['segments']
    for i, (t0, rate) in enumerate(segs):
        t1 = segs[i + 1][0] if i + 1 < len(segs) else None
        if rate == 0:
            continue
        per_min = Fraction(rate, 60)
        need = left / per_min
        if t1 is None or t0 + need <= t1:
            empty = t0 + need
            return {'empty_min': round(float(empty), 1), 'alarm_min': round(float(empty - 30), 1)}
        left -= per_min * (t1 - t0)
    return {'empty_min': None, 'alarm_min': None}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('single rate', {'bag_ml': 500, 'segments': [[0, 125]]}, {'empty_min': 240.0, 'alarm_min': 210.0}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 260]]},
   {'empty_min': 355.4, 'alarm_min': 325.4}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [150, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 110, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 31]]},
   {'empty_min': 272.9, 'alarm_min': 242.9}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 80]]},
   {'empty_min': 15.0, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 30]]},
   {'empty_min': 230.0, 'alarm_min': 200.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 11]]},
   {'empty_min': 5241.8, 'alarm_min': 5211.8})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 150]]}, {'empty_min': 200.0, 'alarm_min': 170.0}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 270]]},
   {'empty_min': 351.1, 'alarm_min': 321.1}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [180, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 120, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 32]]},
   {'empty_min': 266.2, 'alarm_min': 236.2}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 100]]},
   {'empty_min': 12.0, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 60]]},
   {'empty_min': 160.0, 'alarm_min': 130.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 12]]},
   {'empty_min': 4810.0, 'alarm_min': 4780.0})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 175]]}, {'empty_min': 171.4, 'alarm_min': 141.4}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 280]]},
   {'empty_min': 347.1, 'alarm_min': 317.1}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [210, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 130, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 33]]},
   {'empty_min': 260.0, 'alarm_min': 230.0}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 120]]},
   {'empty_min': 10.0, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 90]]},
   {'empty_min': 136.7, 'alarm_min': 106.7}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 13]]},
   {'empty_min': 4444.6, 'alarm_min': 4414.6})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 200]]}, {'empty_min': 150.0, 'alarm_min': 120.0}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 290]]},
   {'empty_min': 343.4, 'alarm_min': 313.4}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [240, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 140, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 34]]},
   {'empty_min': 254.1, 'alarm_min': 224.1}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 140]]},
   {'empty_min': 8.6, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 120]]},
   {'empty_min': 125.0, 'alarm_min': 95.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 14]]},
   {'empty_min': 4131.4, 'alarm_min': 4101.4})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 225]]}, {'empty_min': 133.3, 'alarm_min': 103.3}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 300]]},
   {'empty_min': 340.0, 'alarm_min': 310.0}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [270, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 150, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 35]]},
   {'empty_min': 248.6, 'alarm_min': 218.6}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 160]]},
   {'empty_min': 7.5, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 150]]},
   {'empty_min': 118.0, 'alarm_min': 88.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 15]]},
   {'empty_min': 3860.0, 'alarm_min': 3830.0})]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(x):
    left = Fraction(x['bag_ml'])
    segs = x['segments']
    for i, (t0, rate) in enumerate(segs):
        t1 = segs[i + 1][0] if i + 1 < len(segs) else None
        if rate == 0:
            continue
        per_min = Fraction(rate, 60)
        need = left / per_min
        if t1 is None or t0 + need <= t1:
            empty = t0 + need
            return {'empty_min': round(float(empty), 1), 'alarm_min': round(float(max(Fraction(0), empty) - 30), 1)}
        left -= per_min * (t1 - t0)
    return {'empty_min': None, 'alarm_min': None}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('single rate', {'bag_ml': 500, 'segments': [[0, 125]]}, {'empty_min': 240.0, 'alarm_min': 210.0}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 260]]},
   {'empty_min': 355.4, 'alarm_min': 325.4}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [150, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 110, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 31]]},
   {'empty_min': 272.9, 'alarm_min': 242.9}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 80]]},
   {'empty_min': 15.0, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 30]]},
   {'empty_min': 230.0, 'alarm_min': 200.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 11]]},
   {'empty_min': 5241.8, 'alarm_min': 5211.8})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 150]]}, {'empty_min': 200.0, 'alarm_min': 170.0}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 270]]},
   {'empty_min': 351.1, 'alarm_min': 321.1}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [180, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 120, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 32]]},
   {'empty_min': 266.2, 'alarm_min': 236.2}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 100]]},
   {'empty_min': 12.0, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 60]]},
   {'empty_min': 160.0, 'alarm_min': 130.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 12]]},
   {'empty_min': 4810.0, 'alarm_min': 4780.0})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 175]]}, {'empty_min': 171.4, 'alarm_min': 141.4}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 280]]},
   {'empty_min': 347.1, 'alarm_min': 317.1}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [210, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 130, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 33]]},
   {'empty_min': 260.0, 'alarm_min': 230.0}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 120]]},
   {'empty_min': 10.0, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 90]]},
   {'empty_min': 136.7, 'alarm_min': 106.7}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 13]]},
   {'empty_min': 4444.6, 'alarm_min': 4414.6})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 200]]}, {'empty_min': 150.0, 'alarm_min': 120.0}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 290]]},
   {'empty_min': 343.4, 'alarm_min': 313.4}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [240, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 140, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 34]]},
   {'empty_min': 254.1, 'alarm_min': 224.1}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 140]]},
   {'empty_min': 8.6, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 120]]},
   {'empty_min': 125.0, 'alarm_min': 95.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 14]]},
   {'empty_min': 4131.4, 'alarm_min': 4101.4})],
 [('single rate', {'bag_ml': 500, 'segments': [[0, 225]]}, {'empty_min': 133.3, 'alarm_min': 103.3}),
  ('rate change mid bag',
   {'bag_ml': 1000, 'segments': [[0, 125], [240, 300]]},
   {'empty_min': 340.0, 'alarm_min': 310.0}),
  ('empties exactly at pause',
   {'bag_ml': 250, 'segments': [[0, 125], [120, 0], [270, 60]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('empties exactly at end of final paused tail',
   {'bag_ml': 100, 'segments': [[0, 50], [120, 0]]},
   {'empty_min': 120.0, 'alarm_min': 90.0}),
  ('bag outlasts second segment before pause',
   {'bag_ml': 150, 'segments': [[0, 60], [60, 60], [100, 0]]},
   {'empty_min': None, 'alarm_min': None}),
  ('completed middle segment consumption',
   {'bag_ml': 200, 'segments': [[0, 60], [30, 120], [60, 35]]},
   {'empty_min': 248.6, 'alarm_min': 218.6}),
  ('small bag alarm clamps at zero',
   {'bag_ml': 20, 'segments': [[0, 160]]},
   {'empty_min': 7.5, 'alarm_min': 0.0}),
  ('pause then resume',
   {'bag_ml': 100, 'segments': [[0, 60], [30, 0], [90, 150]]},
   {'empty_min': 118.0, 'alarm_min': 88.0}),
  ('very slow multi-day tail',
   {'bag_ml': 1000, 'segments': [[0, 50], [60, 15]]},
   {'empty_min': 3860.0, 'alarm_min': 3830.0})]]
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)

prompt:
A small bag shows an alarm time before the infusion started.

Input {bag_ml, segments [[start_min, rate_ml_h], ...] ascending from 0}. Each segment runs until the next start; the last segment is open-ended. Paused segments (rate 0) consume nothing. Return {empty_min, alarm_min = max(0, empty-30)} rounded to 0.1 min, or both None when the bag never empties.

split: open-access