FA-69296 / Tide and marine navigation tables / Open access
Deviation card interpolation: Headings past the last card entry have no deviation · case 01
Headings between the last card heading and 360 return nothing.
ROOT CAUSE
The wrap-around point first+360 is never appended to the card.
VERIFIED REPAIR
Append the first card point shifted by 360 degrees.
Unsuccessful approach: Appending a flat point at 360 with the last deviation ignores the first card value.
Case contract
Input [heading, card]: card lists [compass heading, deviation] pairs (east positive) in any order. Headings wrap modulo 360; deviation is linearly interpolated between neighbouring card headings, including across the 360/0 seam. Return deviation rounded to 2 decimals.
Why this case matters
Tide tables and passage plans turn published predictions into go/no-go decisions about depth, clearance and timing.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
hdg,card=x
pts=sorted(card)
first=pts[0][0]
t=hdg%360
if t<first: t+=360
pass
for k in range(len(pts)-1):
h0,d0=pts[k]; h1,d1=pts[k+1]
if h0<=t<h1:
return round(d0+(d1-d0)*(t-h0)/(h1-h0),2)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('deviation card interpolation [330, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [330, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 1.67), ('deviation card interpolation [0, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [0, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 2.0), ('deviation card interpolation [20, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [20, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 2.67), ('deviation card interpolation [90, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [90, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 1.0), ('deviation card interpolation [100, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [100, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 0.44), ('deviation card interpolation [200, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [200, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], -2.56), ('deviation card interpolation [359, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [359, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 1.99)], [('deviation card interpolation [359, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [359, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 1.99), ('deviation card interpolation [100, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [100, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 0.44), ('deviation card interpolation [200, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [200, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], -2.56), ('deviation card interpolation [330, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [330, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 1.67), ('deviation card interpolation [360, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [360, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 2.0), ('deviation card interpolation [-30, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [-30, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 1.67), ('deviation card interpolation [725, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [725, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 2.17)], [('deviation card interpolation [-30, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [-30, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 1.67), ('deviation card interpolation [359, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [359, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 1.99), ('deviation card interpolation [360, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [360, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 2.0), ('deviation card interpolation [725, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [725, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 2.17), ('deviation card interpolation [5, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [5, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], 0.83), ('deviation card interpolation [15, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [15, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], 1.0), ('deviation card interpolation [50, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [50, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], 1.88)], [('deviation card interpolation [5, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [5, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], 0.83), ('deviation card interpolation [725, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [725, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 2.17), ('deviation card interpolation [15, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [15, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], 1.0), ('deviation card interpolation [50, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [50, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], 1.88), ('deviation card interpolation [150, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [150, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], -0.94), ('deviation card interpolation [300, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [300, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], -0.25), ('deviation card interpolation [350, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [350, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], 0.58)], [('deviation card interpolation [300, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [300, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], -0.25), ('deviation card interpolation [50, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [50, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], 1.88), ('deviation card interpolation [150, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [150, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], -0.94), ('deviation card interpolation [350, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [350, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], 0.58), ('deviation card interpolation [60, [[315, 1.5], [270, 0.5], [225, -2.0], [180, -3.0], [135, -1.5], [90, 1.0], [45, 3.5], [0, 2.0]]]', [60, [[315, 1.5], [270, 0.5], [225, -2.0], [180, -3.0], [135, -1.5], [90, 1.0], [45, 3.5], [0, 2.0]]], 2.67), ('deviation card interpolation [250, [[315, 1.5], [270, 0.5], [225, -2.0], [180, -3.0], [135, -1.5], [90, 1.0], [45, 3.5], [0, 2.0]]]', [250, [[315, 1.5], [270, 0.5], [225, -2.0], [180, -3.0], [135, -1.5], [90, 1.0], [45, 3.5], [0, 2.0]]], -0.61), ('deviation card interpolation [30, [[90, 1.0], [0, 0.0], [270, -1.0], [180, 2.0]]]', [30, [[90, 1.0], [0, 0.0], [270, -1.0], [180, 2.0]]], 0.33)]]
for label, args, expected in fixtures[N-1]:
check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| deviation card interpolation [330, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]] | None | 1.67 | Failed |
| deviation card interpolation [0, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]] | 2.0 | 2.0 | Passed |
| deviation card interpolation [20, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]] | 2.67 | 2.67 | Passed |
| deviation card interpolation [90, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]] | 1.0 | 1.0 | Passed |
| deviation card interpolation [100, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]] | 0.44 | 0.44 | Passed |
| deviation card interpolation [200, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]] | -2.56 | -2.56 | Passed |
| deviation card interpolation [359, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]] | None | 1.99 | Failed |
SHA-256 / bea743742568b953db5b4a6b6d236aad0c1849d338e4869cd34462d9a833a92d
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
hdg,card=x
pts=sorted(card)
first=pts[0][0]
t=hdg%360
if t<first: t+=360
pts.append([360,pts[-1][1]])
for k in range(len(pts)-1):
h0,d0=pts[k]; h1,d1=pts[k+1]
if h0<=t<h1:
return round(d0+(d1-d0)*(t-h0)/(h1-h0),2)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('deviation card interpolation [330, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [330, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 1.67), ('deviation card interpolation [0, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [0, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 2.0), ('deviation card interpolation [20, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [20, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 2.67), ('deviation card interpolation [90, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [90, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 1.0), ('deviation card interpolation [100, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [100, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 0.44), ('deviation card interpolation [200, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [200, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], -2.56), ('deviation card interpolation [359, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [359, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 1.99)], [('deviation card interpolation [359, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [359, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 1.99), ('deviation card interpolation [100, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [100, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 0.44), ('deviation card interpolation [200, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [200, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], -2.56), ('deviation card interpolation [330, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [330, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 1.67), ('deviation card interpolation [360, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [360, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 2.0), ('deviation card interpolation [-30, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [-30, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 1.67), ('deviation card interpolation [725, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [725, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 2.17)], [('deviation card interpolation [-30, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [-30, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 1.67), ('deviation card interpolation [359, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [359, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 1.99), ('deviation card interpolation [360, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [360, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 2.0), ('deviation card interpolation [725, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [725, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 2.17), ('deviation card interpolation [5, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [5, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], 0.83), ('deviation card interpolation [15, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [15, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], 1.0), ('deviation card interpolation [50, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [50, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], 1.88)], [('deviation card interpolation [5, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [5, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], 0.83), ('deviation card interpolation [725, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [725, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 2.17), ('deviation card interpolation [15, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [15, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], 1.0), ('deviation card interpolation [50, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [50, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], 1.88), ('deviation card interpolation [150, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [150, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], -0.94), ('deviation card interpolation [300, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [300, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], -0.25), ('deviation card interpolation [350, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [350, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], 0.58)], [('deviation card interpolation [300, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [300, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], -0.25), ('deviation card interpolation [50, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [50, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], 1.88), ('deviation card interpolation [150, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [150, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], -0.94), ('deviation card interpolation [350, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [350, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], 0.58), ('deviation card interpolation [60, [[315, 1.5], [270, 0.5], [225, -2.0], [180, -3.0], [135, -1.5], [90, 1.0], [45, 3.5], [0, 2.0]]]', [60, [[315, 1.5], [270, 0.5], [225, -2.0], [180, -3.0], [135, -1.5], [90, 1.0], [45, 3.5], [0, 2.0]]], 2.67), ('deviation card interpolation [250, [[315, 1.5], [270, 0.5], [225, -2.0], [180, -3.0], [135, -1.5], [90, 1.0], [45, 3.5], [0, 2.0]]]', [250, [[315, 1.5], [270, 0.5], [225, -2.0], [180, -3.0], [135, -1.5], [90, 1.0], [45, 3.5], [0, 2.0]]], -0.61), ('deviation card interpolation [30, [[90, 1.0], [0, 0.0], [270, -1.0], [180, 2.0]]]', [30, [[90, 1.0], [0, 0.0], [270, -1.0], [180, 2.0]]], 0.33)]]
for label, args, expected in fixtures[N-1]:
check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| deviation card interpolation [330, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]] | 1.5 | 1.67 | Failed |
| deviation card interpolation [0, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]] | 2.0 | 2.0 | Passed |
| deviation card interpolation [20, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]] | 2.67 | 2.67 | Passed |
| deviation card interpolation [90, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]] | 1.0 | 1.0 | Passed |
| deviation card interpolation [100, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]] | 0.44 | 0.44 | Passed |
| deviation card interpolation [200, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]] | -2.56 | -2.56 | Passed |
| deviation card interpolation [359, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]] | 1.5 | 1.99 | Failed |
SHA-256 / ed63b23c9aa4d4da66840cbcbdd53cf6e82a43233d0e4c2b82d7a4e7df6817b9
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
hdg,card=x
pts=sorted(card)
first=pts[0][0]
t=hdg%360
if t<first: t+=360
pts.append([first+360,pts[0][1]])
for k in range(len(pts)-1):
h0,d0=pts[k]; h1,d1=pts[k+1]
if h0<=t<h1:
return round(d0+(d1-d0)*(t-h0)/(h1-h0),2)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('deviation card interpolation [330, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [330, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 1.67), ('deviation card interpolation [0, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [0, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 2.0), ('deviation card interpolation [20, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [20, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 2.67), ('deviation card interpolation [90, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [90, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 1.0), ('deviation card interpolation [100, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [100, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 0.44), ('deviation card interpolation [200, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [200, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], -2.56), ('deviation card interpolation [359, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [359, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 1.99)], [('deviation card interpolation [359, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [359, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 1.99), ('deviation card interpolation [100, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [100, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 0.44), ('deviation card interpolation [200, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [200, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], -2.56), ('deviation card interpolation [330, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [330, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 1.67), ('deviation card interpolation [360, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [360, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 2.0), ('deviation card interpolation [-30, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [-30, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 1.67), ('deviation card interpolation [725, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [725, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 2.17)], [('deviation card interpolation [-30, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [-30, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 1.67), ('deviation card interpolation [359, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [359, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 1.99), ('deviation card interpolation [360, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [360, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 2.0), ('deviation card interpolation [725, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [725, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 2.17), ('deviation card interpolation [5, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [5, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], 0.83), ('deviation card interpolation [15, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [15, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], 1.0), ('deviation card interpolation [50, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [50, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], 1.88)], [('deviation card interpolation [5, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [5, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], 0.83), ('deviation card interpolation [725, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]]', [725, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]], 2.17), ('deviation card interpolation [15, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [15, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], 1.0), ('deviation card interpolation [50, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [50, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], 1.88), ('deviation card interpolation [150, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [150, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], -0.94), ('deviation card interpolation [300, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [300, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], -0.25), ('deviation card interpolation [350, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [350, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], 0.58)], [('deviation card interpolation [300, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [300, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], -0.25), ('deviation card interpolation [50, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [50, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], 1.88), ('deviation card interpolation [150, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [150, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], -0.94), ('deviation card interpolation [350, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]]', [350, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]], 0.58), ('deviation card interpolation [60, [[315, 1.5], [270, 0.5], [225, -2.0], [180, -3.0], [135, -1.5], [90, 1.0], [45, 3.5], [0, 2.0]]]', [60, [[315, 1.5], [270, 0.5], [225, -2.0], [180, -3.0], [135, -1.5], [90, 1.0], [45, 3.5], [0, 2.0]]], 2.67), ('deviation card interpolation [250, [[315, 1.5], [270, 0.5], [225, -2.0], [180, -3.0], [135, -1.5], [90, 1.0], [45, 3.5], [0, 2.0]]]', [250, [[315, 1.5], [270, 0.5], [225, -2.0], [180, -3.0], [135, -1.5], [90, 1.0], [45, 3.5], [0, 2.0]]], -0.61), ('deviation card interpolation [30, [[90, 1.0], [0, 0.0], [270, -1.0], [180, 2.0]]]', [30, [[90, 1.0], [0, 0.0], [270, -1.0], [180, 2.0]]], 0.33)]]
for label, args, expected in fixtures[N-1]:
check(label, solve(args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| deviation card interpolation [330, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]] | 1.67 | 1.67 | Passed |
| deviation card interpolation [0, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]] | 2.0 | 2.0 | Passed |
| deviation card interpolation [20, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]] | 2.67 | 2.67 | Passed |
| deviation card interpolation [90, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]] | 1.0 | 1.0 | Passed |
| deviation card interpolation [100, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]] | 0.44 | 0.44 | Passed |
| deviation card interpolation [200, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]] | -2.56 | -2.56 | Passed |
| deviation card interpolation [359, [[0, 2.0], [45, 3.5], [90, 1.0], [135, -1.5], [180, -3.0], [225, -2.0], [270, 0.5], [315, 1.5]]] | 1.99 | 1.99 | Passed |
SHA-256 / ad5f5d29fa82b3a549228b02dc3da2436fca14703114c652ee498da133d21d65
Verification & scope
A deterministic toy model with stipulated rules and constants; not certified hydrographic software or a substitute for official tide tables. 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:48:10.054969+00:00.
Case digest / 98d1b5ace637e5152d878e420536bab9eec6798fe245fd3d69d01574cd748136