FA-68911 / Tide and marine navigation tables / Open access
Cosine curve time for height: Duration of rise is doubled as a full tidal cycle · case 01
Computed times fall far beyond the second turning point.
ROOT CAUSE
The cosine period is treated as the full cycle 2*(t2-t1) rather than the half-cycle between turning points.
VERIFIED REPAIR
Use T=t2-t1 as the half period.
Unsuccessful approach: Using the full cycle but halving the angle compensates only at mid-tide.
Case contract
Input [t1,h1,t2,h2,h] (hours, metres) for consecutive turning points with t2>t1 and h1!=h2. Height follows h1+(h2-h1)*(1-cos(pi*s/T))/2 with s elapsed and T=t2-t1. Return the time in whole minutes (rounded half up) when the height h is first reached on that half-cycle, or None when h lies outside the closed range of h1..h2.
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):
t1,h1,t2,h2,h=x
lo,hi=min(h1,h2),max(h1,h2)
if h<lo or h>hi: return None
frac=(h-h1)/(h2-h1)
T=2*(t2-t1)
s=T*math.acos(1-2*frac)/math.pi
return math.floor((t1+s)*60+0.5)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('cosine curve time for height [0, 0.6, 6.2, 4.4, 1.0]', [0, 0.6, 6.2, 4.4, 1.0], 78), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 0.6]', [0, 0.6, 6.2, 4.4, 0.6], 0), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 2.5]', [0, 0.6, 6.2, 4.4, 2.5], 186), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 3.9]', [0, 0.6, 6.2, 4.4, 3.9], 284), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 4.4]', [0, 0.6, 6.2, 4.4, 4.4], 372), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 4.5]', [0, 0.6, 6.2, 4.4, 4.5], None), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 5.1]', [3.5, 5.1, 9.75, 1.2, 5.1], 210)], [('cosine curve time for height [0, 0.6, 6.2, 4.4, 2.5]', [0, 0.6, 6.2, 4.4, 2.5], 186), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 3.9]', [0, 0.6, 6.2, 4.4, 3.9], 284), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 4.4]', [0, 0.6, 6.2, 4.4, 4.4], 372), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 4.5]', [0, 0.6, 6.2, 4.4, 4.5], None), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 5.1]', [3.5, 5.1, 9.75, 1.2, 5.1], 210), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 4.0]', [3.5, 5.1, 9.75, 1.2, 4.0], 344), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 3.15]', [3.5, 5.1, 9.75, 1.2, 3.15], 398)], [('cosine curve time for height [0, 0.6, 6.2, 4.4, 3.9]', [0, 0.6, 6.2, 4.4, 3.9], 284), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 5.1]', [3.5, 5.1, 9.75, 1.2, 5.1], 210), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 4.0]', [3.5, 5.1, 9.75, 1.2, 4.0], 344), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 3.15]', [3.5, 5.1, 9.75, 1.2, 3.15], 398), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 1.3]', [3.5, 5.1, 9.75, 1.2, 1.3], 547), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 1.2]', [3.5, 5.1, 9.75, 1.2, 1.2], 585), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 0.9]', [3.5, 5.1, 9.75, 1.2, 0.9], None)], [('cosine curve time for height [0, 0.6, 6.2, 4.4, 4.4]', [0, 0.6, 6.2, 4.4, 4.4], 372), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 1.3]', [3.5, 5.1, 9.75, 1.2, 1.3], 547), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 1.2]', [3.5, 5.1, 9.75, 1.2, 1.2], 585), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 0.9]', [3.5, 5.1, 9.75, 1.2, 0.9], None), ('cosine curve time for height [10, 2.0, 22.4, 2.6, 2.3]', [10, 2.0, 22.4, 2.6, 2.3], 972), ('cosine curve time for height [0, 0, 2, 1, 0.25]', [0, 0, 2, 1, 0.25], 40), ('cosine curve time for height [1.25, 1.0, 7.25, 3.0, 2.0]', [1.25, 1.0, 7.25, 3.0, 2.0], 255)], [('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 4.0]', [3.5, 5.1, 9.75, 1.2, 4.0], 344), ('cosine curve time for height [10, 2.0, 22.4, 2.6, 2.3]', [10, 2.0, 22.4, 2.6, 2.3], 972), ('cosine curve time for height [0, 0, 2, 1, 0.25]', [0, 0, 2, 1, 0.25], 40), ('cosine curve time for height [1.25, 1.0, 7.25, 3.0, 2.0]', [1.25, 1.0, 7.25, 3.0, 2.0], 255), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 0.6]', [0, 0.6, 6.2, 4.4, 0.6], 0), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 1.0]', [0, 0.6, 6.2, 4.4, 1.0], 78), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 2.5]', [0, 0.6, 6.2, 4.4, 2.5], 186)]]
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 |
|---|---|---|---|
| cosine curve time for height [0, 0.6, 6.2, 4.4, 1.0] | 157 | 78 | Failed |
| cosine curve time for height [0, 0.6, 6.2, 4.4, 0.6] | 0 | 0 | Passed |
| cosine curve time for height [0, 0.6, 6.2, 4.4, 2.5] | 372 | 186 | Failed |
| cosine curve time for height [0, 0.6, 6.2, 4.4, 3.9] | 568 | 284 | Failed |
| cosine curve time for height [0, 0.6, 6.2, 4.4, 4.4] | 744 | 372 | Failed |
| cosine curve time for height [0, 0.6, 6.2, 4.4, 4.5] | None | None | Passed |
| cosine curve time for height [3.5, 5.1, 9.75, 1.2, 5.1] | 210 | 210 | Passed |
SHA-256 / 58c65c4eab4325395d16f7478a9a05dde869587c412f739e52b6a872f119014a
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
t1,h1,t2,h2,h=x
lo,hi=min(h1,h2),max(h1,h2)
if h<lo or h>hi: return None
frac=(h-h1)/(h2-h1)
T=(t2-t1)/2
s=T*math.acos(1-2*frac)/math.pi
return math.floor((t1+s)*60+0.5)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('cosine curve time for height [0, 0.6, 6.2, 4.4, 1.0]', [0, 0.6, 6.2, 4.4, 1.0], 78), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 0.6]', [0, 0.6, 6.2, 4.4, 0.6], 0), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 2.5]', [0, 0.6, 6.2, 4.4, 2.5], 186), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 3.9]', [0, 0.6, 6.2, 4.4, 3.9], 284), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 4.4]', [0, 0.6, 6.2, 4.4, 4.4], 372), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 4.5]', [0, 0.6, 6.2, 4.4, 4.5], None), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 5.1]', [3.5, 5.1, 9.75, 1.2, 5.1], 210)], [('cosine curve time for height [0, 0.6, 6.2, 4.4, 2.5]', [0, 0.6, 6.2, 4.4, 2.5], 186), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 3.9]', [0, 0.6, 6.2, 4.4, 3.9], 284), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 4.4]', [0, 0.6, 6.2, 4.4, 4.4], 372), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 4.5]', [0, 0.6, 6.2, 4.4, 4.5], None), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 5.1]', [3.5, 5.1, 9.75, 1.2, 5.1], 210), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 4.0]', [3.5, 5.1, 9.75, 1.2, 4.0], 344), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 3.15]', [3.5, 5.1, 9.75, 1.2, 3.15], 398)], [('cosine curve time for height [0, 0.6, 6.2, 4.4, 3.9]', [0, 0.6, 6.2, 4.4, 3.9], 284), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 5.1]', [3.5, 5.1, 9.75, 1.2, 5.1], 210), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 4.0]', [3.5, 5.1, 9.75, 1.2, 4.0], 344), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 3.15]', [3.5, 5.1, 9.75, 1.2, 3.15], 398), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 1.3]', [3.5, 5.1, 9.75, 1.2, 1.3], 547), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 1.2]', [3.5, 5.1, 9.75, 1.2, 1.2], 585), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 0.9]', [3.5, 5.1, 9.75, 1.2, 0.9], None)], [('cosine curve time for height [0, 0.6, 6.2, 4.4, 4.4]', [0, 0.6, 6.2, 4.4, 4.4], 372), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 1.3]', [3.5, 5.1, 9.75, 1.2, 1.3], 547), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 1.2]', [3.5, 5.1, 9.75, 1.2, 1.2], 585), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 0.9]', [3.5, 5.1, 9.75, 1.2, 0.9], None), ('cosine curve time for height [10, 2.0, 22.4, 2.6, 2.3]', [10, 2.0, 22.4, 2.6, 2.3], 972), ('cosine curve time for height [0, 0, 2, 1, 0.25]', [0, 0, 2, 1, 0.25], 40), ('cosine curve time for height [1.25, 1.0, 7.25, 3.0, 2.0]', [1.25, 1.0, 7.25, 3.0, 2.0], 255)], [('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 4.0]', [3.5, 5.1, 9.75, 1.2, 4.0], 344), ('cosine curve time for height [10, 2.0, 22.4, 2.6, 2.3]', [10, 2.0, 22.4, 2.6, 2.3], 972), ('cosine curve time for height [0, 0, 2, 1, 0.25]', [0, 0, 2, 1, 0.25], 40), ('cosine curve time for height [1.25, 1.0, 7.25, 3.0, 2.0]', [1.25, 1.0, 7.25, 3.0, 2.0], 255), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 0.6]', [0, 0.6, 6.2, 4.4, 0.6], 0), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 1.0]', [0, 0.6, 6.2, 4.4, 1.0], 78), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 2.5]', [0, 0.6, 6.2, 4.4, 2.5], 186)]]
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 |
|---|---|---|---|
| cosine curve time for height [0, 0.6, 6.2, 4.4, 1.0] | 39 | 78 | Failed |
| cosine curve time for height [0, 0.6, 6.2, 4.4, 0.6] | 0 | 0 | Passed |
| cosine curve time for height [0, 0.6, 6.2, 4.4, 2.5] | 93 | 186 | Failed |
| cosine curve time for height [0, 0.6, 6.2, 4.4, 3.9] | 142 | 284 | Failed |
| cosine curve time for height [0, 0.6, 6.2, 4.4, 4.4] | 186 | 372 | Failed |
| cosine curve time for height [0, 0.6, 6.2, 4.4, 4.5] | None | None | Passed |
| cosine curve time for height [3.5, 5.1, 9.75, 1.2, 5.1] | 210 | 210 | Passed |
SHA-256 / 6607306e4c765e2ef366a6920badae8f215b08f5403a0ea9320457628b64601b
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
t1,h1,t2,h2,h=x
lo,hi=min(h1,h2),max(h1,h2)
if h<lo or h>hi: return None
frac=(h-h1)/(h2-h1)
T=t2-t1
s=T*math.acos(1-2*frac)/math.pi
return math.floor((t1+s)*60+0.5)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('cosine curve time for height [0, 0.6, 6.2, 4.4, 1.0]', [0, 0.6, 6.2, 4.4, 1.0], 78), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 0.6]', [0, 0.6, 6.2, 4.4, 0.6], 0), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 2.5]', [0, 0.6, 6.2, 4.4, 2.5], 186), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 3.9]', [0, 0.6, 6.2, 4.4, 3.9], 284), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 4.4]', [0, 0.6, 6.2, 4.4, 4.4], 372), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 4.5]', [0, 0.6, 6.2, 4.4, 4.5], None), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 5.1]', [3.5, 5.1, 9.75, 1.2, 5.1], 210)], [('cosine curve time for height [0, 0.6, 6.2, 4.4, 2.5]', [0, 0.6, 6.2, 4.4, 2.5], 186), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 3.9]', [0, 0.6, 6.2, 4.4, 3.9], 284), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 4.4]', [0, 0.6, 6.2, 4.4, 4.4], 372), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 4.5]', [0, 0.6, 6.2, 4.4, 4.5], None), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 5.1]', [3.5, 5.1, 9.75, 1.2, 5.1], 210), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 4.0]', [3.5, 5.1, 9.75, 1.2, 4.0], 344), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 3.15]', [3.5, 5.1, 9.75, 1.2, 3.15], 398)], [('cosine curve time for height [0, 0.6, 6.2, 4.4, 3.9]', [0, 0.6, 6.2, 4.4, 3.9], 284), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 5.1]', [3.5, 5.1, 9.75, 1.2, 5.1], 210), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 4.0]', [3.5, 5.1, 9.75, 1.2, 4.0], 344), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 3.15]', [3.5, 5.1, 9.75, 1.2, 3.15], 398), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 1.3]', [3.5, 5.1, 9.75, 1.2, 1.3], 547), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 1.2]', [3.5, 5.1, 9.75, 1.2, 1.2], 585), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 0.9]', [3.5, 5.1, 9.75, 1.2, 0.9], None)], [('cosine curve time for height [0, 0.6, 6.2, 4.4, 4.4]', [0, 0.6, 6.2, 4.4, 4.4], 372), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 1.3]', [3.5, 5.1, 9.75, 1.2, 1.3], 547), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 1.2]', [3.5, 5.1, 9.75, 1.2, 1.2], 585), ('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 0.9]', [3.5, 5.1, 9.75, 1.2, 0.9], None), ('cosine curve time for height [10, 2.0, 22.4, 2.6, 2.3]', [10, 2.0, 22.4, 2.6, 2.3], 972), ('cosine curve time for height [0, 0, 2, 1, 0.25]', [0, 0, 2, 1, 0.25], 40), ('cosine curve time for height [1.25, 1.0, 7.25, 3.0, 2.0]', [1.25, 1.0, 7.25, 3.0, 2.0], 255)], [('cosine curve time for height [3.5, 5.1, 9.75, 1.2, 4.0]', [3.5, 5.1, 9.75, 1.2, 4.0], 344), ('cosine curve time for height [10, 2.0, 22.4, 2.6, 2.3]', [10, 2.0, 22.4, 2.6, 2.3], 972), ('cosine curve time for height [0, 0, 2, 1, 0.25]', [0, 0, 2, 1, 0.25], 40), ('cosine curve time for height [1.25, 1.0, 7.25, 3.0, 2.0]', [1.25, 1.0, 7.25, 3.0, 2.0], 255), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 0.6]', [0, 0.6, 6.2, 4.4, 0.6], 0), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 1.0]', [0, 0.6, 6.2, 4.4, 1.0], 78), ('cosine curve time for height [0, 0.6, 6.2, 4.4, 2.5]', [0, 0.6, 6.2, 4.4, 2.5], 186)]]
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 |
|---|---|---|---|
| cosine curve time for height [0, 0.6, 6.2, 4.4, 1.0] | 78 | 78 | Passed |
| cosine curve time for height [0, 0.6, 6.2, 4.4, 0.6] | 0 | 0 | Passed |
| cosine curve time for height [0, 0.6, 6.2, 4.4, 2.5] | 186 | 186 | Passed |
| cosine curve time for height [0, 0.6, 6.2, 4.4, 3.9] | 284 | 284 | Passed |
| cosine curve time for height [0, 0.6, 6.2, 4.4, 4.4] | 372 | 372 | Passed |
| cosine curve time for height [0, 0.6, 6.2, 4.4, 4.5] | None | None | Passed |
| cosine curve time for height [3.5, 5.1, 9.75, 1.2, 5.1] | 210 | 210 | Passed |
SHA-256 / 2b06888251755aaeea5d3575a5d5458c965b8d9c0f61405100614bfe9626b0cf
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:06.677998+00:00.
Case digest / 75a45b14c683849b25054f80d87e57d9fc939406cfaec2e67dfd8bf817ea4afe