FA-84501 / Betting odds conversion / Open access
Winner excluded from the place part or last place unpaid · case 01
The winner of an each-way bet receives only the win part, or the last paying place is missed.
ROOT CAUSE
The place condition uses position < places_paid.
VERIFIED REPAIR
Pay the place part for any position up to and including places_paid.
Unsuccessful approach: Excluding the winner from the place part misreads each-way as win-or-place.
Case contract
Each-way settlement with dead heats. stake_cents is the stake of each part (win and place). odds is fractional "a/b"; terms "1/4" or "1/5" is the place fraction of the odds. position is the finishing position shared by dead_heat runners (1 = no dead heat), occupying positions position .. position + dead_heat - 1. Win part: paid if position == 1 with stake / dead_heat at 1 + a/b. Place part: paid if position <= places_paid, with stake scaled by min(dead_heat, places_paid - position + 1) / dead_heat at 1 + (a/b) * terms. Return the total return in cents rounded down.
Why this case matters
Horse-racing settlement applies place terms and dead-heat reductions to each part separately.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
import math
N = 1
observations = []
def solve(stake_cents, odds, terms, position, places_paid, dead_heat):
a, b = map(int, odds.split('/'))
f = Fraction(a, b)
tn, td = map(int, terms.split('/'))
place_f = f * Fraction(tn, td)
ret = Fraction(0)
if position == 1:
ret += Fraction(stake_cents, dead_heat) * (1 + f)
if position < places_paid:
share = Fraction(min(dead_heat, places_paid - position + 1), dead_heat)
ret += stake_cents * share * (1 + place_f)
return math.floor(ret)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
def run(args):
try:
return solve(*args)
except Exception as exc:
return 'raised ' + type(exc).__name__
cases = [[('control winner', (1000, '4/1', '1/4', 1, 3, 1), 7000),
('control placed', (1000, '4/1', '1/4', 2, 3, 1), 2000),
('control unplaced', (1000, '4/1', '1/4', 4, 3, 1), 0),
('boundary dead heat for the win', (1000, '4/1', '1/5', 1, 3, 2), 4300),
('boundary dead heat for last place', (1000, '10/1', '1/5', 3, 3, 2), 1500),
('regression: place eligibility', (250, '14/2', '1/5', 1, 4, 2), 1600),
('regression: place eligibility', (1000, '1/5', '1/4', 2, 2, 3), 350),
('variant scenario 1', (250, '2/5', '1/4', 3, 4, 3), 183),
('variant scenario 2', (100, '27/1', '1/5', 1, 4, 2), 2040)],
[('control winner', (1000, '4/1', '1/4', 1, 3, 1), 7000),
('control placed', (1000, '4/1', '1/4', 2, 3, 1), 2000),
('control unplaced', (1000, '4/1', '1/4', 4, 3, 1), 0),
('boundary dead heat for the win', (1000, '4/1', '1/5', 1, 3, 2), 4300),
('boundary dead heat for last place', (1000, '10/1', '1/5', 3, 3, 2), 1500),
('regression: place eligibility', (250, '16/1', '1/5', 1, 2, 1), 5300),
('regression: place eligibility', (250, '17/1', '1/5', 3, 3, 2), 550),
('variant scenario 1', (250, '19/2', '1/5', 2, 5, 2), 725),
('variant scenario 2', (250, '21/5', '1/5', 2, 5, 3), 460)],
[('control winner', (1000, '4/1', '1/4', 1, 3, 1), 7000),
('control placed', (1000, '4/1', '1/4', 2, 3, 1), 2000),
('control unplaced', (1000, '4/1', '1/4', 4, 3, 1), 0),
('boundary dead heat for the win', (1000, '4/1', '1/5', 1, 3, 2), 4300),
('boundary dead heat for last place', (1000, '10/1', '1/5', 3, 3, 2), 1500),
('regression: place eligibility', (250, '10/2', '1/4', 1, 3, 1), 2062),
('regression: place eligibility', (1000, '1/1', '1/4', 2, 2, 2), 625),
('variant scenario 1', (100, '24/1', '1/4', 3, 2, 3), 0),
('variant scenario 2', (100, '2/2', '1/5', 4, 3, 2), 0)],
[('control winner', (1000, '4/1', '1/4', 1, 3, 1), 7000),
('control placed', (1000, '4/1', '1/4', 2, 3, 1), 2000),
('control unplaced', (1000, '4/1', '1/4', 4, 3, 1), 0),
('boundary dead heat for the win', (1000, '4/1', '1/5', 1, 3, 2), 4300),
('boundary dead heat for last place', (1000, '10/1', '1/5', 3, 3, 2), 1500),
('regression: place eligibility', (500, '18/1', '1/5', 1, 4, 2), 7050),
('regression: place eligibility', (250, '11/1', '1/5', 3, 3, 1), 800),
('variant scenario 1', (250, '28/5', '1/4', 3, 2, 1), 0),
('variant scenario 2', (250, '31/4', '1/5', 2, 4, 3), 637)],
[('control winner', (1000, '4/1', '1/4', 1, 3, 1), 7000),
('control placed', (1000, '4/1', '1/4', 2, 3, 1), 2000),
('control unplaced', (1000, '4/1', '1/4', 4, 3, 1), 0),
('boundary dead heat for the win', (1000, '4/1', '1/5', 1, 3, 2), 4300),
('boundary dead heat for last place', (1000, '10/1', '1/5', 3, 3, 2), 1500),
('regression: place eligibility', (1000, '15/2', '1/5', 1, 4, 3), 5333),
('regression: place eligibility', (250, '29/1', '1/5', 2, 2, 1), 1700),
('variant scenario 1', (500, '19/5', '1/5', 2, 4, 1), 880),
('variant scenario 2', (500, '33/1', '1/4', 3, 5, 3), 4625)]]
for label, args, expected in cases[N - 1]:
check(label, run(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| control winner | 7000 | 7000 | Passed |
| control placed | 2000 | 2000 | Passed |
| control unplaced | 0 | 0 | Passed |
| boundary dead heat for the win | 4300 | 4300 | Passed |
| boundary dead heat for last place | 0 | 1500 | Failed |
| regression: place eligibility | 1600 | 1600 | Passed |
| regression: place eligibility | 0 | 350 | Failed |
| variant scenario 1 | 183 | 183 | Passed |
| variant scenario 2 | 2040 | 2040 | Passed |
SHA-256 / 9e1783677dc83edbe15b7b2894bf33e328fbac01774ceb855d79f4e3671132e7
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
import math
N = 1
observations = []
def solve(stake_cents, odds, terms, position, places_paid, dead_heat):
a, b = map(int, odds.split('/'))
f = Fraction(a, b)
tn, td = map(int, terms.split('/'))
place_f = f * Fraction(tn, td)
ret = Fraction(0)
if position == 1:
ret += Fraction(stake_cents, dead_heat) * (1 + f)
if 1 < position <= places_paid:
share = Fraction(min(dead_heat, places_paid - position + 1), dead_heat)
ret += stake_cents * share * (1 + place_f)
return math.floor(ret)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
def run(args):
try:
return solve(*args)
except Exception as exc:
return 'raised ' + type(exc).__name__
cases = [[('control winner', (1000, '4/1', '1/4', 1, 3, 1), 7000),
('control placed', (1000, '4/1', '1/4', 2, 3, 1), 2000),
('control unplaced', (1000, '4/1', '1/4', 4, 3, 1), 0),
('boundary dead heat for the win', (1000, '4/1', '1/5', 1, 3, 2), 4300),
('boundary dead heat for last place', (1000, '10/1', '1/5', 3, 3, 2), 1500),
('regression: place eligibility', (250, '14/2', '1/5', 1, 4, 2), 1600),
('regression: place eligibility', (1000, '1/5', '1/4', 2, 2, 3), 350),
('variant scenario 1', (250, '2/5', '1/4', 3, 4, 3), 183),
('variant scenario 2', (100, '27/1', '1/5', 1, 4, 2), 2040)],
[('control winner', (1000, '4/1', '1/4', 1, 3, 1), 7000),
('control placed', (1000, '4/1', '1/4', 2, 3, 1), 2000),
('control unplaced', (1000, '4/1', '1/4', 4, 3, 1), 0),
('boundary dead heat for the win', (1000, '4/1', '1/5', 1, 3, 2), 4300),
('boundary dead heat for last place', (1000, '10/1', '1/5', 3, 3, 2), 1500),
('regression: place eligibility', (250, '16/1', '1/5', 1, 2, 1), 5300),
('regression: place eligibility', (250, '17/1', '1/5', 3, 3, 2), 550),
('variant scenario 1', (250, '19/2', '1/5', 2, 5, 2), 725),
('variant scenario 2', (250, '21/5', '1/5', 2, 5, 3), 460)],
[('control winner', (1000, '4/1', '1/4', 1, 3, 1), 7000),
('control placed', (1000, '4/1', '1/4', 2, 3, 1), 2000),
('control unplaced', (1000, '4/1', '1/4', 4, 3, 1), 0),
('boundary dead heat for the win', (1000, '4/1', '1/5', 1, 3, 2), 4300),
('boundary dead heat for last place', (1000, '10/1', '1/5', 3, 3, 2), 1500),
('regression: place eligibility', (250, '10/2', '1/4', 1, 3, 1), 2062),
('regression: place eligibility', (1000, '1/1', '1/4', 2, 2, 2), 625),
('variant scenario 1', (100, '24/1', '1/4', 3, 2, 3), 0),
('variant scenario 2', (100, '2/2', '1/5', 4, 3, 2), 0)],
[('control winner', (1000, '4/1', '1/4', 1, 3, 1), 7000),
('control placed', (1000, '4/1', '1/4', 2, 3, 1), 2000),
('control unplaced', (1000, '4/1', '1/4', 4, 3, 1), 0),
('boundary dead heat for the win', (1000, '4/1', '1/5', 1, 3, 2), 4300),
('boundary dead heat for last place', (1000, '10/1', '1/5', 3, 3, 2), 1500),
('regression: place eligibility', (500, '18/1', '1/5', 1, 4, 2), 7050),
('regression: place eligibility', (250, '11/1', '1/5', 3, 3, 1), 800),
('variant scenario 1', (250, '28/5', '1/4', 3, 2, 1), 0),
('variant scenario 2', (250, '31/4', '1/5', 2, 4, 3), 637)],
[('control winner', (1000, '4/1', '1/4', 1, 3, 1), 7000),
('control placed', (1000, '4/1', '1/4', 2, 3, 1), 2000),
('control unplaced', (1000, '4/1', '1/4', 4, 3, 1), 0),
('boundary dead heat for the win', (1000, '4/1', '1/5', 1, 3, 2), 4300),
('boundary dead heat for last place', (1000, '10/1', '1/5', 3, 3, 2), 1500),
('regression: place eligibility', (1000, '15/2', '1/5', 1, 4, 3), 5333),
('regression: place eligibility', (250, '29/1', '1/5', 2, 2, 1), 1700),
('variant scenario 1', (500, '19/5', '1/5', 2, 4, 1), 880),
('variant scenario 2', (500, '33/1', '1/4', 3, 5, 3), 4625)]]
for label, args, expected in cases[N - 1]:
check(label, run(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| control winner | 5000 | 7000 | Failed |
| control placed | 2000 | 2000 | Passed |
| control unplaced | 0 | 0 | Passed |
| boundary dead heat for the win | 2500 | 4300 | Failed |
| boundary dead heat for last place | 1500 | 1500 | Passed |
| regression: place eligibility | 1000 | 1600 | Failed |
| regression: place eligibility | 350 | 350 | Passed |
| variant scenario 1 | 183 | 183 | Passed |
| variant scenario 2 | 1400 | 2040 | Failed |
SHA-256 / e0246cd78f36c0951efe83f18206c3530b52d75e4cdb16bb61017f262b4359f9
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
import math
N = 1
observations = []
def solve(stake_cents, odds, terms, position, places_paid, dead_heat):
a, b = map(int, odds.split('/'))
f = Fraction(a, b)
tn, td = map(int, terms.split('/'))
place_f = f * Fraction(tn, td)
ret = Fraction(0)
if position == 1:
ret += Fraction(stake_cents, dead_heat) * (1 + f)
if position <= places_paid:
share = Fraction(min(dead_heat, places_paid - position + 1), dead_heat)
ret += stake_cents * share * (1 + place_f)
return math.floor(ret)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
def run(args):
try:
return solve(*args)
except Exception as exc:
return 'raised ' + type(exc).__name__
cases = [[('control winner', (1000, '4/1', '1/4', 1, 3, 1), 7000),
('control placed', (1000, '4/1', '1/4', 2, 3, 1), 2000),
('control unplaced', (1000, '4/1', '1/4', 4, 3, 1), 0),
('boundary dead heat for the win', (1000, '4/1', '1/5', 1, 3, 2), 4300),
('boundary dead heat for last place', (1000, '10/1', '1/5', 3, 3, 2), 1500),
('regression: place eligibility', (250, '14/2', '1/5', 1, 4, 2), 1600),
('regression: place eligibility', (1000, '1/5', '1/4', 2, 2, 3), 350),
('variant scenario 1', (250, '2/5', '1/4', 3, 4, 3), 183),
('variant scenario 2', (100, '27/1', '1/5', 1, 4, 2), 2040)],
[('control winner', (1000, '4/1', '1/4', 1, 3, 1), 7000),
('control placed', (1000, '4/1', '1/4', 2, 3, 1), 2000),
('control unplaced', (1000, '4/1', '1/4', 4, 3, 1), 0),
('boundary dead heat for the win', (1000, '4/1', '1/5', 1, 3, 2), 4300),
('boundary dead heat for last place', (1000, '10/1', '1/5', 3, 3, 2), 1500),
('regression: place eligibility', (250, '16/1', '1/5', 1, 2, 1), 5300),
('regression: place eligibility', (250, '17/1', '1/5', 3, 3, 2), 550),
('variant scenario 1', (250, '19/2', '1/5', 2, 5, 2), 725),
('variant scenario 2', (250, '21/5', '1/5', 2, 5, 3), 460)],
[('control winner', (1000, '4/1', '1/4', 1, 3, 1), 7000),
('control placed', (1000, '4/1', '1/4', 2, 3, 1), 2000),
('control unplaced', (1000, '4/1', '1/4', 4, 3, 1), 0),
('boundary dead heat for the win', (1000, '4/1', '1/5', 1, 3, 2), 4300),
('boundary dead heat for last place', (1000, '10/1', '1/5', 3, 3, 2), 1500),
('regression: place eligibility', (250, '10/2', '1/4', 1, 3, 1), 2062),
('regression: place eligibility', (1000, '1/1', '1/4', 2, 2, 2), 625),
('variant scenario 1', (100, '24/1', '1/4', 3, 2, 3), 0),
('variant scenario 2', (100, '2/2', '1/5', 4, 3, 2), 0)],
[('control winner', (1000, '4/1', '1/4', 1, 3, 1), 7000),
('control placed', (1000, '4/1', '1/4', 2, 3, 1), 2000),
('control unplaced', (1000, '4/1', '1/4', 4, 3, 1), 0),
('boundary dead heat for the win', (1000, '4/1', '1/5', 1, 3, 2), 4300),
('boundary dead heat for last place', (1000, '10/1', '1/5', 3, 3, 2), 1500),
('regression: place eligibility', (500, '18/1', '1/5', 1, 4, 2), 7050),
('regression: place eligibility', (250, '11/1', '1/5', 3, 3, 1), 800),
('variant scenario 1', (250, '28/5', '1/4', 3, 2, 1), 0),
('variant scenario 2', (250, '31/4', '1/5', 2, 4, 3), 637)],
[('control winner', (1000, '4/1', '1/4', 1, 3, 1), 7000),
('control placed', (1000, '4/1', '1/4', 2, 3, 1), 2000),
('control unplaced', (1000, '4/1', '1/4', 4, 3, 1), 0),
('boundary dead heat for the win', (1000, '4/1', '1/5', 1, 3, 2), 4300),
('boundary dead heat for last place', (1000, '10/1', '1/5', 3, 3, 2), 1500),
('regression: place eligibility', (1000, '15/2', '1/5', 1, 4, 3), 5333),
('regression: place eligibility', (250, '29/1', '1/5', 2, 2, 1), 1700),
('variant scenario 1', (500, '19/5', '1/5', 2, 4, 1), 880),
('variant scenario 2', (500, '33/1', '1/4', 3, 5, 3), 4625)]]
for label, args, expected in cases[N - 1]:
check(label, run(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| control winner | 7000 | 7000 | Passed |
| control placed | 2000 | 2000 | Passed |
| control unplaced | 0 | 0 | Passed |
| boundary dead heat for the win | 4300 | 4300 | Passed |
| boundary dead heat for last place | 1500 | 1500 | Passed |
| regression: place eligibility | 1600 | 1600 | Passed |
| regression: place eligibility | 350 | 350 | Passed |
| variant scenario 1 | 183 | 183 | Passed |
| variant scenario 2 | 2040 | 2040 | Passed |
SHA-256 / f82fae75f3a978ea4cd5afcf5fcf56e8ed9d8c802b4c1bc8e7891db2d03b60dc
Verification & scope
Stipulated, bounded toy contract stated in the contract field; not a claim of conformance with any operator, exchange or regulator rule set. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:50:31.573400+00:00.
Case digest / 8c79f6b300b665c80585b3abecd9cc6448c8edfe9be2bd65a31e1e7894cf1b52