FA-84491 / Betting odds conversion / Open access
Dead heat for first ignored or applied to profit only · case 01
A dead-heated winner is paid as a solo winner.
ROOT CAUSE
The win part uses the full stake regardless of the dead heat.
VERIFIED REPAIR
Divide the win stake by the number of runners dead-heating.
Unsuccessful approach: Dividing only the winnings keeps the full stake and overpays.
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 += stake_cents * (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: win dead heat', (1000, '4/4', '1/4', 1, 2, 2), 2250),
('variant scenario 1', (250, '10/5', '1/4', 2, 3, 2), 375),
('variant scenario 2', (250, '19/4', '1/5', 1, 2, 1), 1925)],
[('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: win dead heat', (1000, '18/2', '1/5', 1, 5, 3), 6133),
('variant scenario 1', (100, '9/4', '1/4', 4, 5, 1), 156),
('variant scenario 2', (100, '31/5', '1/5', 4, 5, 1), 224)],
[('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: win dead heat', (1000, '23/4', '1/5', 1, 5, 2), 5525),
('variant scenario 1', (1000, '10/2', '1/5', 5, 5, 1), 2000),
('variant scenario 2', (100, '11/2', '1/5', 5, 3, 1), 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: win dead heat', (250, '20/1', '1/5', 1, 3, 2), 3875),
('variant scenario 1', (500, '5/1', '1/5', 2, 5, 2), 1000),
('variant scenario 2', (100, '16/2', '1/4', 4, 4, 1), 300)],
[('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: win dead heat', (100, '9/1', '1/4', 1, 2, 3), 550),
('variant scenario 1', (1000, '10/1', '1/4', 2, 3, 1), 3500),
('variant scenario 2', (1000, '18/5', '1/4', 5, 3, 2), 0)]]
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 | 6800 | 4300 | Failed |
| boundary dead heat for last place | 1500 | 1500 | Passed |
| regression: win dead heat | 3250 | 2250 | Failed |
| variant scenario 1 | 375 | 375 | Passed |
| variant scenario 2 | 1925 | 1925 | Passed |
SHA-256 / ff67128ad93d2e0f9ea402ec3e350ef89f186cf579a4eaed02f9adfc1b24fab0
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 += stake_cents * (1 + f / dead_heat)
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: win dead heat', (1000, '4/4', '1/4', 1, 2, 2), 2250),
('variant scenario 1', (250, '10/5', '1/4', 2, 3, 2), 375),
('variant scenario 2', (250, '19/4', '1/5', 1, 2, 1), 1925)],
[('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: win dead heat', (1000, '18/2', '1/5', 1, 5, 3), 6133),
('variant scenario 1', (100, '9/4', '1/4', 4, 5, 1), 156),
('variant scenario 2', (100, '31/5', '1/5', 4, 5, 1), 224)],
[('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: win dead heat', (1000, '23/4', '1/5', 1, 5, 2), 5525),
('variant scenario 1', (1000, '10/2', '1/5', 5, 5, 1), 2000),
('variant scenario 2', (100, '11/2', '1/5', 5, 3, 1), 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: win dead heat', (250, '20/1', '1/5', 1, 3, 2), 3875),
('variant scenario 1', (500, '5/1', '1/5', 2, 5, 2), 1000),
('variant scenario 2', (100, '16/2', '1/4', 4, 4, 1), 300)],
[('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: win dead heat', (100, '9/1', '1/4', 1, 2, 3), 550),
('variant scenario 1', (1000, '10/1', '1/4', 2, 3, 1), 3500),
('variant scenario 2', (1000, '18/5', '1/4', 5, 3, 2), 0)]]
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 | 4800 | 4300 | Failed |
| boundary dead heat for last place | 1500 | 1500 | Passed |
| regression: win dead heat | 2750 | 2250 | Failed |
| variant scenario 1 | 375 | 375 | Passed |
| variant scenario 2 | 1925 | 1925 | Passed |
SHA-256 / 88fd749a285b8b782cde82c81bde12044890f15a261757d2eb1dc26bbed2e087
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: win dead heat', (1000, '4/4', '1/4', 1, 2, 2), 2250),
('variant scenario 1', (250, '10/5', '1/4', 2, 3, 2), 375),
('variant scenario 2', (250, '19/4', '1/5', 1, 2, 1), 1925)],
[('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: win dead heat', (1000, '18/2', '1/5', 1, 5, 3), 6133),
('variant scenario 1', (100, '9/4', '1/4', 4, 5, 1), 156),
('variant scenario 2', (100, '31/5', '1/5', 4, 5, 1), 224)],
[('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: win dead heat', (1000, '23/4', '1/5', 1, 5, 2), 5525),
('variant scenario 1', (1000, '10/2', '1/5', 5, 5, 1), 2000),
('variant scenario 2', (100, '11/2', '1/5', 5, 3, 1), 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: win dead heat', (250, '20/1', '1/5', 1, 3, 2), 3875),
('variant scenario 1', (500, '5/1', '1/5', 2, 5, 2), 1000),
('variant scenario 2', (100, '16/2', '1/4', 4, 4, 1), 300)],
[('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: win dead heat', (100, '9/1', '1/4', 1, 2, 3), 550),
('variant scenario 1', (1000, '10/1', '1/4', 2, 3, 1), 3500),
('variant scenario 2', (1000, '18/5', '1/4', 5, 3, 2), 0)]]
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: win dead heat | 2250 | 2250 | Passed |
| variant scenario 1 | 375 | 375 | Passed |
| variant scenario 2 | 1925 | 1925 | Passed |
SHA-256 / d057efaa8d451e828880cd52f0d3c02d608944fd11722cf36383edda439f2082
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.311949+00:00.
Case digest / 16e3f393b8958ddd10d001f7c12dbf71de501d1830afb46146c966da18978cc1