FA-69301 / Tide and marine navigation tables / Open access
Deviation card interpolation: Headings before the first card entry are not shifted · case 01
A card starting at 015 returns nothing for headings 000-014.
ROOT CAUSE
Headings below the first card heading are not moved into the seam segment.
VERIFIED REPAIR
Add 360 to headings below the first card heading.
Unsuccessful approach: Clamping to the first card heading returns its deviation instead of interpolating across the seam.
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
pass
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 [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 [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 [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 [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 [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 [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 [-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 [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 [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 [-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 [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 [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 [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 [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)]]
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 [5, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]] | None | 0.83 | 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 [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 |
SHA-256 / c8b539c053f0c6da397dda4a5590a34a33352991664d1e6634dc841cdac1872a
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
t=max(t,first)
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 [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 [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 [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 [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 [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 [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 [-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 [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 [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 [-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 [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 [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 [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 [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)]]
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 [5, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]] | 1.0 | 0.83 | 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 [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 |
SHA-256 / 862d0d120685438ec9882cba82466345d0ba8f3214aeca6324b519e26d96ac95
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 [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 [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 [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 [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 [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 [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 [-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 [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 [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 [-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 [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 [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 [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 [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)]]
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 [5, [[15, 1.0], [75, 2.5], [120, 0.0], [200, -2.5], [285, -0.5]]] | 0.83 | 0.83 | 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 [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 |
SHA-256 / 899792e5c4d7b84793f1262d7f1e84520130217e878353d875bdc2bcd91083b7
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.145657+00:00.
Case digest / 42da4968e3484f9b1e8d3efd4556d6095af7731b45b6da31edc00bcb2a1dd115