broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json
from decimal import Decimal, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_FLOOR, ROUND_CEILING, ROUND_DOWN, ROUND_UP, ROUND_HALF_DOWN
N = 1
observations = []
def solve(amount, frm, to):
    rates = {'DEM': '1.95583', 'FRF': '6.55957', 'ITL': '1936.27', 'ESP': '166.386', 'IEP': '0.787564', 'NLG': '2.20371', 'BEF': '40.3399', 'PTE': '200.482', 'ATS': '13.7603', 'FIM': '5.94573', 'EUR': '1'}
    zero = ('ITL', 'ESP', 'BEF', 'PTE')
    if frm not in rates or to not in rates: return 'ERR:currency'
    def q(v, c):
        return v.quantize(Decimal(1) if c in zero else Decimal('0.01'), rounding=ROUND_HALF_UP)
    x = Decimal(amount)
    if frm == to: return format(q(x, to), 'f')
    if frm == 'EUR':
        eur = x
    elif to == 'EUR':
        return format((x / Decimal(rates[frm])).quantize(Decimal('0.001'), rounding=ROUND_HALF_UP), 'f')
    else:
        eur = (x / Decimal(rates[frm])).quantize(Decimal('0.001'), rounding=ROUND_HALF_UP)
    return format(q(eur * Decimal(rates[to]), to), 'f')
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression euro-target-rounding 1', ('0.85', 'DEM', 'EUR'), '0.43'),
  ('regression euro-target-rounding 2', ('2.18', 'DEM', 'EUR'), '1.11'),
  ('control: mark to franc', ('100', 'DEM', 'FRF'), '335.38'),
  ('control: lira to euro', ('1000000', 'ITL', 'EUR'), '516.46'),
  ('control: euro to lira', ('10', 'EUR', 'ITL'), '19363'),
  ('control: same currency rounding', ('100.5', 'ITL', 'ITL'), '101')],
 [('regression euro-target-rounding 1', ('5.54', 'FRF', 'EUR'), '0.84'),
  ('regression euro-target-rounding 2', ('106', 'ITL', 'EUR'), '0.05'),
  ('control: same currency rounding', ('100.5', 'ITL', 'ITL'), '101'),
  ('control: unknown', ('5', 'XEU', 'DEM'), 'ERR:currency'),
  ('control: peseta to punt', ('123456', 'ESP', 'IEP'), '584.36'),
  ('control: guilder to escudo', ('0.01', 'NLG', 'PTE'), '1')],
 [('regression euro-target-rounding 1', ('1.20', 'NLG', 'EUR'), '0.54'),
  ('regression euro-target-rounding 2', ('1000000', 'ITL', 'EUR'), '516.46'),
  ('partial repair guard 2', ('0.85', 'DEM', 'EUR'), '0.43'),
  ('control: guilder to escudo', ('0.01', 'NLG', 'PTE'), '1'),
  ('control: schilling to markka', ('987.65', 'ATS', 'FIM'), '426.75'),
  ('control: franc to franc', ('12.345', 'BEF', 'FRF'), '2.01'),
  ('control: mark to franc', ('100', 'DEM', 'FRF'), '335.38')],
 [('regression euro-target-rounding 1', ('2838484', 'ESP', 'EUR'), '17059.63'),
  ('regression euro-target-rounding 2', ('4062865.64', 'FRF', 'EUR'), '619379.87'),
  ('partial repair guard 1', ('2.18', 'DEM', 'EUR'), '1.11'),
  ('partial repair guard 2', ('5.54', 'FRF', 'EUR'), '0.84'),
  ('control: mark to franc', ('100', 'DEM', 'FRF'), '335.38'),
  ('control: lira to euro', ('1000000', 'ITL', 'EUR'), '516.46'),
  ('control: euro to lira', ('10', 'EUR', 'ITL'), '19363'),
  ('control: same currency rounding', ('100.5', 'ITL', 'ITL'), '101')],
 [('regression euro-target-rounding 1', ('4466382', 'FRF', 'EUR'), '680895.55'),
  ('regression euro-target-rounding 2', ('3694885', 'IEP', 'EUR'), '4691536.18'),
  ('partial repair guard 1', ('106', 'ITL', 'EUR'), '0.05'), ('partial repair guard 2', ('1.20', 'NLG', 'EUR'), '0.54'),
  ('control: same currency rounding', ('100.5', 'ITL', 'ITL'), '101'),
  ('control: unknown', ('5', 'XEU', 'DEM'), 'ERR:currency'),
  ('control: peseta to punt', ('123456', 'ESP', 'IEP'), '584.36'),
  ('control: guilder to escudo', ('0.01', 'NLG', 'PTE'), '1')]]
for label, args, expected in cases[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
from decimal import Decimal, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_FLOOR, ROUND_CEILING, ROUND_DOWN, ROUND_UP, ROUND_HALF_DOWN
N = 1
observations = []
def solve(amount, frm, to):
    rates = {'DEM': '1.95583', 'FRF': '6.55957', 'ITL': '1936.27', 'ESP': '166.386', 'IEP': '0.787564', 'NLG': '2.20371', 'BEF': '40.3399', 'PTE': '200.482', 'ATS': '13.7603', 'FIM': '5.94573', 'EUR': '1'}
    zero = ('ITL', 'ESP', 'BEF', 'PTE')
    if frm not in rates or to not in rates: return 'ERR:currency'
    def q(v, c):
        return v.quantize(Decimal(1) if c in zero else Decimal('0.01'), rounding=ROUND_HALF_UP)
    x = Decimal(amount)
    if frm == to: return format(q(x, to), 'f')
    if frm == 'EUR':
        eur = x
    elif to == 'EUR':
        return format(q((x / Decimal(rates[frm])).quantize(Decimal('0.001'), rounding=ROUND_HALF_UP), 'EUR'), 'f')
    else:
        eur = (x / Decimal(rates[frm])).quantize(Decimal('0.001'), rounding=ROUND_HALF_UP)
    return format(q(eur * Decimal(rates[to]), to), 'f')
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression euro-target-rounding 1', ('0.85', 'DEM', 'EUR'), '0.43'),
  ('regression euro-target-rounding 2', ('2.18', 'DEM', 'EUR'), '1.11'),
  ('control: mark to franc', ('100', 'DEM', 'FRF'), '335.38'),
  ('control: lira to euro', ('1000000', 'ITL', 'EUR'), '516.46'),
  ('control: euro to lira', ('10', 'EUR', 'ITL'), '19363'),
  ('control: same currency rounding', ('100.5', 'ITL', 'ITL'), '101')],
 [('regression euro-target-rounding 1', ('5.54', 'FRF', 'EUR'), '0.84'),
  ('regression euro-target-rounding 2', ('106', 'ITL', 'EUR'), '0.05'),
  ('control: same currency rounding', ('100.5', 'ITL', 'ITL'), '101'),
  ('control: unknown', ('5', 'XEU', 'DEM'), 'ERR:currency'),
  ('control: peseta to punt', ('123456', 'ESP', 'IEP'), '584.36'),
  ('control: guilder to escudo', ('0.01', 'NLG', 'PTE'), '1')],
 [('regression euro-target-rounding 1', ('1.20', 'NLG', 'EUR'), '0.54'),
  ('regression euro-target-rounding 2', ('1000000', 'ITL', 'EUR'), '516.46'),
  ('partial repair guard 2', ('0.85', 'DEM', 'EUR'), '0.43'),
  ('control: guilder to escudo', ('0.01', 'NLG', 'PTE'), '1'),
  ('control: schilling to markka', ('987.65', 'ATS', 'FIM'), '426.75'),
  ('control: franc to franc', ('12.345', 'BEF', 'FRF'), '2.01'),
  ('control: mark to franc', ('100', 'DEM', 'FRF'), '335.38')],
 [('regression euro-target-rounding 1', ('2838484', 'ESP', 'EUR'), '17059.63'),
  ('regression euro-target-rounding 2', ('4062865.64', 'FRF', 'EUR'), '619379.87'),
  ('partial repair guard 1', ('2.18', 'DEM', 'EUR'), '1.11'),
  ('partial repair guard 2', ('5.54', 'FRF', 'EUR'), '0.84'),
  ('control: mark to franc', ('100', 'DEM', 'FRF'), '335.38'),
  ('control: lira to euro', ('1000000', 'ITL', 'EUR'), '516.46'),
  ('control: euro to lira', ('10', 'EUR', 'ITL'), '19363'),
  ('control: same currency rounding', ('100.5', 'ITL', 'ITL'), '101')],
 [('regression euro-target-rounding 1', ('4466382', 'FRF', 'EUR'), '680895.55'),
  ('regression euro-target-rounding 2', ('3694885', 'IEP', 'EUR'), '4691536.18'),
  ('partial repair guard 1', ('106', 'ITL', 'EUR'), '0.05'), ('partial repair guard 2', ('1.20', 'NLG', 'EUR'), '0.54'),
  ('control: same currency rounding', ('100.5', 'ITL', 'ITL'), '101'),
  ('control: unknown', ('5', 'XEU', 'DEM'), 'ERR:currency'),
  ('control: peseta to punt', ('123456', 'ESP', 'IEP'), '584.36'),
  ('control: guilder to escudo', ('0.01', 'NLG', 'PTE'), '1')]]
for label, args, expected in cases[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:
Marks converted to euros are reported with three decimals.

solve(amount, frm, to): stipulated legacy-currency triangulation. Fixed rates are units per 1 EUR (DEM 1.95583, FRF 6.55957, ITL 1936.27, ESP 166.386, IEP 0.787564, NLG 2.20371, BEF 40.3399, PTE 200.482, ATS 13.7603, FIM 5.94573). Exponents: ITL, ESP, BEF, PTE 0; others and EUR 2. Legacy to legacy: divide by the source rate, round the EUR intermediate half-up to 3 decimals, multiply by the target rate, round half-up to the target exponent. Legacy to EUR: divide and round half-up to 2 decimals. EUR to legacy: multiply and round half-up to the target exponent. Same currency: round the amount half-up to its exponent. Inverse rates are never used. Unknown codes return 'ERR:currency'.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json
from decimal import Decimal, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_FLOOR, ROUND_CEILING, ROUND_DOWN, ROUND_UP, ROUND_HALF_DOWN
N = 1
observations = []
def solve(amount, frm, to):
    rates = {'DEM': '1.95583', 'FRF': '6.55957', 'ITL': '1936.27', 'ESP': '166.386', 'IEP': '0.787564', 'NLG': '2.20371', 'BEF': '40.3399', 'PTE': '200.482', 'ATS': '13.7603', 'FIM': '5.94573', 'EUR': '1'}
    zero = ('ITL', 'ESP', 'BEF', 'PTE')
    if frm not in rates or to not in rates: return 'ERR:currency'
    def q(v, c):
        return v.quantize(Decimal(1) if c in zero else Decimal('0.01'), rounding=ROUND_HALF_UP)
    x = Decimal(amount)
    pass
    if frm == 'EUR':
        eur = x
    elif to == 'EUR':
        return format(q(x / Decimal(rates[frm]), 'EUR'), 'f')
    else:
        eur = (x / Decimal(rates[frm])).quantize(Decimal('0.001'), rounding=ROUND_HALF_UP)
    return format(q(eur * Decimal(rates[to]), to), 'f')
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression same-currency 1', ('12345', 'ITL', 'ITL'), '12345'),
  ('regression same-currency 2', ('409108', 'ITL', 'ITL'), '409108'),
  ('partial repair guard 1', ('100.5', 'ITL', 'ITL'), '101'),
  ('partial repair guard 2', ('1.005', 'DEM', 'DEM'), '1.01'),
  ('control: mark to franc', ('100', 'DEM', 'FRF'), '335.38'),
  ('control: lira to euro', ('1000000', 'ITL', 'EUR'), '516.46'),
  ('control: euro to lira', ('10', 'EUR', 'ITL'), '19363'), ('control: unknown', ('5', 'XEU', 'DEM'), 'ERR:currency')],
 [('regression same-currency 1', ('12345', 'ITL', 'ITL'), '12345'),
  ('regression same-currency 2', ('409108', 'ITL', 'ITL'), '409108'),
  ('partial repair guard 1', ('278015', 'FIM', 'FIM'), '278015.00'),
  ('partial repair guard 2', ('162491', 'FRF', 'FRF'), '162491.00'),
  ('control: same currency rounding', ('100.5', 'ITL', 'ITL'), '101'),
  ('control: unknown', ('5', 'XEU', 'DEM'), 'ERR:currency'),
  ('control: peseta to punt', ('123456', 'ESP', 'IEP'), '584.36'),
  ('control: guilder to escudo', ('0.01', 'NLG', 'PTE'), '1')],
 [('regression same-currency 1', ('12345', 'ITL', 'ITL'), '12345'),
  ('regression same-currency 2', ('409108', 'ITL', 'ITL'), '409108'),
  ('partial repair guard 1', ('3161904', 'FRF', 'FRF'), '3161904.00'),
  ('partial repair guard 2', ('604787', 'EUR', 'EUR'), '604787.00'),
  ('control: guilder to escudo', ('0.01', 'NLG', 'PTE'), '1'),
  ('control: schilling to markka', ('987.65', 'ATS', 'FIM'), '426.75'),
  ('control: franc to franc', ('12.345', 'BEF', 'FRF'), '2.01'),
  ('control: mark to franc', ('100', 'DEM', 'FRF'), '335.38')],
 [('regression same-currency 1', ('12345', 'ITL', 'ITL'), '12345'),
  ('regression same-currency 2', ('409108', 'ITL', 'ITL'), '409108'),
  ('partial repair guard 1', ('2390508', 'EUR', 'EUR'), '2390508.00'),
  ('partial repair guard 2', ('4901642', 'IEP', 'IEP'), '4901642.00'),
  ('control: mark to franc', ('100', 'DEM', 'FRF'), '335.38'),
  ('control: lira to euro', ('1000000', 'ITL', 'EUR'), '516.46'),
  ('control: euro to lira', ('10', 'EUR', 'ITL'), '19363'),
  ('control: same currency rounding', ('100.5', 'ITL', 'ITL'), '101')],
 [('regression same-currency 1', ('12345', 'ITL', 'ITL'), '12345'),
  ('regression same-currency 2', ('409108', 'ITL', 'ITL'), '409108'),
  ('partial repair guard 1', ('3675688', 'EUR', 'EUR'), '3675688.00'),
  ('partial repair guard 2', ('4983100', 'DEM', 'DEM'), '4983100.00'),
  ('control: same currency rounding', ('100.5', 'ITL', 'ITL'), '101'),
  ('control: unknown', ('5', 'XEU', 'DEM'), 'ERR:currency'),
  ('control: peseta to punt', ('123456', 'ESP', 'IEP'), '584.36'),
  ('control: guilder to escudo', ('0.01', 'NLG', 'PTE'), '1')]]
for label, args, expected in cases[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
from decimal import Decimal, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_FLOOR, ROUND_CEILING, ROUND_DOWN, ROUND_UP, ROUND_HALF_DOWN
N = 1
observations = []
def solve(amount, frm, to):
    rates = {'DEM': '1.95583', 'FRF': '6.55957', 'ITL': '1936.27', 'ESP': '166.386', 'IEP': '0.787564', 'NLG': '2.20371', 'BEF': '40.3399', 'PTE': '200.482', 'ATS': '13.7603', 'FIM': '5.94573', 'EUR': '1'}
    zero = ('ITL', 'ESP', 'BEF', 'PTE')
    if frm not in rates or to not in rates: return 'ERR:currency'
    def q(v, c):
        return v.quantize(Decimal(1) if c in zero else Decimal('0.01'), rounding=ROUND_HALF_UP)
    x = Decimal(amount)
    if frm == to: return amount
    if frm == 'EUR':
        eur = x
    elif to == 'EUR':
        return format(q(x / Decimal(rates[frm]), 'EUR'), 'f')
    else:
        eur = (x / Decimal(rates[frm])).quantize(Decimal('0.001'), rounding=ROUND_HALF_UP)
    return format(q(eur * Decimal(rates[to]), to), 'f')
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression same-currency 1', ('12345', 'ITL', 'ITL'), '12345'),
  ('regression same-currency 2', ('409108', 'ITL', 'ITL'), '409108'),
  ('partial repair guard 1', ('100.5', 'ITL', 'ITL'), '101'),
  ('partial repair guard 2', ('1.005', 'DEM', 'DEM'), '1.01'),
  ('control: mark to franc', ('100', 'DEM', 'FRF'), '335.38'),
  ('control: lira to euro', ('1000000', 'ITL', 'EUR'), '516.46'),
  ('control: euro to lira', ('10', 'EUR', 'ITL'), '19363'), ('control: unknown', ('5', 'XEU', 'DEM'), 'ERR:currency')],
 [('regression same-currency 1', ('12345', 'ITL', 'ITL'), '12345'),
  ('regression same-currency 2', ('409108', 'ITL', 'ITL'), '409108'),
  ('partial repair guard 1', ('278015', 'FIM', 'FIM'), '278015.00'),
  ('partial repair guard 2', ('162491', 'FRF', 'FRF'), '162491.00'),
  ('control: same currency rounding', ('100.5', 'ITL', 'ITL'), '101'),
  ('control: unknown', ('5', 'XEU', 'DEM'), 'ERR:currency'),
  ('control: peseta to punt', ('123456', 'ESP', 'IEP'), '584.36'),
  ('control: guilder to escudo', ('0.01', 'NLG', 'PTE'), '1')],
 [('regression same-currency 1', ('12345', 'ITL', 'ITL'), '12345'),
  ('regression same-currency 2', ('409108', 'ITL', 'ITL'), '409108'),
  ('partial repair guard 1', ('3161904', 'FRF', 'FRF'), '3161904.00'),
  ('partial repair guard 2', ('604787', 'EUR', 'EUR'), '604787.00'),
  ('control: guilder to escudo', ('0.01', 'NLG', 'PTE'), '1'),
  ('control: schilling to markka', ('987.65', 'ATS', 'FIM'), '426.75'),
  ('control: franc to franc', ('12.345', 'BEF', 'FRF'), '2.01'),
  ('control: mark to franc', ('100', 'DEM', 'FRF'), '335.38')],
 [('regression same-currency 1', ('12345', 'ITL', 'ITL'), '12345'),
  ('regression same-currency 2', ('409108', 'ITL', 'ITL'), '409108'),
  ('partial repair guard 1', ('2390508', 'EUR', 'EUR'), '2390508.00'),
  ('partial repair guard 2', ('4901642', 'IEP', 'IEP'), '4901642.00'),
  ('control: mark to franc', ('100', 'DEM', 'FRF'), '335.38'),
  ('control: lira to euro', ('1000000', 'ITL', 'EUR'), '516.46'),
  ('control: euro to lira', ('10', 'EUR', 'ITL'), '19363'),
  ('control: same currency rounding', ('100.5', 'ITL', 'ITL'), '101')],
 [('regression same-currency 1', ('12345', 'ITL', 'ITL'), '12345'),
  ('regression same-currency 2', ('409108', 'ITL', 'ITL'), '409108'),
  ('partial repair guard 1', ('3675688', 'EUR', 'EUR'), '3675688.00'),
  ('partial repair guard 2', ('4983100', 'DEM', 'DEM'), '4983100.00'),
  ('control: same currency rounding', ('100.5', 'ITL', 'ITL'), '101'),
  ('control: unknown', ('5', 'XEU', 'DEM'), 'ERR:currency'),
  ('control: peseta to punt', ('123456', 'ESP', 'IEP'), '584.36'),
  ('control: guilder to escudo', ('0.01', 'NLG', 'PTE'), '1')]]
for label, args, expected in cases[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:
Converting 12345 lira to lira returns 12346 lira.

solve(amount, frm, to): stipulated legacy-currency triangulation. Fixed rates are units per 1 EUR (DEM 1.95583, FRF 6.55957, ITL 1936.27, ESP 166.386, IEP 0.787564, NLG 2.20371, BEF 40.3399, PTE 200.482, ATS 13.7603, FIM 5.94573). Exponents: ITL, ESP, BEF, PTE 0; others and EUR 2. Legacy to legacy: divide by the source rate, round the EUR intermediate half-up to 3 decimals, multiply by the target rate, round half-up to the target exponent. Legacy to EUR: divide and round half-up to 2 decimals. EUR to legacy: multiply and round half-up to the target exponent. Same currency: round the amount half-up to its exponent. Inverse rates are never used. Unknown codes return 'ERR:currency'.

split: open-access


prompt:
Invoice totals in the target currency drift from round(sum*rate) and no plug is ever posted.

solve(lines, rate, exp): lines are source-currency decimal strings (credits negative), rate a decimal string, exp the target exponent. The converted total is round_half_even(sum(lines)*rate) at exp. Each line is converted and rounded half-even individually; the difference between the converted total and the sum of converted lines is posted in full to the line with the largest absolute source amount (earliest on ties). Return the converted lines as plain strings; zero lines are unsigned. An empty invoice returns [].

split: open-access


prompt:
When the largest line is a credit, the difference is booked to a small debit line instead.

solve(lines, rate, exp): lines are source-currency decimal strings (credits negative), rate a decimal string, exp the target exponent. The converted total is round_half_even(sum(lines)*rate) at exp. Each line is converted and rounded half-even individually; the difference between the converted total and the sum of converted lines is posted in full to the line with the largest absolute source amount (earliest on ties). Return the converted lines as plain strings; zero lines are unsigned. An empty invoice returns [].

split: open-access


prompt:
Converted lines sum to a value two differences away from the control total.

solve(lines, rate, exp): lines are source-currency decimal strings (credits negative), rate a decimal string, exp the target exponent. The converted total is round_half_even(sum(lines)*rate) at exp. Each line is converted and rounded half-even individually; the difference between the converted total and the sum of converted lines is posted in full to the line with the largest absolute source amount (earliest on ties). Return the converted lines as plain strings; zero lines are unsigned. An empty invoice returns [].

split: open-access


prompt:
A one-cent credit converted at 0.3 shows as '-0.00' on the invoice.

solve(lines, rate, exp): lines are source-currency decimal strings (credits negative), rate a decimal string, exp the target exponent. The converted total is round_half_even(sum(lines)*rate) at exp. Each line is converted and rounded half-even individually; the difference between the converted total and the sum of converted lines is posted in full to the line with the largest absolute source amount (earliest on ties). Return the converted lines as plain strings; zero lines are unsigned. An empty invoice returns [].

split: open-access


prompt:
A trade at t=7 ignores the tick published at t=7 and reports a stale or older rate.

solve(ticks, trade_ts, max_age): ticks is the published rate feed [[ts, rate], ...] in publication order. Use the tick with the greatest ts <= trade_ts; among ticks with equal ts the later-published one is a correction and wins. No eligible tick returns 'ERR:no-rate'. If max_age is not None and trade_ts - ts > max_age the rate is 'ERR:stale' (max_age 0 accepts only a same-instant tick). Return [ts, rate].

split: open-access


prompt:
The originally published rate is used although a correction for the same instant followed it.

solve(ticks, trade_ts, max_age): ticks is the published rate feed [[ts, rate], ...] in publication order. Use the tick with the greatest ts <= trade_ts; among ticks with equal ts the later-published one is a correction and wins. No eligible tick returns 'ERR:no-rate'. If max_age is not None and trade_ts - ts > max_age the rate is 'ERR:stale' (max_age 0 accepts only a same-instant tick). Return [ts, rate].

split: open-access


source:
"""Failure Map reference implementation. Python standard library only."""
import json
from decimal import Decimal, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_FLOOR, ROUND_CEILING, ROUND_DOWN, ROUND_UP, ROUND_HALF_DOWN
N = 1
observations = []
def solve(ticks, trade_ts, max_age):
    best = None
    for ts, r in ticks:
        if ts <= trade_ts and (best is None or ts >= best[0]):
            best = [ts, r]
    if best is None: return 'ERR:no-rate'
    if max_age is not None and trade_ts - max(t for t, _ in ticks) > max_age: return 'ERR:stale'
    return best
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression staleness-boundary 1', ([[4, '1.11'], [12, '1.50']], 8, 4), [4, '1.11']),
  ('regression staleness-boundary 2', ([[7, '1.40']], 7, 0), [7, '1.40']),
  ('partial repair guard 1', ([[1, '1.10'], [9, '1.30']], 7, 3), 'ERR:stale'),
  ('partial repair guard 2', ([[1, '1.0708'], [20, '1.0061'], [14, '1.0619'], [11, '1.2351']], 18, 2), 'ERR:stale'),
  ('control: correction wins', ([[1, '1.10'], [5, '1.20'], [5, '1.21'], [9, '1.30']], 7, 3), [5, '1.21']),
  ('control: only future', ([[9, '1.30']], 7, None), 'ERR:no-rate'),
  ('control: unlimited age', ([[0, '1.05']], 20, None), [0, '1.05']),
  ('control: empty feed', ([], 3, 5), 'ERR:no-rate')],
 [('regression staleness-boundary 1',
   ([[16, '1.0577'], [3, '1.1605'], [9, '1.0153'], [16, '1.0347'], [5, '1.1882']], 4, 1), [3, '1.1605']),
  ('regression staleness-boundary 2', ([[10, '1.1254'], [1, '1.0516'], [3, '1.1640']], 2, 1), [1, '1.0516']),
  ('partial repair guard 1',
   ([[14, '1.1444'], [0, '1.1478'], [5, '1.1087'], [5, '1.1978'], [11, '1.2115'], [1, '1.2119']], 7, 0), 'ERR:stale'),
  ('partial repair guard 2', ([[1, '1.1610'], [10, '1.2604']], 3, 1), 'ERR:stale'),
  ('control: same instant zero age', ([[7, '1.40']], 7, 0), [7, '1.40']),
  ('control: unlimited age', ([[0, '1.05']], 20, None), [0, '1.05']),
  ('control: age boundary', ([[4, '1.11'], [12, '1.50']], 8, 4), [4, '1.11']),
  ('control: empty feed', ([], 3, 5), 'ERR:no-rate')],
 [('regression staleness-boundary 1', ([[1, '1.2376'], [19, '1.2134'], [14, '1.2465']], 1, 0), [1, '1.2376']),
  ('regression staleness-boundary 2', ([[3, '1.2016'], [20, '1.0619'], [10, '1.1904'], [10, '1.1149']], 6, 3),
   [3, '1.2016']),
  ('partial repair guard 1', ([[17, '1.2848'], [2, '1.1228']], 14, 2), 'ERR:stale'),
  ('partial repair guard 2', ([[10, '1.2328'], [1, '1.0928'], [3, '1.1922'], [19, '1.2521'], [19, '1.2864']], 2, 0),
   'ERR:stale'),
  ('control: empty feed', ([], 3, 5), 'ERR:no-rate'),
  ('control: out of order feed', ([[6, '1.26'], [2, '1.22'], [6, '1.19']], 6, 1), [6, '1.19']),
  ('control: correction wins', ([[1, '1.10'], [5, '1.20'], [5, '1.21'], [9, '1.30']], 7, 3), [5, '1.21']),
  ('control: stale', ([[1, '1.10'], [9, '1.30']], 7, 3), 'ERR:stale')],
 [('regression staleness-boundary 1', ([[4, '1.2845'], [1, '1.0456'], [3, '1.1500'], [14, '1.1676']], 17, 3),
   [14, '1.1676']),
  ('regression staleness-boundary 2', ([[14, '1.2739'], [20, '1.2257'], [0, '1.2886']], 16, 2), [14, '1.2739']),
  ('partial repair guard 1', ([[6, '1.0581'], [9, '1.2011'], [16, '1.2956']], 12, 1), 'ERR:stale'),
  ('partial repair guard 2', ([[17, '1.1794'], [15, '1.0788'], [2, '1.2545']], 12, 0), 'ERR:stale'),
  ('control: stale', ([[1, '1.10'], [9, '1.30']], 7, 3), 'ERR:stale'),
  ('control: only future', ([[9, '1.30']], 7, None), 'ERR:no-rate'),
  ('control: same instant zero age', ([[7, '1.40']], 7, 0), [7, '1.40']),
  ('control: unlimited age', ([[0, '1.05']], 20, None), [0, '1.05'])],
 [('regression staleness-boundary 1',
   ([[5, '1.0271'], [11, '1.2757'], [10, '1.0041'], [14, '1.1151'], [2, '1.2167']], 14, 0), [14, '1.1151']),
  ('regression staleness-boundary 2',
   ([[13, '1.1719'], [0, '1.0347'], [20, '1.2239'], [9, '1.1422'], [3, '1.0957']], 1, 1), [0, '1.0347']),
  ('partial repair guard 1',
   ([[1, '1.0230'], [14, '1.0591'], [3, '1.2010'], [13, '1.0135'], [3, '1.1001'], [13, '1.1421']], 12, 3),
   'ERR:stale'),
  ('partial repair guard 2',
   ([[5, '1.0556'], [2, '1.2743'], [17, '1.2317'], [7, '1.0015'], [4, '1.2457'], [7, '1.1125']], 16, 5), 'ERR:stale'),
  ('control: unlimited age', ([[0, '1.05']], 20, None), [0, '1.05']),
  ('control: age boundary', ([[4, '1.11'], [12, '1.50']], 8, 4), [4, '1.11']),
  ('control: empty feed', ([], 3, 5), 'ERR:no-rate'),
  ('control: out of order feed', ([[6, '1.26'], [2, '1.22'], [6, '1.19']], 6, 1), [6, '1.19'])]]
for label, args, expected in cases[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 tick exactly max_age old is rejected.

solve(ticks, trade_ts, max_age): ticks is the published rate feed [[ts, rate], ...] in publication order. Use the tick with the greatest ts <= trade_ts; among ticks with equal ts the later-published one is a correction and wins. No eligible tick returns 'ERR:no-rate'. If max_age is not None and trade_ts - ts > max_age the rate is 'ERR:stale' (max_age 0 accepts only a same-instant tick). Return [ts, rate].

split: open-access


prompt:
With max_age 0, an hour-old rate is accepted.

solve(ticks, trade_ts, max_age): ticks is the published rate feed [[ts, rate], ...] in publication order. Use the tick with the greatest ts <= trade_ts; among ticks with equal ts the later-published one is a correction and wins. No eligible tick returns 'ERR:no-rate'. If max_age is not None and trade_ts - ts > max_age the rate is 'ERR:stale' (max_age 0 accepts only a same-instant tick). Return [ts, rate].

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json
from decimal import Decimal, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_FLOOR, ROUND_CEILING, ROUND_DOWN, ROUND_UP, ROUND_HALF_DOWN
N = 1
observations = []
def solve(amount_minor, from_exp, to_exp, rate):
    scale = Decimal(1)
    v = Decimal(amount_minor) * Decimal(rate) * scale
    return int(v.quantize(Decimal(1), rounding=ROUND_HALF_EVEN))
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression exponent-rescale 1', (1000, 2, 0, '151.37'), 1514),
  ('regression exponent-rescale 2', (1, 0, 3, '0.3071'), 307), ('control: float trap tie', (115, 2, 2, '1.1'), 126),
  ('control: negative exact', (-250, 2, 2, '0.5'), -125), ('control: negative tie', (-3, 2, 2, '0.5'), -2),
  ('control: zero', (0, 2, 0, '151.37'), 0)],
 [('regression exponent-rescale 1', (987654321, 2, 3, '0.30712'), 3033283951),
  ('regression exponent-rescale 2', (64824, 0, 2, '51.9345'), 336660203),
  ('control: yen to dinar', (1, 0, 3, '0.3071'), 307), ('control: negative tie', (-3, 2, 2, '0.5'), -2),
  ('control: zero', (0, 2, 0, '151.37'), 0), ('control: precise rate', (123456, 2, 2, '1.08347'), 133761)],
 [('regression exponent-rescale 1', (806786, 2, 3, '113828.2'), 918349981652),
  ('regression exponent-rescale 2', (755323, 2, 4, '7.24667'), 547357652),
  ('control: precise rate', (123456, 2, 2, '1.08347'), 133761),
  ('control: large', (987654321, 2, 3, '0.30712'), 3033283951), ('control: cents to yen', (1000, 2, 0, '151.37'), 1514),
  ('control: float trap tie', (115, 2, 2, '1.1'), 126)],
 [('regression exponent-rescale 1', (943097, 3, 2, '109.9318'), 10367635),
  ('regression exponent-rescale 2', (286850, 2, 3, '1.495849'), 4290843),
  ('control: float trap tie', (115, 2, 2, '1.1'), 126), ('control: negative exact', (-250, 2, 2, '0.5'), -125),
  ('control: yen to dinar', (1, 0, 3, '0.3071'), 307), ('control: negative tie', (-3, 2, 2, '0.5'), -2)],
 [('regression exponent-rescale 1', (253357, 0, 4, '18.88901'), 47856629066),
  ('regression exponent-rescale 2', (190708, 0, 4, '188.1068'), 358734716144),
  ('control: negative tie', (-3, 2, 2, '0.5'), -2), ('control: zero', (0, 2, 0, '151.37'), 0),
  ('control: precise rate', (123456, 2, 2, '1.08347'), 133761),
  ('control: large', (987654321, 2, 3, '0.30712'), 3033283951)]]
for label, args, expected in cases[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
from decimal import Decimal, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_FLOOR, ROUND_CEILING, ROUND_DOWN, ROUND_UP, ROUND_HALF_DOWN
N = 1
observations = []
def solve(amount_minor, from_exp, to_exp, rate):
    scale = Decimal(10) ** (from_exp - to_exp)
    v = Decimal(amount_minor) * Decimal(rate) * scale
    return int(v.quantize(Decimal(1), rounding=ROUND_HALF_EVEN))
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression exponent-rescale 1', (1000, 2, 0, '151.37'), 1514),
  ('regression exponent-rescale 2', (1, 0, 3, '0.3071'), 307), ('control: float trap tie', (115, 2, 2, '1.1'), 126),
  ('control: negative exact', (-250, 2, 2, '0.5'), -125), ('control: negative tie', (-3, 2, 2, '0.5'), -2),
  ('control: zero', (0, 2, 0, '151.37'), 0)],
 [('regression exponent-rescale 1', (987654321, 2, 3, '0.30712'), 3033283951),
  ('regression exponent-rescale 2', (64824, 0, 2, '51.9345'), 336660203),
  ('control: yen to dinar', (1, 0, 3, '0.3071'), 307), ('control: negative tie', (-3, 2, 2, '0.5'), -2),
  ('control: zero', (0, 2, 0, '151.37'), 0), ('control: precise rate', (123456, 2, 2, '1.08347'), 133761)],
 [('regression exponent-rescale 1', (806786, 2, 3, '113828.2'), 918349981652),
  ('regression exponent-rescale 2', (755323, 2, 4, '7.24667'), 547357652),
  ('control: precise rate', (123456, 2, 2, '1.08347'), 133761),
  ('control: large', (987654321, 2, 3, '0.30712'), 3033283951), ('control: cents to yen', (1000, 2, 0, '151.37'), 1514),
  ('control: float trap tie', (115, 2, 2, '1.1'), 126)],
 [('regression exponent-rescale 1', (943097, 3, 2, '109.9318'), 10367635),
  ('regression exponent-rescale 2', (286850, 2, 3, '1.495849'), 4290843),
  ('control: float trap tie', (115, 2, 2, '1.1'), 126), ('control: negative exact', (-250, 2, 2, '0.5'), -125),
  ('control: yen to dinar', (1, 0, 3, '0.3071'), 307), ('control: negative tie', (-3, 2, 2, '0.5'), -2)],
 [('regression exponent-rescale 1', (253357, 0, 4, '18.88901'), 47856629066),
  ('regression exponent-rescale 2', (190708, 0, 4, '188.1068'), 358734716144),
  ('control: negative tie', (-3, 2, 2, '0.5'), -2), ('control: zero', (0, 2, 0, '151.37'), 0),
  ('control: precise rate', (123456, 2, 2, '1.08347'), 133761),
  ('control: large', (987654321, 2, 3, '0.30712'), 3033283951)]]
for label, args, expected in cases[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:
1000 US cents convert to 151370 yen instead of 1514 yen.

solve(amount_minor, from_exp, to_exp, rate): amount_minor is an integer count of source minor units, rate a decimal string giving target major units per source major unit. The target minor amount is amount_minor * rate * 10**(to_exp - from_exp), computed exactly and rounded half-even to an integer.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json
from decimal import Decimal, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_FLOOR, ROUND_CEILING, ROUND_DOWN, ROUND_UP, ROUND_HALF_DOWN
N = 1
observations = []
def solve(amount_minor, from_exp, to_exp, rate):
    scale = Decimal(10) ** (to_exp - from_exp)
    v = Decimal(amount_minor) * Decimal(rate) * scale
    return int(v)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression integer-rounding 1', (1000, 2, 0, '151.37'), 1514),
  ('regression integer-rounding 2', (-3, 2, 2, '0.5'), -2), ('partial repair guard 2', (-7, 2, 2, '0.3'), -2),
  ('control: float trap tie', (115, 2, 2, '1.1'), 126), ('control: negative exact', (-250, 2, 2, '0.5'), -125),
  ('control: yen to dinar', (1, 0, 3, '0.3071'), 307), ('control: zero', (0, 2, 0, '151.37'), 0)],
 [('regression integer-rounding 1', (123456, 2, 2, '1.08347'), 133761),
  ('regression integer-rounding 2', (987654321, 2, 3, '0.30712'), 3033283951),
  ('partial repair guard 1', (115, 2, 2, '1.1'), 126), ('partial repair guard 2', (-250, 2, 2, '0.5'), -125),
  ('control: yen to dinar', (1, 0, 3, '0.3071'), 307), ('control: negative tie', (-3, 2, 2, '0.5'), -2),
  ('control: zero', (0, 2, 0, '151.37'), 0), ('control: cents to yen', (1000, 2, 0, '151.37'), 1514)],
 [('regression integer-rounding 1', (589334, 0, 0, '168.0593'), 99043060),
  ('regression integer-rounding 2', (64824, 0, 2, '51.9345'), 336660203),
  ('partial repair guard 1', (-66003, 3, 4, '7.30025'), -4818384),
  ('partial repair guard 2', (-35317, 0, 3, '196135.8'), -6926928048600),
  ('control: precise rate', (123456, 2, 2, '1.08347'), 133761),
  ('control: large', (987654321, 2, 3, '0.30712'), 3033283951), ('control: cents to yen', (1000, 2, 0, '151.37'), 1514),
  ('control: float trap tie', (115, 2, 2, '1.1'), 126)],
 [('regression integer-rounding 1', (410259, 2, 2, '0.258909'), 106220),
  ('regression integer-rounding 2', (286850, 2, 3, '1.495849'), 4290843),
  ('partial repair guard 1', (-46763, 3, 2, '4592.5'), -21475908),
  ('partial repair guard 2', (-35469, 3, 2, '139877.5'), -496131505),
  ('control: float trap tie', (115, 2, 2, '1.1'), 126), ('control: negative exact', (-250, 2, 2, '0.5'), -125),
  ('control: yen to dinar', (1, 0, 3, '0.3071'), 307), ('control: negative tie', (-3, 2, 2, '0.5'), -2)],
 [('regression integer-rounding 1', (253357, 0, 4, '18.88901'), 47856629066),
  ('regression integer-rounding 2', (402529, 2, 4, '1.969810'), 79290565),
  ('partial repair guard 1', (-87559, 2, 2, '118188.8'), -10348493139),
  ('partial repair guard 2', (260569, 0, 4, '19.56965'), 50992441308), ('control: negative tie', (-3, 2, 2, '0.5'), -2),
  ('control: zero', (0, 2, 0, '151.37'), 0), ('control: precise rate', (123456, 2, 2, '1.08347'), 133761),
  ('control: large', (987654321, 2, 3, '0.30712'), 3033283951)]]
for label, args, expected in cases[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
from decimal import Decimal, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_FLOOR, ROUND_CEILING, ROUND_DOWN, ROUND_UP, ROUND_HALF_DOWN
N = 1
observations = []
def solve(amount_minor, from_exp, to_exp, rate):
    scale = Decimal(10) ** (to_exp - from_exp)
    v = Decimal(amount_minor) * Decimal(rate) * scale
    return int(v + Decimal('0.5'))
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression integer-rounding 1', (1000, 2, 0, '151.37'), 1514),
  ('regression integer-rounding 2', (-3, 2, 2, '0.5'), -2), ('partial repair guard 2', (-7, 2, 2, '0.3'), -2),
  ('control: float trap tie', (115, 2, 2, '1.1'), 126), ('control: negative exact', (-250, 2, 2, '0.5'), -125),
  ('control: yen to dinar', (1, 0, 3, '0.3071'), 307), ('control: zero', (0, 2, 0, '151.37'), 0)],
 [('regression integer-rounding 1', (123456, 2, 2, '1.08347'), 133761),
  ('regression integer-rounding 2', (987654321, 2, 3, '0.30712'), 3033283951),
  ('partial repair guard 1', (115, 2, 2, '1.1'), 126), ('partial repair guard 2', (-250, 2, 2, '0.5'), -125),
  ('control: yen to dinar', (1, 0, 3, '0.3071'), 307), ('control: negative tie', (-3, 2, 2, '0.5'), -2),
  ('control: zero', (0, 2, 0, '151.37'), 0), ('control: cents to yen', (1000, 2, 0, '151.37'), 1514)],
 [('regression integer-rounding 1', (589334, 0, 0, '168.0593'), 99043060),
  ('regression integer-rounding 2', (64824, 0, 2, '51.9345'), 336660203),
  ('partial repair guard 1', (-66003, 3, 4, '7.30025'), -4818384),
  ('partial repair guard 2', (-35317, 0, 3, '196135.8'), -6926928048600),
  ('control: precise rate', (123456, 2, 2, '1.08347'), 133761),
  ('control: large', (987654321, 2, 3, '0.30712'), 3033283951), ('control: cents to yen', (1000, 2, 0, '151.37'), 1514),
  ('control: float trap tie', (115, 2, 2, '1.1'), 126)],
 [('regression integer-rounding 1', (410259, 2, 2, '0.258909'), 106220),
  ('regression integer-rounding 2', (286850, 2, 3, '1.495849'), 4290843),
  ('partial repair guard 1', (-46763, 3, 2, '4592.5'), -21475908),
  ('partial repair guard 2', (-35469, 3, 2, '139877.5'), -496131505),
  ('control: float trap tie', (115, 2, 2, '1.1'), 126), ('control: negative exact', (-250, 2, 2, '0.5'), -125),
  ('control: yen to dinar', (1, 0, 3, '0.3071'), 307), ('control: negative tie', (-3, 2, 2, '0.5'), -2)],
 [('regression integer-rounding 1', (253357, 0, 4, '18.88901'), 47856629066),
  ('regression integer-rounding 2', (402529, 2, 4, '1.969810'), 79290565),
  ('partial repair guard 1', (-87559, 2, 2, '118188.8'), -10348493139),
  ('partial repair guard 2', (260569, 0, 4, '19.56965'), 50992441308), ('control: negative tie', (-3, 2, 2, '0.5'), -2),
  ('control: zero', (0, 2, 0, '151.37'), 0), ('control: precise rate', (123456, 2, 2, '1.08347'), 133761),
  ('control: large', (987654321, 2, 3, '0.30712'), 3033283951)]]
for label, args, expected in cases[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:
Converted amounts are systematically short by up to one minor unit, and negatives move toward zero.

solve(amount_minor, from_exp, to_exp, rate): amount_minor is an integer count of source minor units, rate a decimal string giving target major units per source major unit. The target minor amount is amount_minor * rate * 10**(to_exp - from_exp), computed exactly and rounded half-even to an integer.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json
from decimal import Decimal, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_FLOOR, ROUND_CEILING, ROUND_DOWN, ROUND_UP, ROUND_HALF_DOWN
N = 1
observations = []
def solve(amount_minor, from_exp, to_exp, rate):
    scale = Decimal(10) ** (to_exp - from_exp)
    v = Decimal(amount_minor * float(rate)) * scale
    return int(v.quantize(Decimal(1), rounding=ROUND_HALF_EVEN))
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression binary-product 1', (115, 2, 2, '1.1'), 126),
  ('regression binary-product 2', (238181, 0, 2, '147.6350'), 3516385194),
  ('control: cents to yen', (1000, 2, 0, '151.37'), 1514), ('control: negative exact', (-250, 2, 2, '0.5'), -125),
  ('control: yen to dinar', (1, 0, 3, '0.3071'), 307), ('control: negative tie', (-3, 2, 2, '0.5'), -2)],
 [('regression binary-product 1', (115, 2, 2, '1.1'), 126),
  ('regression binary-product 2', (238181, 0, 2, '147.6350'), 3516385194),
  ('control: yen to dinar', (1, 0, 3, '0.3071'), 307), ('control: negative tie', (-3, 2, 2, '0.5'), -2),
  ('control: zero', (0, 2, 0, '151.37'), 0), ('control: precise rate', (123456, 2, 2, '1.08347'), 133761)],
 [('regression binary-product 1', (115, 2, 2, '1.1'), 126),
  ('regression binary-product 2', (238181, 0, 2, '147.6350'), 3516385194),
  ('control: precise rate', (123456, 2, 2, '1.08347'), 133761),
  ('control: large', (987654321, 2, 3, '0.30712'), 3033283951), ('control: cents to yen', (1000, 2, 0, '151.37'), 1514),
  ('control: negative exact', (-250, 2, 2, '0.5'), -125)],
 [('regression binary-product 1', (115, 2, 2, '1.1'), 126),
  ('regression binary-product 2', (238181, 0, 2, '147.6350'), 3516385194),
  ('control: negative exact', (-250, 2, 2, '0.5'), -125), ('control: yen to dinar', (1, 0, 3, '0.3071'), 307),
  ('control: negative tie', (-3, 2, 2, '0.5'), -2), ('control: zero', (0, 2, 0, '151.37'), 0)],
 [('regression binary-product 1', (115, 2, 2, '1.1'), 126),
  ('regression binary-product 2', (238181, 0, 2, '147.6350'), 3516385194),
  ('control: negative tie', (-3, 2, 2, '0.5'), -2), ('control: zero', (0, 2, 0, '151.37'), 0),
  ('control: precise rate', (123456, 2, 2, '1.08347'), 133761),
  ('control: large', (987654321, 2, 3, '0.30712'), 3033283951)]]
for label, args, expected in cases[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
from decimal import Decimal, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_FLOOR, ROUND_CEILING, ROUND_DOWN, ROUND_UP, ROUND_HALF_DOWN
N = 1
observations = []
def solve(amount_minor, from_exp, to_exp, rate):
    scale = Decimal(10) ** (to_exp - from_exp)
    v = Decimal(repr(amount_minor * float(rate))) * scale
    return int(v.quantize(Decimal(1), rounding=ROUND_HALF_EVEN))
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression binary-product 1', (115, 2, 2, '1.1'), 126),
  ('regression binary-product 2', (238181, 0, 2, '147.6350'), 3516385194),
  ('control: cents to yen', (1000, 2, 0, '151.37'), 1514), ('control: negative exact', (-250, 2, 2, '0.5'), -125),
  ('control: yen to dinar', (1, 0, 3, '0.3071'), 307), ('control: negative tie', (-3, 2, 2, '0.5'), -2)],
 [('regression binary-product 1', (115, 2, 2, '1.1'), 126),
  ('regression binary-product 2', (238181, 0, 2, '147.6350'), 3516385194),
  ('control: yen to dinar', (1, 0, 3, '0.3071'), 307), ('control: negative tie', (-3, 2, 2, '0.5'), -2),
  ('control: zero', (0, 2, 0, '151.37'), 0), ('control: precise rate', (123456, 2, 2, '1.08347'), 133761)],
 [('regression binary-product 1', (115, 2, 2, '1.1'), 126),
  ('regression binary-product 2', (238181, 0, 2, '147.6350'), 3516385194),
  ('control: precise rate', (123456, 2, 2, '1.08347'), 133761),
  ('control: large', (987654321, 2, 3, '0.30712'), 3033283951), ('control: cents to yen', (1000, 2, 0, '151.37'), 1514),
  ('control: negative exact', (-250, 2, 2, '0.5'), -125)],
 [('regression binary-product 1', (115, 2, 2, '1.1'), 126),
  ('regression binary-product 2', (238181, 0, 2, '147.6350'), 3516385194),
  ('control: negative exact', (-250, 2, 2, '0.5'), -125), ('control: yen to dinar', (1, 0, 3, '0.3071'), 307),
  ('control: negative tie', (-3, 2, 2, '0.5'), -2), ('control: zero', (0, 2, 0, '151.37'), 0)],
 [('regression binary-product 1', (115, 2, 2, '1.1'), 126),
  ('regression binary-product 2', (238181, 0, 2, '147.6350'), 3516385194),
  ('control: negative tie', (-3, 2, 2, '0.5'), -2), ('control: zero', (0, 2, 0, '151.37'), 0),
  ('control: precise rate', (123456, 2, 2, '1.08347'), 133761),
  ('control: large', (987654321, 2, 3, '0.30712'), 3033283951)]]
for label, args, expected in cases[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:
115 cents at 1.1 becomes 127 instead of the half-even 126.

solve(amount_minor, from_exp, to_exp, rate): amount_minor is an integer count of source minor units, rate a decimal string giving target major units per source major unit. The target minor amount is amount_minor * rate * 10**(to_exp - from_exp), computed exactly and rounded half-even to an integer.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json
from decimal import Decimal, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_FLOOR, ROUND_CEILING, ROUND_DOWN, ROUND_UP, ROUND_HALF_DOWN
N = 1
observations = []
def solve(amount_minor, from_exp, to_exp, rate):
    scale = Decimal(10) ** (to_exp - from_exp)
    v = Decimal(amount_minor) * Decimal(rate).quantize(Decimal('0.0001'), rounding=ROUND_HALF_EVEN) * scale
    return int(v.quantize(Decimal(1), rounding=ROUND_HALF_EVEN))
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression rate-storage-scale 1', (987654321, 2, 3, '0.30712'), 3033283951),
  ('regression rate-storage-scale 2', (100000000, 2, 2, '1.0834712'), 108347120),
  ('partial repair guard 2', (123456789, 2, 2, '0.00000071'), 88),
  ('control: cents to yen', (1000, 2, 0, '151.37'), 1514), ('control: float trap tie', (115, 2, 2, '1.1'), 126),
  ('control: negative exact', (-250, 2, 2, '0.5'), -125), ('control: yen to dinar', (1, 0, 3, '0.3071'), 307)],
 [('regression rate-storage-scale 1', (123456789, 2, 2, '0.00000071'), 88),
  ('regression rate-storage-scale 2', (123456, 2, 2, '1.08347'), 133761),
  ('partial repair guard 1', (100000000, 2, 2, '1.0834712'), 108347120),
  ('control: yen to dinar', (1, 0, 3, '0.3071'), 307), ('control: negative tie', (-3, 2, 2, '0.5'), -2),
  ('control: zero', (0, 2, 0, '151.37'), 0), ('control: large', (987654321, 2, 3, '0.30712'), 3033283951)],
 [('regression rate-storage-scale 1', (755323, 2, 4, '7.24667'), 547357652),
  ('regression rate-storage-scale 2', (410259, 2, 2, '0.258909'), 106220),
  ('partial repair guard 1', (100000000, 2, 2, '1.0834712'), 108347120),
  ('partial repair guard 2', (123456789, 2, 2, '0.00000071'), 88),
  ('control: precise rate', (123456, 2, 2, '1.08347'), 133761),
  ('control: large', (987654321, 2, 3, '0.30712'), 3033283951), ('control: cents to yen', (1000, 2, 0, '151.37'), 1514),
  ('control: float trap tie', (115, 2, 2, '1.1'), 126)],
 [('regression rate-storage-scale 1', (286850, 2, 3, '1.495849'), 4290843),
  ('regression rate-storage-scale 2', (253357, 0, 4, '18.88901'), 47856629066),
  ('partial repair guard 1', (100000000, 2, 2, '1.0834712'), 108347120),
  ('partial repair guard 2', (123456789, 2, 2, '0.00000071'), 88), ('control: float trap tie', (115, 2, 2, '1.1'), 126),
  ('control: negative exact', (-250, 2, 2, '0.5'), -125), ('control: yen to dinar', (1, 0, 3, '0.3071'), 307),
  ('control: negative tie', (-3, 2, 2, '0.5'), -2)],
 [('regression rate-storage-scale 1', (395121, 3, 4, '1.362591'), 5383883),
  ('regression rate-storage-scale 2', (402529, 2, 4, '1.969810'), 79290565),
  ('partial repair guard 1', (100000000, 2, 2, '1.0834712'), 108347120),
  ('partial repair guard 2', (123456789, 2, 2, '0.00000071'), 88), ('control: negative tie', (-3, 2, 2, '0.5'), -2),
  ('control: zero', (0, 2, 0, '151.37'), 0), ('control: precise rate', (123456, 2, 2, '1.08347'), 133761),
  ('control: large', (987654321, 2, 3, '0.30712'), 3033283951)]]
for label, args, expected in cases[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
from decimal import Decimal, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_FLOOR, ROUND_CEILING, ROUND_DOWN, ROUND_UP, ROUND_HALF_DOWN
N = 1
observations = []
def solve(amount_minor, from_exp, to_exp, rate):
    scale = Decimal(10) ** (to_exp - from_exp)
    v = Decimal(amount_minor) * Decimal(rate).quantize(Decimal('0.000001'), rounding=ROUND_HALF_EVEN) * scale
    return int(v.quantize(Decimal(1), rounding=ROUND_HALF_EVEN))
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression rate-storage-scale 1', (987654321, 2, 3, '0.30712'), 3033283951),
  ('regression rate-storage-scale 2', (100000000, 2, 2, '1.0834712'), 108347120),
  ('partial repair guard 2', (123456789, 2, 2, '0.00000071'), 88),
  ('control: cents to yen', (1000, 2, 0, '151.37'), 1514), ('control: float trap tie', (115, 2, 2, '1.1'), 126),
  ('control: negative exact', (-250, 2, 2, '0.5'), -125), ('control: yen to dinar', (1, 0, 3, '0.3071'), 307)],
 [('regression rate-storage-scale 1', (123456789, 2, 2, '0.00000071'), 88),
  ('regression rate-storage-scale 2', (123456, 2, 2, '1.08347'), 133761),
  ('partial repair guard 1', (100000000, 2, 2, '1.0834712'), 108347120),
  ('control: yen to dinar', (1, 0, 3, '0.3071'), 307), ('control: negative tie', (-3, 2, 2, '0.5'), -2),
  ('control: zero', (0, 2, 0, '151.37'), 0), ('control: large', (987654321, 2, 3, '0.30712'), 3033283951)],
 [('regression rate-storage-scale 1', (755323, 2, 4, '7.24667'), 547357652),
  ('regression rate-storage-scale 2', (410259, 2, 2, '0.258909'), 106220),
  ('partial repair guard 1', (100000000, 2, 2, '1.0834712'), 108347120),
  ('partial repair guard 2', (123456789, 2, 2, '0.00000071'), 88),
  ('control: precise rate', (123456, 2, 2, '1.08347'), 133761),
  ('control: large', (987654321, 2, 3, '0.30712'), 3033283951), ('control: cents to yen', (1000, 2, 0, '151.37'), 1514),
  ('control: float trap tie', (115, 2, 2, '1.1'), 126)],
 [('regression rate-storage-scale 1', (286850, 2, 3, '1.495849'), 4290843),
  ('regression rate-storage-scale 2', (253357, 0, 4, '18.88901'), 47856629066),
  ('partial repair guard 1', (100000000, 2, 2, '1.0834712'), 108347120),
  ('partial repair guard 2', (123456789, 2, 2, '0.00000071'), 88), ('control: float trap tie', (115, 2, 2, '1.1'), 126),
  ('control: negative exact', (-250, 2, 2, '0.5'), -125), ('control: yen to dinar', (1, 0, 3, '0.3071'), 307),
  ('control: negative tie', (-3, 2, 2, '0.5'), -2)],
 [('regression rate-storage-scale 1', (395121, 3, 4, '1.362591'), 5383883),
  ('regression rate-storage-scale 2', (402529, 2, 4, '1.969810'), 79290565),
  ('partial repair guard 1', (100000000, 2, 2, '1.0834712'), 108347120),
  ('partial repair guard 2', (123456789, 2, 2, '0.00000071'), 88), ('control: negative tie', (-3, 2, 2, '0.5'), -2),
  ('control: zero', (0, 2, 0, '151.37'), 0), ('control: precise rate', (123456, 2, 2, '1.08347'), 133761),
  ('control: large', (987654321, 2, 3, '0.30712'), 3033283951)]]
for label, args, expected in cases[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:
Large conversions at five- or six-decimal rates are off by many minor units.

solve(amount_minor, from_exp, to_exp, rate): amount_minor is an integer count of source minor units, rate a decimal string giving target major units per source major unit. The target minor amount is amount_minor * rate * 10**(to_exp - from_exp), computed exactly and rounded half-even to an integer.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json
from decimal import Decimal, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_FLOOR, ROUND_CEILING, ROUND_DOWN, ROUND_UP, ROUND_HALF_DOWN
N = 1
observations = []
def solve(lines, tender):
    def cash(v):
        return (v / Decimal('0.05')).quantize(Decimal(1), rounding=ROUND_HALF_UP) * Decimal('0.05')
    def z(d, e):
        d = d.quantize(Decimal(1).scaleb(-e), rounding=ROUND_HALF_UP)
        return format(abs(d) if d == 0 else d, 'f')
    exact = sum((Decimal(l) for l in lines), Decimal('0.000'))
    if tender.strip().lower() == 'cash':
        r = sum((cash(Decimal(l)) for l in lines), Decimal('0.00'))
    else:
        r = exact.quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)
    return [z(r, 2), z(r - exact, 3)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression rounding-scope 1', (['1.02', '1.02'], 'cash'), ['2.05', '0.010']),
  ('regression rounding-scope 2', (['0.99', '0.03'], 'cash'), ['1.00', '-0.020']),
  ('partial repair guard 2', (['1.02', '1.00'], 'cash'), ['2.00', '-0.020']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('control: card exact', (['1.02'], 'card'), ['1.02', '0.000']),
  ('control: twint exact', (['3.33', '4.44'], 'twint'), ['7.77', '0.000'])],
 [('regression rounding-scope 1', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('regression rounding-scope 2', (['12.40', '-3.12', '0.99'], ' CASH'), ['10.25', '-0.020']),
  ('partial repair guard 1', (['0.99', '0.03'], 'cash'), ['1.00', '-0.020']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('control: card exact', (['1.02'], 'card'), ['1.02', '0.000']),
  ('control: twint exact', (['3.33', '4.44'], 'twint'), ['7.77', '0.000']),
  ('control: positive tie', (['3.00', '0.025'], 'cash'), ['3.05', '0.025'])],
 [('regression rounding-scope 1', (['12.71', '-2.68'], 'Cash'), ['10.05', '0.020']),
  ('regression rounding-scope 2', (['17.98', '8.07', '0.335', '23.38'], 'Cash'), ['49.75', '-0.015']),
  ('partial repair guard 1', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('partial repair guard 2', (['3.00', '0.025'], 'cash'), ['3.05', '0.025']),
  ('control: negative tie', (['-2.075'], 'cash'), ['-2.10', '-0.025']),
  ('control: voucher exact', (['7.07'], 'voucher'), ['7.07', '0.000']),
  ('control: mixed basket', (['12.40', '-3.12', '0.99'], ' CASH'), ['10.25', '-0.020']),
  ('control: round down', (['1.02', '1.00'], 'cash'), ['2.00', '-0.020'])],
 [('regression rounding-scope 1', (['7.95', '16.09', '-3.325', '23.21'], 'cash'), ['43.95', '0.025']),
  ('regression rounding-scope 2', (['12.08', '3.43', '4.44', '-4.37'], ' cash '), ['15.60', '0.020']),
  ('partial repair guard 1', (['-2.075'], 'cash'), ['-2.10', '-0.025']),
  ('partial repair guard 2', (['12.40', '-3.12', '0.99'], ' CASH'), ['10.25', '-0.020']),
  ('control: round down', (['1.02', '1.00'], 'cash'), ['2.00', '-0.020']),
  ('control: round to franc', (['0.99', '0.03'], 'cash'), ['1.00', '-0.020']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020'])],
 [('regression rounding-scope 1', (['22.60', '28.56', '15.17'], ' cash '), ['66.35', '0.020']),
  ('regression rounding-scope 2', (['1.095', '2.025', '14.13'], 'cash'), ['17.25', '0.000']),
  ('partial repair guard 1', (['12.71', '-2.68'], 'Cash'), ['10.05', '0.020']),
  ('partial repair guard 2', (['19.47', '26.34'], 'CASH'), ['45.80', '-0.010']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('control: card exact', (['1.02'], 'card'), ['1.02', '0.000']),
  ('control: twint exact', (['3.33', '4.44'], 'twint'), ['7.77', '0.000'])]]
for label, args, expected in cases[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
from decimal import Decimal, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_FLOOR, ROUND_CEILING, ROUND_DOWN, ROUND_UP, ROUND_HALF_DOWN
N = 1
observations = []
def solve(lines, tender):
    def cash(v):
        return (v / Decimal('0.05')).quantize(Decimal(1), rounding=ROUND_HALF_UP) * Decimal('0.05')
    def z(d, e):
        d = d.quantize(Decimal(1).scaleb(-e), rounding=ROUND_HALF_UP)
        return format(abs(d) if d == 0 else d, 'f')
    exact = sum((Decimal(l) for l in lines), Decimal('0.000'))
    if tender.strip().lower() == 'cash':
        r = exact.quantize(Decimal('0.05'), rounding=ROUND_HALF_UP)
    else:
        r = exact.quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)
    return [z(r, 2), z(r - exact, 3)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression rounding-scope 1', (['1.02', '1.02'], 'cash'), ['2.05', '0.010']),
  ('regression rounding-scope 2', (['0.99', '0.03'], 'cash'), ['1.00', '-0.020']),
  ('partial repair guard 2', (['1.02', '1.00'], 'cash'), ['2.00', '-0.020']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('control: card exact', (['1.02'], 'card'), ['1.02', '0.000']),
  ('control: twint exact', (['3.33', '4.44'], 'twint'), ['7.77', '0.000'])],
 [('regression rounding-scope 1', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('regression rounding-scope 2', (['12.40', '-3.12', '0.99'], ' CASH'), ['10.25', '-0.020']),
  ('partial repair guard 1', (['0.99', '0.03'], 'cash'), ['1.00', '-0.020']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('control: card exact', (['1.02'], 'card'), ['1.02', '0.000']),
  ('control: twint exact', (['3.33', '4.44'], 'twint'), ['7.77', '0.000']),
  ('control: positive tie', (['3.00', '0.025'], 'cash'), ['3.05', '0.025'])],
 [('regression rounding-scope 1', (['12.71', '-2.68'], 'Cash'), ['10.05', '0.020']),
  ('regression rounding-scope 2', (['17.98', '8.07', '0.335', '23.38'], 'Cash'), ['49.75', '-0.015']),
  ('partial repair guard 1', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('partial repair guard 2', (['3.00', '0.025'], 'cash'), ['3.05', '0.025']),
  ('control: negative tie', (['-2.075'], 'cash'), ['-2.10', '-0.025']),
  ('control: voucher exact', (['7.07'], 'voucher'), ['7.07', '0.000']),
  ('control: mixed basket', (['12.40', '-3.12', '0.99'], ' CASH'), ['10.25', '-0.020']),
  ('control: round down', (['1.02', '1.00'], 'cash'), ['2.00', '-0.020'])],
 [('regression rounding-scope 1', (['7.95', '16.09', '-3.325', '23.21'], 'cash'), ['43.95', '0.025']),
  ('regression rounding-scope 2', (['12.08', '3.43', '4.44', '-4.37'], ' cash '), ['15.60', '0.020']),
  ('partial repair guard 1', (['-2.075'], 'cash'), ['-2.10', '-0.025']),
  ('partial repair guard 2', (['12.40', '-3.12', '0.99'], ' CASH'), ['10.25', '-0.020']),
  ('control: round down', (['1.02', '1.00'], 'cash'), ['2.00', '-0.020']),
  ('control: round to franc', (['0.99', '0.03'], 'cash'), ['1.00', '-0.020']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020'])],
 [('regression rounding-scope 1', (['22.60', '28.56', '15.17'], ' cash '), ['66.35', '0.020']),
  ('regression rounding-scope 2', (['1.095', '2.025', '14.13'], 'cash'), ['17.25', '0.000']),
  ('partial repair guard 1', (['12.71', '-2.68'], 'Cash'), ['10.05', '0.020']),
  ('partial repair guard 2', (['19.47', '26.34'], 'CASH'), ['45.80', '-0.010']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('control: card exact', (['1.02'], 'card'), ['1.02', '0.000']),
  ('control: twint exact', (['3.33', '4.44'], 'twint'), ['7.77', '0.000'])]]
for label, args, expected in cases[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 basket of 1.02 and 1.02 is charged 2.00 instead of 2.05.

solve(lines, tender): lines are CHF decimal strings with up to three decimals (weight- or volume-priced items; refund lines negative). The exact total is their sum. For tender 'cash' (compared after trimming and lower-casing) the total is rounded to the nearest 0.05 with ties away from zero; every other tender ('card', 'twint', 'voucher', ...) pays the total rounded half-up to 0.01. Return [payable as a 2-decimal string, adjustment as a 3-decimal string] where adjustment = payable - exact; zeros are unsigned.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json
from decimal import Decimal, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_FLOOR, ROUND_CEILING, ROUND_DOWN, ROUND_UP, ROUND_HALF_DOWN
N = 1
observations = []
def solve(lines, tender):
    def cash(v):
        return (v / Decimal('0.05') + Decimal('0.5')).quantize(Decimal(1), rounding=ROUND_FLOOR) * Decimal('0.05')
    def z(d, e):
        d = d.quantize(Decimal(1).scaleb(-e), rounding=ROUND_HALF_UP)
        return format(abs(d) if d == 0 else d, 'f')
    exact = sum((Decimal(l) for l in lines), Decimal('0.000'))
    if tender.strip().lower() == 'cash':
        r = cash(exact)
    else:
        r = exact.quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)
    return [z(r, 2), z(r - exact, 3)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression refund-tie-direction 1', (['-2.075'], 'cash'), ['-2.10', '-0.025']),
  ('regression refund-tie-direction 2', (['-1.025'], 'cash'), ['-1.05', '-0.025']),
  ('partial repair guard 2', (['3.00', '0.025'], 'cash'), ['3.05', '0.025']),
  ('control: round down', (['1.02', '1.00'], 'cash'), ['2.00', '-0.020']),
  ('control: round to franc', (['0.99', '0.03'], 'cash'), ['1.00', '-0.020']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020'])],
 [('regression refund-tie-direction 1', (['-0.075'], 'cash'), ['-0.10', '-0.025']),
  ('regression refund-tie-direction 2', (['-0.625'], 'cash'), ['-0.65', '-0.025']),
  ('partial repair guard 1', (['7.95', '16.09', '-3.325', '23.21'], 'cash'), ['43.95', '0.025']),
  ('partial repair guard 2', (['-0.46', '-0.885', '26.47'], 'CASH'), ['25.15', '0.025']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('control: card exact', (['1.02'], 'card'), ['1.02', '0.000']),
  ('control: twint exact', (['3.33', '4.44'], 'twint'), ['7.77', '0.000']),
  ('control: positive tie', (['3.00', '0.025'], 'cash'), ['3.05', '0.025'])],
 [('regression refund-tie-direction 1', (['-2.075'], 'cash'), ['-2.10', '-0.025']),
  ('regression refund-tie-direction 2', (['-1.025'], 'cash'), ['-1.05', '-0.025']),
  ('partial repair guard 1', (['1.825'], 'CASH'), ['1.85', '0.025']),
  ('partial repair guard 2', (['-0.625'], 'cash'), ['-0.65', '-0.025']),
  ('control: positive tie', (['3.00', '0.025'], 'cash'), ['3.05', '0.025']),
  ('control: voucher exact', (['7.07'], 'voucher'), ['7.07', '0.000']),
  ('control: mixed basket', (['12.40', '-3.12', '0.99'], ' CASH'), ['10.25', '-0.020']),
  ('control: round down', (['1.02', '1.00'], 'cash'), ['2.00', '-0.020'])],
 [('regression refund-tie-direction 1', (['-0.075'], 'cash'), ['-0.10', '-0.025']),
  ('regression refund-tie-direction 2', (['-0.625'], 'cash'), ['-0.65', '-0.025']),
  ('partial repair guard 1', (['22.51', '1.915'], 'Cash'), ['24.45', '0.025']),
  ('partial repair guard 2', (['8.51', '22.58', '28.67', '0.565'], 'Cash'), ['60.35', '0.025']),
  ('control: mixed basket', (['12.40', '-3.12', '0.99'], ' CASH'), ['10.25', '-0.020']),
  ('control: round down', (['1.02', '1.00'], 'cash'), ['2.00', '-0.020']),
  ('control: round to franc', (['0.99', '0.03'], 'cash'), ['1.00', '-0.020']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020'])],
 [('regression refund-tie-direction 1', (['-2.075'], 'cash'), ['-2.10', '-0.025']),
  ('regression refund-tie-direction 2', (['-1.025'], 'cash'), ['-1.05', '-0.025']),
  ('partial repair guard 1', (['3.51', '-0.375', '11.09'], 'Cash'), ['14.25', '0.025']),
  ('partial repair guard 2', (['15.83', '18.48', '1.715'], 'Cash'), ['36.05', '0.025']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('control: card exact', (['1.02'], 'card'), ['1.02', '0.000']),
  ('control: twint exact', (['3.33', '4.44'], 'twint'), ['7.77', '0.000'])]]
for label, args, expected in cases[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
from decimal import Decimal, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_FLOOR, ROUND_CEILING, ROUND_DOWN, ROUND_UP, ROUND_HALF_DOWN
N = 1
observations = []
def solve(lines, tender):
    def cash(v):
        return (v / Decimal('0.05')).quantize(Decimal(1), rounding=ROUND_HALF_EVEN) * Decimal('0.05')
    def z(d, e):
        d = d.quantize(Decimal(1).scaleb(-e), rounding=ROUND_HALF_UP)
        return format(abs(d) if d == 0 else d, 'f')
    exact = sum((Decimal(l) for l in lines), Decimal('0.000'))
    if tender.strip().lower() == 'cash':
        r = cash(exact)
    else:
        r = exact.quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)
    return [z(r, 2), z(r - exact, 3)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression refund-tie-direction 1', (['-2.075'], 'cash'), ['-2.10', '-0.025']),
  ('regression refund-tie-direction 2', (['-1.025'], 'cash'), ['-1.05', '-0.025']),
  ('partial repair guard 2', (['3.00', '0.025'], 'cash'), ['3.05', '0.025']),
  ('control: round down', (['1.02', '1.00'], 'cash'), ['2.00', '-0.020']),
  ('control: round to franc', (['0.99', '0.03'], 'cash'), ['1.00', '-0.020']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020'])],
 [('regression refund-tie-direction 1', (['-0.075'], 'cash'), ['-0.10', '-0.025']),
  ('regression refund-tie-direction 2', (['-0.625'], 'cash'), ['-0.65', '-0.025']),
  ('partial repair guard 1', (['7.95', '16.09', '-3.325', '23.21'], 'cash'), ['43.95', '0.025']),
  ('partial repair guard 2', (['-0.46', '-0.885', '26.47'], 'CASH'), ['25.15', '0.025']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('control: card exact', (['1.02'], 'card'), ['1.02', '0.000']),
  ('control: twint exact', (['3.33', '4.44'], 'twint'), ['7.77', '0.000']),
  ('control: positive tie', (['3.00', '0.025'], 'cash'), ['3.05', '0.025'])],
 [('regression refund-tie-direction 1', (['-2.075'], 'cash'), ['-2.10', '-0.025']),
  ('regression refund-tie-direction 2', (['-1.025'], 'cash'), ['-1.05', '-0.025']),
  ('partial repair guard 1', (['1.825'], 'CASH'), ['1.85', '0.025']),
  ('partial repair guard 2', (['-0.625'], 'cash'), ['-0.65', '-0.025']),
  ('control: positive tie', (['3.00', '0.025'], 'cash'), ['3.05', '0.025']),
  ('control: voucher exact', (['7.07'], 'voucher'), ['7.07', '0.000']),
  ('control: mixed basket', (['12.40', '-3.12', '0.99'], ' CASH'), ['10.25', '-0.020']),
  ('control: round down', (['1.02', '1.00'], 'cash'), ['2.00', '-0.020'])],
 [('regression refund-tie-direction 1', (['-0.075'], 'cash'), ['-0.10', '-0.025']),
  ('regression refund-tie-direction 2', (['-0.625'], 'cash'), ['-0.65', '-0.025']),
  ('partial repair guard 1', (['22.51', '1.915'], 'Cash'), ['24.45', '0.025']),
  ('partial repair guard 2', (['8.51', '22.58', '28.67', '0.565'], 'Cash'), ['60.35', '0.025']),
  ('control: mixed basket', (['12.40', '-3.12', '0.99'], ' CASH'), ['10.25', '-0.020']),
  ('control: round down', (['1.02', '1.00'], 'cash'), ['2.00', '-0.020']),
  ('control: round to franc', (['0.99', '0.03'], 'cash'), ['1.00', '-0.020']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020'])],
 [('regression refund-tie-direction 1', (['-2.075'], 'cash'), ['-2.10', '-0.025']),
  ('regression refund-tie-direction 2', (['-1.025'], 'cash'), ['-1.05', '-0.025']),
  ('partial repair guard 1', (['3.51', '-0.375', '11.09'], 'Cash'), ['14.25', '0.025']),
  ('partial repair guard 2', (['15.83', '18.48', '1.715'], 'Cash'), ['36.05', '0.025']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('control: card exact', (['1.02'], 'card'), ['1.02', '0.000']),
  ('control: twint exact', (['3.33', '4.44'], 'twint'), ['7.77', '0.000'])]]
for label, args, expected in cases[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 cash refund of -2.075 pays out -2.05 while a 2.075 sale charges 2.10.

solve(lines, tender): lines are CHF decimal strings with up to three decimals (weight- or volume-priced items; refund lines negative). The exact total is their sum. For tender 'cash' (compared after trimming and lower-casing) the total is rounded to the nearest 0.05 with ties away from zero; every other tender ('card', 'twint', 'voucher', ...) pays the total rounded half-up to 0.01. Return [payable as a 2-decimal string, adjustment as a 3-decimal string] where adjustment = payable - exact; zeros are unsigned.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json
from decimal import Decimal, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_FLOOR, ROUND_CEILING, ROUND_DOWN, ROUND_UP, ROUND_HALF_DOWN
N = 1
observations = []
def solve(lines, tender):
    def cash(v):
        return (v / Decimal('0.05')).quantize(Decimal(1), rounding=ROUND_HALF_UP) * Decimal('0.05')
    def z(d, e):
        d = d.quantize(Decimal(1).scaleb(-e), rounding=ROUND_HALF_UP)
        return format(abs(d) if d == 0 else d, 'f')
    exact = sum((Decimal(l) for l in lines), Decimal('0.000'))
    if tender.strip().lower() != 'card':
        r = cash(exact)
    else:
        r = exact.quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)
    return [z(r, 2), z(r - exact, 3)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression tender-scope 1', (['3.33', '4.44'], 'twint'), ['7.77', '0.000']),
  ('regression tender-scope 2', (['7.07'], 'voucher'), ['7.07', '0.000']),
  ('partial repair guard 2', (['2.215', '-2.59', '0.15', '24.24'], 'voucher'), ['24.02', '0.005']),
  ('control: round down', (['1.02', '1.00'], 'cash'), ['2.00', '-0.020']),
  ('control: round to franc', (['0.99', '0.03'], 'cash'), ['1.00', '-0.020']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020'])],
 [('regression tender-scope 1', (['22.99', '2.02', '4.93', '0.185'], 'twint'), ['30.13', '0.005']),
  ('regression tender-scope 2', (['2.215', '-2.59', '0.15', '24.24'], 'voucher'), ['24.02', '0.005']),
  ('partial repair guard 1', (['12.22', '18.81', '9.42', '4.81'], 'voucher'), ['45.26', '0.000']),
  ('partial repair guard 2', (['24.12', '-3.20', '-4.67', '20.42'], 'voucher'), ['36.67', '0.000']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('control: card exact', (['1.02'], 'card'), ['1.02', '0.000']),
  ('control: twint exact', (['3.33', '4.44'], 'twint'), ['7.77', '0.000']),
  ('control: positive tie', (['3.00', '0.025'], 'cash'), ['3.05', '0.025'])],
 [('regression tender-scope 1', (['12.22', '18.81', '9.42', '4.81'], 'voucher'), ['45.26', '0.000']),
  ('regression tender-scope 2', (['24.12', '-3.20', '-4.67', '20.42'], 'voucher'), ['36.67', '0.000']),
  ('partial repair guard 1', (['8.11'], 'voucher'), ['8.11', '0.000']),
  ('partial repair guard 2', (['15.28'], 'voucher'), ['15.28', '0.000']),
  ('control: positive tie', (['3.00', '0.025'], 'cash'), ['3.05', '0.025']),
  ('control: negative tie', (['-2.075'], 'cash'), ['-2.10', '-0.025']),
  ('control: voucher exact', (['7.07'], 'voucher'), ['7.07', '0.000']),
  ('control: mixed basket', (['12.40', '-3.12', '0.99'], ' CASH'), ['10.25', '-0.020'])],
 [('regression tender-scope 1', (['8.11'], 'voucher'), ['8.11', '0.000']),
  ('regression tender-scope 2', (['-3.385'], 'twint'), ['-3.39', '-0.005']),
  ('partial repair guard 1', (['5.31', '-1.325'], 'voucher'), ['3.99', '0.005']),
  ('partial repair guard 2', (['12.32', '6.28', '-0.89', '2.395'], 'voucher'), ['20.11', '0.005']),
  ('control: mixed basket', (['12.40', '-3.12', '0.99'], ' CASH'), ['10.25', '-0.020']),
  ('control: round down', (['1.02', '1.00'], 'cash'), ['2.00', '-0.020']),
  ('control: round to franc', (['0.99', '0.03'], 'cash'), ['1.00', '-0.020']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020'])],
 [('regression tender-scope 1', (['22.96'], 'twint'), ['22.96', '0.000']),
  ('regression tender-scope 2', (['15.28'], 'voucher'), ['15.28', '0.000']),
  ('partial repair guard 1', (['25.48'], 'voucher'), ['25.48', '0.000']),
  ('partial repair guard 2', (['19.98', '1.54'], 'voucher'), ['21.52', '0.000']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('control: card exact', (['1.02'], 'card'), ['1.02', '0.000']),
  ('control: twint exact', (['3.33', '4.44'], 'twint'), ['7.77', '0.000'])]]
for label, args, expected in cases[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
from decimal import Decimal, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_FLOOR, ROUND_CEILING, ROUND_DOWN, ROUND_UP, ROUND_HALF_DOWN
N = 1
observations = []
def solve(lines, tender):
    def cash(v):
        return (v / Decimal('0.05')).quantize(Decimal(1), rounding=ROUND_HALF_UP) * Decimal('0.05')
    def z(d, e):
        d = d.quantize(Decimal(1).scaleb(-e), rounding=ROUND_HALF_UP)
        return format(abs(d) if d == 0 else d, 'f')
    exact = sum((Decimal(l) for l in lines), Decimal('0.000'))
    if tender.strip().lower() in ('cash', 'voucher'):
        r = cash(exact)
    else:
        r = exact.quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)
    return [z(r, 2), z(r - exact, 3)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression tender-scope 1', (['3.33', '4.44'], 'twint'), ['7.77', '0.000']),
  ('regression tender-scope 2', (['7.07'], 'voucher'), ['7.07', '0.000']),
  ('partial repair guard 2', (['2.215', '-2.59', '0.15', '24.24'], 'voucher'), ['24.02', '0.005']),
  ('control: round down', (['1.02', '1.00'], 'cash'), ['2.00', '-0.020']),
  ('control: round to franc', (['0.99', '0.03'], 'cash'), ['1.00', '-0.020']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020'])],
 [('regression tender-scope 1', (['22.99', '2.02', '4.93', '0.185'], 'twint'), ['30.13', '0.005']),
  ('regression tender-scope 2', (['2.215', '-2.59', '0.15', '24.24'], 'voucher'), ['24.02', '0.005']),
  ('partial repair guard 1', (['12.22', '18.81', '9.42', '4.81'], 'voucher'), ['45.26', '0.000']),
  ('partial repair guard 2', (['24.12', '-3.20', '-4.67', '20.42'], 'voucher'), ['36.67', '0.000']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('control: card exact', (['1.02'], 'card'), ['1.02', '0.000']),
  ('control: twint exact', (['3.33', '4.44'], 'twint'), ['7.77', '0.000']),
  ('control: positive tie', (['3.00', '0.025'], 'cash'), ['3.05', '0.025'])],
 [('regression tender-scope 1', (['12.22', '18.81', '9.42', '4.81'], 'voucher'), ['45.26', '0.000']),
  ('regression tender-scope 2', (['24.12', '-3.20', '-4.67', '20.42'], 'voucher'), ['36.67', '0.000']),
  ('partial repair guard 1', (['8.11'], 'voucher'), ['8.11', '0.000']),
  ('partial repair guard 2', (['15.28'], 'voucher'), ['15.28', '0.000']),
  ('control: positive tie', (['3.00', '0.025'], 'cash'), ['3.05', '0.025']),
  ('control: negative tie', (['-2.075'], 'cash'), ['-2.10', '-0.025']),
  ('control: voucher exact', (['7.07'], 'voucher'), ['7.07', '0.000']),
  ('control: mixed basket', (['12.40', '-3.12', '0.99'], ' CASH'), ['10.25', '-0.020'])],
 [('regression tender-scope 1', (['8.11'], 'voucher'), ['8.11', '0.000']),
  ('regression tender-scope 2', (['-3.385'], 'twint'), ['-3.39', '-0.005']),
  ('partial repair guard 1', (['5.31', '-1.325'], 'voucher'), ['3.99', '0.005']),
  ('partial repair guard 2', (['12.32', '6.28', '-0.89', '2.395'], 'voucher'), ['20.11', '0.005']),
  ('control: mixed basket', (['12.40', '-3.12', '0.99'], ' CASH'), ['10.25', '-0.020']),
  ('control: round down', (['1.02', '1.00'], 'cash'), ['2.00', '-0.020']),
  ('control: round to franc', (['0.99', '0.03'], 'cash'), ['1.00', '-0.020']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020'])],
 [('regression tender-scope 1', (['22.96'], 'twint'), ['22.96', '0.000']),
  ('regression tender-scope 2', (['15.28'], 'voucher'), ['15.28', '0.000']),
  ('partial repair guard 1', (['25.48'], 'voucher'), ['25.48', '0.000']),
  ('partial repair guard 2', (['19.98', '1.54'], 'voucher'), ['21.52', '0.000']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('control: card exact', (['1.02'], 'card'), ['1.02', '0.000']),
  ('control: twint exact', (['3.33', '4.44'], 'twint'), ['7.77', '0.000'])]]
for label, args, expected in cases[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:
TWINT and voucher payments are rounded to 0.05 as if paid in coins.

solve(lines, tender): lines are CHF decimal strings with up to three decimals (weight- or volume-priced items; refund lines negative). The exact total is their sum. For tender 'cash' (compared after trimming and lower-casing) the total is rounded to the nearest 0.05 with ties away from zero; every other tender ('card', 'twint', 'voucher', ...) pays the total rounded half-up to 0.01. Return [payable as a 2-decimal string, adjustment as a 3-decimal string] where adjustment = payable - exact; zeros are unsigned.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json
from decimal import Decimal, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_FLOOR, ROUND_CEILING, ROUND_DOWN, ROUND_UP, ROUND_HALF_DOWN
N = 1
observations = []
def solve(lines, tender):
    def cash(v):
        return (v / Decimal('0.05')).quantize(Decimal(1), rounding=ROUND_HALF_UP) * Decimal('0.05')
    def z(d, e):
        d = d.quantize(Decimal(1).scaleb(-e), rounding=ROUND_HALF_UP)
        return format(abs(d) if d == 0 else d, 'f')
    exact = sum((Decimal(l) for l in lines), Decimal('0.000'))
    if tender == 'cash':
        r = cash(exact)
    else:
        r = exact.quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)
    return [z(r, 2), z(r - exact, 3)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression tender-normalization 1', (['12.40', '-3.12', '0.99'], ' CASH'), ['10.25', '-0.020']),
  ('regression tender-normalization 2', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('control: round down', (['1.02', '1.00'], 'cash'), ['2.00', '-0.020']),
  ('control: round to franc', (['0.99', '0.03'], 'cash'), ['1.00', '-0.020']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('control: card exact', (['1.02'], 'card'), ['1.02', '0.000'])],
 [('regression tender-normalization 1', (['12.71', '-2.68'], 'Cash'), ['10.05', '0.020']),
  ('regression tender-normalization 2', (['19.47', '26.34'], 'CASH'), ['45.80', '-0.010']),
  ('partial repair guard 1', (['3.93'], ' cash '), ['3.95', '0.020']),
  ('partial repair guard 2', (['2.955'], ' cash '), ['2.95', '-0.005']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('control: card exact', (['1.02'], 'card'), ['1.02', '0.000']),
  ('control: twint exact', (['3.33', '4.44'], 'twint'), ['7.77', '0.000']),
  ('control: positive tie', (['3.00', '0.025'], 'cash'), ['3.05', '0.025'])],
 [('regression tender-normalization 1', (['17.98', '8.07', '0.335', '23.38'], 'Cash'), ['49.75', '-0.015']),
  ('regression tender-normalization 2', (['-1.435'], 'Cash'), ['-1.45', '-0.015']),
  ('partial repair guard 1', (['4.92'], ' cash '), ['4.90', '-0.020']),
  ('partial repair guard 2', (['12.08', '3.43', '4.44', '-4.37'], ' cash '), ['15.60', '0.020']),
  ('control: positive tie', (['3.00', '0.025'], 'cash'), ['3.05', '0.025']),
  ('control: negative tie', (['-2.075'], 'cash'), ['-2.10', '-0.025']),
  ('control: voucher exact', (['7.07'], 'voucher'), ['7.07', '0.000']),
  ('control: mixed basket', (['12.40', '-3.12', '0.99'], ' CASH'), ['10.25', '-0.020'])],
 [('regression tender-normalization 1', (['3.93'], ' cash '), ['3.95', '0.020']),
  ('regression tender-normalization 2', (['2.955'], ' cash '), ['2.95', '-0.005']),
  ('partial repair guard 1', (['22.60', '28.56', '15.17'], ' cash '), ['66.35', '0.020']),
  ('partial repair guard 2', (['23.36'], ' cash '), ['23.35', '-0.010']),
  ('control: mixed basket', (['12.40', '-3.12', '0.99'], ' CASH'), ['10.25', '-0.020']),
  ('control: round down', (['1.02', '1.00'], 'cash'), ['2.00', '-0.020']),
  ('control: round to franc', (['0.99', '0.03'], 'cash'), ['1.00', '-0.020']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020'])],
 [('regression tender-normalization 1', (['2.49', '-3.655', '28.09', '6.96'], 'CASH'), ['33.90', '0.015']),
  ('regression tender-normalization 2', (['2.975'], 'CASH'), ['3.00', '0.025']),
  ('partial repair guard 1', (['4.13', '13.22', '14.73', '-1.77'], ' cash '), ['30.30', '-0.010']),
  ('partial repair guard 2', (['26.28', '1.09', '10.19', '-3.755'], ' cash '), ['33.80', '-0.005']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('control: card exact', (['1.02'], 'card'), ['1.02', '0.000']),
  ('control: twint exact', (['3.33', '4.44'], 'twint'), ['7.77', '0.000'])]]
for label, args, expected in cases[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
from decimal import Decimal, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_FLOOR, ROUND_CEILING, ROUND_DOWN, ROUND_UP, ROUND_HALF_DOWN
N = 1
observations = []
def solve(lines, tender):
    def cash(v):
        return (v / Decimal('0.05')).quantize(Decimal(1), rounding=ROUND_HALF_UP) * Decimal('0.05')
    def z(d, e):
        d = d.quantize(Decimal(1).scaleb(-e), rounding=ROUND_HALF_UP)
        return format(abs(d) if d == 0 else d, 'f')
    exact = sum((Decimal(l) for l in lines), Decimal('0.000'))
    if tender.lower() == 'cash':
        r = cash(exact)
    else:
        r = exact.quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)
    return [z(r, 2), z(r - exact, 3)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression tender-normalization 1', (['12.40', '-3.12', '0.99'], ' CASH'), ['10.25', '-0.020']),
  ('regression tender-normalization 2', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('control: round down', (['1.02', '1.00'], 'cash'), ['2.00', '-0.020']),
  ('control: round to franc', (['0.99', '0.03'], 'cash'), ['1.00', '-0.020']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('control: card exact', (['1.02'], 'card'), ['1.02', '0.000'])],
 [('regression tender-normalization 1', (['12.71', '-2.68'], 'Cash'), ['10.05', '0.020']),
  ('regression tender-normalization 2', (['19.47', '26.34'], 'CASH'), ['45.80', '-0.010']),
  ('partial repair guard 1', (['3.93'], ' cash '), ['3.95', '0.020']),
  ('partial repair guard 2', (['2.955'], ' cash '), ['2.95', '-0.005']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('control: card exact', (['1.02'], 'card'), ['1.02', '0.000']),
  ('control: twint exact', (['3.33', '4.44'], 'twint'), ['7.77', '0.000']),
  ('control: positive tie', (['3.00', '0.025'], 'cash'), ['3.05', '0.025'])],
 [('regression tender-normalization 1', (['17.98', '8.07', '0.335', '23.38'], 'Cash'), ['49.75', '-0.015']),
  ('regression tender-normalization 2', (['-1.435'], 'Cash'), ['-1.45', '-0.015']),
  ('partial repair guard 1', (['4.92'], ' cash '), ['4.90', '-0.020']),
  ('partial repair guard 2', (['12.08', '3.43', '4.44', '-4.37'], ' cash '), ['15.60', '0.020']),
  ('control: positive tie', (['3.00', '0.025'], 'cash'), ['3.05', '0.025']),
  ('control: negative tie', (['-2.075'], 'cash'), ['-2.10', '-0.025']),
  ('control: voucher exact', (['7.07'], 'voucher'), ['7.07', '0.000']),
  ('control: mixed basket', (['12.40', '-3.12', '0.99'], ' CASH'), ['10.25', '-0.020'])],
 [('regression tender-normalization 1', (['3.93'], ' cash '), ['3.95', '0.020']),
  ('regression tender-normalization 2', (['2.955'], ' cash '), ['2.95', '-0.005']),
  ('partial repair guard 1', (['22.60', '28.56', '15.17'], ' cash '), ['66.35', '0.020']),
  ('partial repair guard 2', (['23.36'], ' cash '), ['23.35', '-0.010']),
  ('control: mixed basket', (['12.40', '-3.12', '0.99'], ' CASH'), ['10.25', '-0.020']),
  ('control: round down', (['1.02', '1.00'], 'cash'), ['2.00', '-0.020']),
  ('control: round to franc', (['0.99', '0.03'], 'cash'), ['1.00', '-0.020']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020'])],
 [('regression tender-normalization 1', (['2.49', '-3.655', '28.09', '6.96'], 'CASH'), ['33.90', '0.015']),
  ('regression tender-normalization 2', (['2.975'], 'CASH'), ['3.00', '0.025']),
  ('partial repair guard 1', (['4.13', '13.22', '14.73', '-1.77'], ' cash '), ['30.30', '-0.010']),
  ('partial repair guard 2', (['26.28', '1.09', '10.19', '-3.755'], ' cash '), ['33.80', '-0.005']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('control: card exact', (['1.02'], 'card'), ['1.02', '0.000']),
  ('control: twint exact', (['3.33', '4.44'], 'twint'), ['7.77', '0.000'])]]
for label, args, expected in cases[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:
'CASH' and ' cash ' payments are charged the exact total.

solve(lines, tender): lines are CHF decimal strings with up to three decimals (weight- or volume-priced items; refund lines negative). The exact total is their sum. For tender 'cash' (compared after trimming and lower-casing) the total is rounded to the nearest 0.05 with ties away from zero; every other tender ('card', 'twint', 'voucher', ...) pays the total rounded half-up to 0.01. Return [payable as a 2-decimal string, adjustment as a 3-decimal string] where adjustment = payable - exact; zeros are unsigned.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json
from decimal import Decimal, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_FLOOR, ROUND_CEILING, ROUND_DOWN, ROUND_UP, ROUND_HALF_DOWN
N = 1
observations = []
def solve(lines, tender):
    def cash(v):
        return (v / Decimal('0.05')).quantize(Decimal(1), rounding=ROUND_HALF_UP) * Decimal('0.05')
    def z(d, e):
        d = d.quantize(Decimal(1).scaleb(-e), rounding=ROUND_HALF_UP)
        return format(abs(d) if d == 0 else d, 'f')
    exact = sum((Decimal(l) for l in lines), Decimal('0.000'))
    if tender.strip().lower() == 'cash':
        r = cash(exact)
    else:
        r = exact.quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)
    return [z(r, 2), z(exact - r, 3)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression adjustment-sign 1', (['1.02', '1.00'], 'cash'), ['2.00', '-0.020']),
  ('regression adjustment-sign 2', (['2.025'], 'cash'), ['2.05', '0.025']),
  ('partial repair guard 2', (['0.99', '0.03'], 'cash'), ['1.00', '-0.020']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('control: card exact', (['1.02'], 'card'), ['1.02', '0.000']),
  ('control: twint exact', (['3.33', '4.44'], 'twint'), ['7.77', '0.000'])],
 [('regression adjustment-sign 1', (['0.99', '0.03'], 'cash'), ['1.00', '-0.020']),
  ('regression adjustment-sign 2', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('partial repair guard 1', (['-2.075'], 'cash'), ['-2.10', '-0.025']),
  ('partial repair guard 2', (['12.40', '-3.12', '0.99'], ' CASH'), ['10.25', '-0.020']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('control: card exact', (['1.02'], 'card'), ['1.02', '0.000']),
  ('control: twint exact', (['3.33', '4.44'], 'twint'), ['7.77', '0.000']),
  ('control: positive tie', (['3.00', '0.025'], 'cash'), ['3.05', '0.025'])],
 [('regression adjustment-sign 1', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('regression adjustment-sign 2', (['3.00', '0.025'], 'cash'), ['3.05', '0.025']),
  ('partial repair guard 1', (['19.47', '26.34'], 'CASH'), ['45.80', '-0.010']),
  ('partial repair guard 2', (['17.98', '8.07', '0.335', '23.38'], 'Cash'), ['49.75', '-0.015']),
  ('control: negative tie', (['-2.075'], 'cash'), ['-2.10', '-0.025']),
  ('control: voucher exact', (['7.07'], 'voucher'), ['7.07', '0.000']),
  ('control: mixed basket', (['12.40', '-3.12', '0.99'], ' CASH'), ['10.25', '-0.020']),
  ('control: round down', (['1.02', '1.00'], 'cash'), ['2.00', '-0.020'])],
 [('regression adjustment-sign 1', (['-2.075'], 'cash'), ['-2.10', '-0.025']),
  ('regression adjustment-sign 2', (['12.40', '-3.12', '0.99'], ' CASH'), ['10.25', '-0.020']),
  ('partial repair guard 1', (['-1.435'], 'Cash'), ['-1.45', '-0.015']),
  ('partial repair guard 2', (['2.955'], ' cash '), ['2.95', '-0.005']),
  ('control: round down', (['1.02', '1.00'], 'cash'), ['2.00', '-0.020']),
  ('control: round to franc', (['0.99', '0.03'], 'cash'), ['1.00', '-0.020']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020'])],
 [('regression adjustment-sign 1', (['12.71', '-2.68'], 'Cash'), ['10.05', '0.020']),
  ('regression adjustment-sign 2', (['22.99', '2.02', '4.93', '0.185'], 'twint'), ['30.13', '0.005']),
  ('partial repair guard 1', (['1.91', '-3.315'], 'card'), ['-1.41', '-0.005']),
  ('partial repair guard 2', (['4.92'], ' cash '), ['4.90', '-0.020']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('control: card exact', (['1.02'], 'card'), ['1.02', '0.000']),
  ('control: twint exact', (['3.33', '4.44'], 'twint'), ['7.77', '0.000'])]]
for label, args, expected in cases[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
from decimal import Decimal, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_FLOOR, ROUND_CEILING, ROUND_DOWN, ROUND_UP, ROUND_HALF_DOWN
N = 1
observations = []
def solve(lines, tender):
    def cash(v):
        return (v / Decimal('0.05')).quantize(Decimal(1), rounding=ROUND_HALF_UP) * Decimal('0.05')
    def z(d, e):
        d = d.quantize(Decimal(1).scaleb(-e), rounding=ROUND_HALF_UP)
        return format(abs(d) if d == 0 else d, 'f')
    exact = sum((Decimal(l) for l in lines), Decimal('0.000'))
    if tender.strip().lower() == 'cash':
        r = cash(exact)
    else:
        r = exact.quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)
    return [z(r, 2), z(abs(r - exact), 3)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression adjustment-sign 1', (['1.02', '1.00'], 'cash'), ['2.00', '-0.020']),
  ('regression adjustment-sign 2', (['2.025'], 'cash'), ['2.05', '0.025']),
  ('partial repair guard 2', (['0.99', '0.03'], 'cash'), ['1.00', '-0.020']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('control: card exact', (['1.02'], 'card'), ['1.02', '0.000']),
  ('control: twint exact', (['3.33', '4.44'], 'twint'), ['7.77', '0.000'])],
 [('regression adjustment-sign 1', (['0.99', '0.03'], 'cash'), ['1.00', '-0.020']),
  ('regression adjustment-sign 2', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('partial repair guard 1', (['-2.075'], 'cash'), ['-2.10', '-0.025']),
  ('partial repair guard 2', (['12.40', '-3.12', '0.99'], ' CASH'), ['10.25', '-0.020']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('control: card exact', (['1.02'], 'card'), ['1.02', '0.000']),
  ('control: twint exact', (['3.33', '4.44'], 'twint'), ['7.77', '0.000']),
  ('control: positive tie', (['3.00', '0.025'], 'cash'), ['3.05', '0.025'])],
 [('regression adjustment-sign 1', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('regression adjustment-sign 2', (['3.00', '0.025'], 'cash'), ['3.05', '0.025']),
  ('partial repair guard 1', (['19.47', '26.34'], 'CASH'), ['45.80', '-0.010']),
  ('partial repair guard 2', (['17.98', '8.07', '0.335', '23.38'], 'Cash'), ['49.75', '-0.015']),
  ('control: negative tie', (['-2.075'], 'cash'), ['-2.10', '-0.025']),
  ('control: voucher exact', (['7.07'], 'voucher'), ['7.07', '0.000']),
  ('control: mixed basket', (['12.40', '-3.12', '0.99'], ' CASH'), ['10.25', '-0.020']),
  ('control: round down', (['1.02', '1.00'], 'cash'), ['2.00', '-0.020'])],
 [('regression adjustment-sign 1', (['-2.075'], 'cash'), ['-2.10', '-0.025']),
  ('regression adjustment-sign 2', (['12.40', '-3.12', '0.99'], ' CASH'), ['10.25', '-0.020']),
  ('partial repair guard 1', (['-1.435'], 'Cash'), ['-1.45', '-0.015']),
  ('partial repair guard 2', (['2.955'], ' cash '), ['2.95', '-0.005']),
  ('control: round down', (['1.02', '1.00'], 'cash'), ['2.00', '-0.020']),
  ('control: round to franc', (['0.99', '0.03'], 'cash'), ['1.00', '-0.020']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020'])],
 [('regression adjustment-sign 1', (['12.71', '-2.68'], 'Cash'), ['10.05', '0.020']),
  ('regression adjustment-sign 2', (['22.99', '2.02', '4.93', '0.185'], 'twint'), ['30.13', '0.005']),
  ('partial repair guard 1', (['1.91', '-3.315'], 'card'), ['-1.41', '-0.005']),
  ('partial repair guard 2', (['4.92'], ' cash '), ['4.90', '-0.020']),
  ('control: refund', (['-1.03', '-0.99'], 'cash'), ['-2.00', '0.020']),
  ('control: refund to zero', (['-0.02'], 'Cash '), ['0.00', '0.020']),
  ('control: card exact', (['1.02'], 'card'), ['1.02', '0.000']),
  ('control: twint exact', (['3.33', '4.44'], 'twint'), ['7.77', '0.000'])]]
for label, args, expected in cases[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:
Rounding 2.02 down to 2.00 reports an adjustment of +0.02.

solve(lines, tender): lines are CHF decimal strings with up to three decimals (weight- or volume-priced items; refund lines negative). The exact total is their sum. For tender 'cash' (compared after trimming and lower-casing) the total is rounded to the nearest 0.05 with ties away from zero; every other tender ('card', 'twint', 'voucher', ...) pays the total rounded half-up to 0.01. Return [payable as a 2-decimal string, adjustment as a 3-decimal string] where adjustment = payable - exact; zeros are unsigned.

split: open-access