FA-69081 / Tide and marine navigation tables / Open access
Tidal height window: A window already open at the first sample is lost · case 01
When the tide is already high enough at the start, the first window is omitted or truncated.
ROOT CAUSE
The start state ignores the first sample, so the first falling crossing has no start.
VERIFIED REPAIR
Start open at ts[0] when hs[0]>=req.
Unsuccessful approach: Treating an exactly sufficient first sample as closed still loses that window.
Case contract
Input [ts, hs, req]: sample times (minutes) and heights. Return the list of [start, end] intervals where height>=req, with crossing times linearly interpolated and rounded conservatively inward (start up, end down, 1e-9 tolerance); windows that vanish after rounding are dropped. A window open at the first sample starts at ts[0]; one still open at the end closes at ts[-1].
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):
ts,hs,req=x
wins=[]
def close(a,b):
s0,e0=math.ceil(a-1e-9),math.floor(b+1e-9)
if s0<=e0: wins.append([s0,e0])
start=None
for k in range(1,len(ts)):
a,b=hs[k-1],hs[k]
if (a>=req)!=(b>=req):
tc=ts[k-1]+(ts[k]-ts[k-1])*(req-a)/(b-a)
if b>=req: start=tc
else:
if start is not None: close(start,tc)
start=None
if start is not None: close(start,ts[-1])
return wins
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('tidal height window [[0, 60, 120, 180, 240], [3.0, 2.6, 2.0, 2.4, 2.8], 2.5]', [[0, 60, 120, 180, 240], [3.0, 2.6, 2.0, 2.4, 2.8], 2.5], [[0, 70], [195, 240]]), ('tidal height window [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5]', [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5], [[0, 70], [195, 240]]), ('tidal height window [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 2.5]', [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 2.5], [[99, 280]]), ('tidal height window [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 3.3]', [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 3.3], [[155, 216]]), ('tidal height window [[0, 30, 60, 90, 120], [1.0, 2.0, 3.0, 2.0, 1.0], 2.0]', [[0, 30, 60, 90, 120], [1.0, 2.0, 3.0, 2.0, 1.0], 2.0], [[30, 90]]), ('tidal height window [[0, 45, 90, 135], [0.5, 0.7, 0.9, 0.6], 2.0]', [[0, 45, 90, 135], [0.5, 0.7, 0.9, 0.6], 2.0], []), ('tidal height window [[0, 60, 120], [2.1, 2.2, 2.3], 2.0]', [[0, 60, 120], [2.1, 2.2, 2.3], 2.0], [[0, 120]])], [('tidal height window [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5]', [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5], [[0, 70], [195, 240]]), ('tidal height window [[0, 30, 60, 90, 120], [1.0, 2.0, 3.0, 2.0, 1.0], 2.0]', [[0, 30, 60, 90, 120], [1.0, 2.0, 3.0, 2.0, 1.0], 2.0], [[30, 90]]), ('tidal height window [[0, 45, 90, 135], [0.5, 0.7, 0.9, 0.6], 2.0]', [[0, 45, 90, 135], [0.5, 0.7, 0.9, 0.6], 2.0], []), ('tidal height window [[0, 60, 120], [2.1, 2.2, 2.3], 2.0]', [[0, 60, 120], [2.1, 2.2, 2.3], 2.0], [[0, 120]]), ('tidal height window [[0, 60, 120, 180, 240, 300], [0.8, 1.9, 2.6, 1.7, 2.4, 3.0], 2.2]', [[0, 60, 120, 180, 240, 300], [0.8, 1.9, 2.6, 1.7, 2.4, 3.0], 2.2], [[86, 146], [223, 300]]), ('tidal height window [[0, 50, 100, 150], [1.0, 2.0, 3.0, 1.0], 1.5]', [[0, 50, 100, 150], [1.0, 2.0, 3.0, 1.0], 1.5], [[25, 137]]), ('tidal height window [[100, 160, 220, 280], [1.0, 1.3, 1.9, 2.2], 1.45]', [[100, 160, 220, 280], [1.0, 1.3, 1.9, 2.2], 1.45], [[175, 280]])], [('tidal height window [[0, 60, 120], [2.1, 2.2, 2.3], 2.0]', [[0, 60, 120], [2.1, 2.2, 2.3], 2.0], [[0, 120]]), ('tidal height window [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5]', [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5], [[0, 70], [195, 240]]), ('tidal height window [[0, 60, 120, 180, 240, 300], [0.8, 1.9, 2.6, 1.7, 2.4, 3.0], 2.2]', [[0, 60, 120, 180, 240, 300], [0.8, 1.9, 2.6, 1.7, 2.4, 3.0], 2.2], [[86, 146], [223, 300]]), ('tidal height window [[0, 50, 100, 150], [1.0, 2.0, 3.0, 1.0], 1.5]', [[0, 50, 100, 150], [1.0, 2.0, 3.0, 1.0], 1.5], [[25, 137]]), ('tidal height window [[100, 160, 220, 280], [1.0, 1.3, 1.9, 2.2], 1.45]', [[100, 160, 220, 280], [1.0, 1.3, 1.9, 2.2], 1.45], [[175, 280]]), ('tidal height window [[0, 60, 120, 180], [3.0, 1.0, 1.0, 3.0], 1.5]', [[0, 60, 120, 180], [3.0, 1.0, 1.0, 3.0], 1.5], [[0, 45], [135, 180]]), ('tidal height window [[0, 60, 120, 180, 240], [1.0, 2.5, 1.0, 2.6, 1.0], 2.0]', [[0, 60, 120, 180, 240], [1.0, 2.5, 1.0, 2.6, 1.0], 2.0], [[40, 80], [158, 202]])], [('tidal height window [[0, 60, 120, 180], [3.0, 1.0, 1.0, 3.0], 1.5]', [[0, 60, 120, 180], [3.0, 1.0, 1.0, 3.0], 1.5], [[0, 45], [135, 180]]), ('tidal height window [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5]', [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5], [[0, 70], [195, 240]]), ('tidal height window [[100, 160, 220, 280], [1.0, 1.3, 1.9, 2.2], 1.45]', [[100, 160, 220, 280], [1.0, 1.3, 1.9, 2.2], 1.45], [[175, 280]]), ('tidal height window [[0, 60, 120, 180, 240], [1.0, 2.5, 1.0, 2.6, 1.0], 2.0]', [[0, 60, 120, 180, 240], [1.0, 2.5, 1.0, 2.6, 1.0], 2.0], [[40, 80], [158, 202]]), ('tidal height window [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 2.5]', [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 2.5], [[99, 280]]), ('tidal height window [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 3.3]', [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 3.3], [[155, 216]]), ('tidal height window [[0, 60, 120, 180, 240], [3.0, 2.6, 2.0, 2.4, 2.8], 2.5]', [[0, 60, 120, 180, 240], [3.0, 2.6, 2.0, 2.4, 2.8], 2.5], [[0, 70], [195, 240]])], [('tidal height window [[0, 60, 120, 180, 240], [3.0, 2.6, 2.0, 2.4, 2.8], 2.5]', [[0, 60, 120, 180, 240], [3.0, 2.6, 2.0, 2.4, 2.8], 2.5], [[0, 70], [195, 240]]), ('tidal height window [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5]', [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5], [[0, 70], [195, 240]]), ('tidal height window [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 2.5]', [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 2.5], [[99, 280]]), ('tidal height window [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 3.3]', [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 3.3], [[155, 216]]), ('tidal height window [[0, 30, 60, 90, 120], [1.0, 2.0, 3.0, 2.0, 1.0], 2.0]', [[0, 30, 60, 90, 120], [1.0, 2.0, 3.0, 2.0, 1.0], 2.0], [[30, 90]]), ('tidal height window [[0, 45, 90, 135], [0.5, 0.7, 0.9, 0.6], 2.0]', [[0, 45, 90, 135], [0.5, 0.7, 0.9, 0.6], 2.0], []), ('tidal height window [[0, 60, 120], [2.1, 2.2, 2.3], 2.0]', [[0, 60, 120], [2.1, 2.2, 2.3], 2.0], [[0, 120]])]]
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 |
|---|---|---|---|
| tidal height window [[0, 60, 120, 180, 240], [3.0, 2.6, 2.0, 2.4, 2.8], 2.5] | [[195, 240]] | [[0, 70], [195, 240]] | Failed |
| tidal height window [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5] | [[195, 240]] | [[0, 70], [195, 240]] | Failed |
| tidal height window [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 2.5] | [[99, 280]] | [[99, 280]] | Passed |
| tidal height window [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 3.3] | [[155, 216]] | [[155, 216]] | Passed |
| tidal height window [[0, 30, 60, 90, 120], [1.0, 2.0, 3.0, 2.0, 1.0], 2.0] | [[30, 90]] | [[30, 90]] | Passed |
| tidal height window [[0, 45, 90, 135], [0.5, 0.7, 0.9, 0.6], 2.0] | [] | [] | Passed |
| tidal height window [[0, 60, 120], [2.1, 2.2, 2.3], 2.0] | [] | [[0, 120]] | Failed |
SHA-256 / 7e75b415f2e2caed34045647e0eefcf94f7373bca9f029bb3811c45fe9bc84a2
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
ts,hs,req=x
wins=[]
def close(a,b):
s0,e0=math.ceil(a-1e-9),math.floor(b+1e-9)
if s0<=e0: wins.append([s0,e0])
start=ts[0] if hs[0]>req else None
for k in range(1,len(ts)):
a,b=hs[k-1],hs[k]
if (a>=req)!=(b>=req):
tc=ts[k-1]+(ts[k]-ts[k-1])*(req-a)/(b-a)
if b>=req: start=tc
else:
if start is not None: close(start,tc)
start=None
if start is not None: close(start,ts[-1])
return wins
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('tidal height window [[0, 60, 120, 180, 240], [3.0, 2.6, 2.0, 2.4, 2.8], 2.5]', [[0, 60, 120, 180, 240], [3.0, 2.6, 2.0, 2.4, 2.8], 2.5], [[0, 70], [195, 240]]), ('tidal height window [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5]', [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5], [[0, 70], [195, 240]]), ('tidal height window [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 2.5]', [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 2.5], [[99, 280]]), ('tidal height window [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 3.3]', [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 3.3], [[155, 216]]), ('tidal height window [[0, 30, 60, 90, 120], [1.0, 2.0, 3.0, 2.0, 1.0], 2.0]', [[0, 30, 60, 90, 120], [1.0, 2.0, 3.0, 2.0, 1.0], 2.0], [[30, 90]]), ('tidal height window [[0, 45, 90, 135], [0.5, 0.7, 0.9, 0.6], 2.0]', [[0, 45, 90, 135], [0.5, 0.7, 0.9, 0.6], 2.0], []), ('tidal height window [[0, 60, 120], [2.1, 2.2, 2.3], 2.0]', [[0, 60, 120], [2.1, 2.2, 2.3], 2.0], [[0, 120]])], [('tidal height window [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5]', [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5], [[0, 70], [195, 240]]), ('tidal height window [[0, 30, 60, 90, 120], [1.0, 2.0, 3.0, 2.0, 1.0], 2.0]', [[0, 30, 60, 90, 120], [1.0, 2.0, 3.0, 2.0, 1.0], 2.0], [[30, 90]]), ('tidal height window [[0, 45, 90, 135], [0.5, 0.7, 0.9, 0.6], 2.0]', [[0, 45, 90, 135], [0.5, 0.7, 0.9, 0.6], 2.0], []), ('tidal height window [[0, 60, 120], [2.1, 2.2, 2.3], 2.0]', [[0, 60, 120], [2.1, 2.2, 2.3], 2.0], [[0, 120]]), ('tidal height window [[0, 60, 120, 180, 240, 300], [0.8, 1.9, 2.6, 1.7, 2.4, 3.0], 2.2]', [[0, 60, 120, 180, 240, 300], [0.8, 1.9, 2.6, 1.7, 2.4, 3.0], 2.2], [[86, 146], [223, 300]]), ('tidal height window [[0, 50, 100, 150], [1.0, 2.0, 3.0, 1.0], 1.5]', [[0, 50, 100, 150], [1.0, 2.0, 3.0, 1.0], 1.5], [[25, 137]]), ('tidal height window [[100, 160, 220, 280], [1.0, 1.3, 1.9, 2.2], 1.45]', [[100, 160, 220, 280], [1.0, 1.3, 1.9, 2.2], 1.45], [[175, 280]])], [('tidal height window [[0, 60, 120], [2.1, 2.2, 2.3], 2.0]', [[0, 60, 120], [2.1, 2.2, 2.3], 2.0], [[0, 120]]), ('tidal height window [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5]', [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5], [[0, 70], [195, 240]]), ('tidal height window [[0, 60, 120, 180, 240, 300], [0.8, 1.9, 2.6, 1.7, 2.4, 3.0], 2.2]', [[0, 60, 120, 180, 240, 300], [0.8, 1.9, 2.6, 1.7, 2.4, 3.0], 2.2], [[86, 146], [223, 300]]), ('tidal height window [[0, 50, 100, 150], [1.0, 2.0, 3.0, 1.0], 1.5]', [[0, 50, 100, 150], [1.0, 2.0, 3.0, 1.0], 1.5], [[25, 137]]), ('tidal height window [[100, 160, 220, 280], [1.0, 1.3, 1.9, 2.2], 1.45]', [[100, 160, 220, 280], [1.0, 1.3, 1.9, 2.2], 1.45], [[175, 280]]), ('tidal height window [[0, 60, 120, 180], [3.0, 1.0, 1.0, 3.0], 1.5]', [[0, 60, 120, 180], [3.0, 1.0, 1.0, 3.0], 1.5], [[0, 45], [135, 180]]), ('tidal height window [[0, 60, 120, 180, 240], [1.0, 2.5, 1.0, 2.6, 1.0], 2.0]', [[0, 60, 120, 180, 240], [1.0, 2.5, 1.0, 2.6, 1.0], 2.0], [[40, 80], [158, 202]])], [('tidal height window [[0, 60, 120, 180], [3.0, 1.0, 1.0, 3.0], 1.5]', [[0, 60, 120, 180], [3.0, 1.0, 1.0, 3.0], 1.5], [[0, 45], [135, 180]]), ('tidal height window [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5]', [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5], [[0, 70], [195, 240]]), ('tidal height window [[100, 160, 220, 280], [1.0, 1.3, 1.9, 2.2], 1.45]', [[100, 160, 220, 280], [1.0, 1.3, 1.9, 2.2], 1.45], [[175, 280]]), ('tidal height window [[0, 60, 120, 180, 240], [1.0, 2.5, 1.0, 2.6, 1.0], 2.0]', [[0, 60, 120, 180, 240], [1.0, 2.5, 1.0, 2.6, 1.0], 2.0], [[40, 80], [158, 202]]), ('tidal height window [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 2.5]', [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 2.5], [[99, 280]]), ('tidal height window [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 3.3]', [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 3.3], [[155, 216]]), ('tidal height window [[0, 60, 120, 180, 240], [3.0, 2.6, 2.0, 2.4, 2.8], 2.5]', [[0, 60, 120, 180, 240], [3.0, 2.6, 2.0, 2.4, 2.8], 2.5], [[0, 70], [195, 240]])], [('tidal height window [[0, 60, 120, 180, 240], [3.0, 2.6, 2.0, 2.4, 2.8], 2.5]', [[0, 60, 120, 180, 240], [3.0, 2.6, 2.0, 2.4, 2.8], 2.5], [[0, 70], [195, 240]]), ('tidal height window [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5]', [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5], [[0, 70], [195, 240]]), ('tidal height window [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 2.5]', [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 2.5], [[99, 280]]), ('tidal height window [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 3.3]', [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 3.3], [[155, 216]]), ('tidal height window [[0, 30, 60, 90, 120], [1.0, 2.0, 3.0, 2.0, 1.0], 2.0]', [[0, 30, 60, 90, 120], [1.0, 2.0, 3.0, 2.0, 1.0], 2.0], [[30, 90]]), ('tidal height window [[0, 45, 90, 135], [0.5, 0.7, 0.9, 0.6], 2.0]', [[0, 45, 90, 135], [0.5, 0.7, 0.9, 0.6], 2.0], []), ('tidal height window [[0, 60, 120], [2.1, 2.2, 2.3], 2.0]', [[0, 60, 120], [2.1, 2.2, 2.3], 2.0], [[0, 120]])]]
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 |
|---|---|---|---|
| tidal height window [[0, 60, 120, 180, 240], [3.0, 2.6, 2.0, 2.4, 2.8], 2.5] | [[0, 70], [195, 240]] | [[0, 70], [195, 240]] | Passed |
| tidal height window [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5] | [[195, 240]] | [[0, 70], [195, 240]] | Failed |
| tidal height window [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 2.5] | [[99, 280]] | [[99, 280]] | Passed |
| tidal height window [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 3.3] | [[155, 216]] | [[155, 216]] | Passed |
| tidal height window [[0, 30, 60, 90, 120], [1.0, 2.0, 3.0, 2.0, 1.0], 2.0] | [[30, 90]] | [[30, 90]] | Passed |
| tidal height window [[0, 45, 90, 135], [0.5, 0.7, 0.9, 0.6], 2.0] | [] | [] | Passed |
| tidal height window [[0, 60, 120], [2.1, 2.2, 2.3], 2.0] | [[0, 120]] | [[0, 120]] | Passed |
SHA-256 / c640e67fca868dd59252855e3ab18d2f794529ac91a9126848b8edbf47d02397
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(x):
ts,hs,req=x
wins=[]
def close(a,b):
s0,e0=math.ceil(a-1e-9),math.floor(b+1e-9)
if s0<=e0: wins.append([s0,e0])
start=ts[0] if hs[0]>=req else None
for k in range(1,len(ts)):
a,b=hs[k-1],hs[k]
if (a>=req)!=(b>=req):
tc=ts[k-1]+(ts[k]-ts[k-1])*(req-a)/(b-a)
if b>=req: start=tc
else:
if start is not None: close(start,tc)
start=None
if start is not None: close(start,ts[-1])
return wins
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('tidal height window [[0, 60, 120, 180, 240], [3.0, 2.6, 2.0, 2.4, 2.8], 2.5]', [[0, 60, 120, 180, 240], [3.0, 2.6, 2.0, 2.4, 2.8], 2.5], [[0, 70], [195, 240]]), ('tidal height window [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5]', [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5], [[0, 70], [195, 240]]), ('tidal height window [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 2.5]', [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 2.5], [[99, 280]]), ('tidal height window [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 3.3]', [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 3.3], [[155, 216]]), ('tidal height window [[0, 30, 60, 90, 120], [1.0, 2.0, 3.0, 2.0, 1.0], 2.0]', [[0, 30, 60, 90, 120], [1.0, 2.0, 3.0, 2.0, 1.0], 2.0], [[30, 90]]), ('tidal height window [[0, 45, 90, 135], [0.5, 0.7, 0.9, 0.6], 2.0]', [[0, 45, 90, 135], [0.5, 0.7, 0.9, 0.6], 2.0], []), ('tidal height window [[0, 60, 120], [2.1, 2.2, 2.3], 2.0]', [[0, 60, 120], [2.1, 2.2, 2.3], 2.0], [[0, 120]])], [('tidal height window [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5]', [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5], [[0, 70], [195, 240]]), ('tidal height window [[0, 30, 60, 90, 120], [1.0, 2.0, 3.0, 2.0, 1.0], 2.0]', [[0, 30, 60, 90, 120], [1.0, 2.0, 3.0, 2.0, 1.0], 2.0], [[30, 90]]), ('tidal height window [[0, 45, 90, 135], [0.5, 0.7, 0.9, 0.6], 2.0]', [[0, 45, 90, 135], [0.5, 0.7, 0.9, 0.6], 2.0], []), ('tidal height window [[0, 60, 120], [2.1, 2.2, 2.3], 2.0]', [[0, 60, 120], [2.1, 2.2, 2.3], 2.0], [[0, 120]]), ('tidal height window [[0, 60, 120, 180, 240, 300], [0.8, 1.9, 2.6, 1.7, 2.4, 3.0], 2.2]', [[0, 60, 120, 180, 240, 300], [0.8, 1.9, 2.6, 1.7, 2.4, 3.0], 2.2], [[86, 146], [223, 300]]), ('tidal height window [[0, 50, 100, 150], [1.0, 2.0, 3.0, 1.0], 1.5]', [[0, 50, 100, 150], [1.0, 2.0, 3.0, 1.0], 1.5], [[25, 137]]), ('tidal height window [[100, 160, 220, 280], [1.0, 1.3, 1.9, 2.2], 1.45]', [[100, 160, 220, 280], [1.0, 1.3, 1.9, 2.2], 1.45], [[175, 280]])], [('tidal height window [[0, 60, 120], [2.1, 2.2, 2.3], 2.0]', [[0, 60, 120], [2.1, 2.2, 2.3], 2.0], [[0, 120]]), ('tidal height window [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5]', [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5], [[0, 70], [195, 240]]), ('tidal height window [[0, 60, 120, 180, 240, 300], [0.8, 1.9, 2.6, 1.7, 2.4, 3.0], 2.2]', [[0, 60, 120, 180, 240, 300], [0.8, 1.9, 2.6, 1.7, 2.4, 3.0], 2.2], [[86, 146], [223, 300]]), ('tidal height window [[0, 50, 100, 150], [1.0, 2.0, 3.0, 1.0], 1.5]', [[0, 50, 100, 150], [1.0, 2.0, 3.0, 1.0], 1.5], [[25, 137]]), ('tidal height window [[100, 160, 220, 280], [1.0, 1.3, 1.9, 2.2], 1.45]', [[100, 160, 220, 280], [1.0, 1.3, 1.9, 2.2], 1.45], [[175, 280]]), ('tidal height window [[0, 60, 120, 180], [3.0, 1.0, 1.0, 3.0], 1.5]', [[0, 60, 120, 180], [3.0, 1.0, 1.0, 3.0], 1.5], [[0, 45], [135, 180]]), ('tidal height window [[0, 60, 120, 180, 240], [1.0, 2.5, 1.0, 2.6, 1.0], 2.0]', [[0, 60, 120, 180, 240], [1.0, 2.5, 1.0, 2.6, 1.0], 2.0], [[40, 80], [158, 202]])], [('tidal height window [[0, 60, 120, 180], [3.0, 1.0, 1.0, 3.0], 1.5]', [[0, 60, 120, 180], [3.0, 1.0, 1.0, 3.0], 1.5], [[0, 45], [135, 180]]), ('tidal height window [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5]', [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5], [[0, 70], [195, 240]]), ('tidal height window [[100, 160, 220, 280], [1.0, 1.3, 1.9, 2.2], 1.45]', [[100, 160, 220, 280], [1.0, 1.3, 1.9, 2.2], 1.45], [[175, 280]]), ('tidal height window [[0, 60, 120, 180, 240], [1.0, 2.5, 1.0, 2.6, 1.0], 2.0]', [[0, 60, 120, 180, 240], [1.0, 2.5, 1.0, 2.6, 1.0], 2.0], [[40, 80], [158, 202]]), ('tidal height window [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 2.5]', [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 2.5], [[99, 280]]), ('tidal height window [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 3.3]', [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 3.3], [[155, 216]]), ('tidal height window [[0, 60, 120, 180, 240], [3.0, 2.6, 2.0, 2.4, 2.8], 2.5]', [[0, 60, 120, 180, 240], [3.0, 2.6, 2.0, 2.4, 2.8], 2.5], [[0, 70], [195, 240]])], [('tidal height window [[0, 60, 120, 180, 240], [3.0, 2.6, 2.0, 2.4, 2.8], 2.5]', [[0, 60, 120, 180, 240], [3.0, 2.6, 2.0, 2.4, 2.8], 2.5], [[0, 70], [195, 240]]), ('tidal height window [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5]', [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5], [[0, 70], [195, 240]]), ('tidal height window [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 2.5]', [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 2.5], [[99, 280]]), ('tidal height window [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 3.3]', [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 3.3], [[155, 216]]), ('tidal height window [[0, 30, 60, 90, 120], [1.0, 2.0, 3.0, 2.0, 1.0], 2.0]', [[0, 30, 60, 90, 120], [1.0, 2.0, 3.0, 2.0, 1.0], 2.0], [[30, 90]]), ('tidal height window [[0, 45, 90, 135], [0.5, 0.7, 0.9, 0.6], 2.0]', [[0, 45, 90, 135], [0.5, 0.7, 0.9, 0.6], 2.0], []), ('tidal height window [[0, 60, 120], [2.1, 2.2, 2.3], 2.0]', [[0, 60, 120], [2.1, 2.2, 2.3], 2.0], [[0, 120]])]]
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 |
|---|---|---|---|
| tidal height window [[0, 60, 120, 180, 240], [3.0, 2.6, 2.0, 2.4, 2.8], 2.5] | [[0, 70], [195, 240]] | [[0, 70], [195, 240]] | Passed |
| tidal height window [[0, 60, 120, 180, 240], [2.5, 2.6, 2.0, 2.4, 2.8], 2.5] | [[0, 70], [195, 240]] | [[0, 70], [195, 240]] | Passed |
| tidal height window [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 2.5] | [[99, 280]] | [[99, 280]] | Passed |
| tidal height window [[0, 60, 120, 180, 240, 300, 360], [1.0, 1.8, 2.9, 3.6, 3.1, 2.2, 1.4], 3.3] | [[155, 216]] | [[155, 216]] | Passed |
| tidal height window [[0, 30, 60, 90, 120], [1.0, 2.0, 3.0, 2.0, 1.0], 2.0] | [[30, 90]] | [[30, 90]] | Passed |
| tidal height window [[0, 45, 90, 135], [0.5, 0.7, 0.9, 0.6], 2.0] | [] | [] | Passed |
| tidal height window [[0, 60, 120], [2.1, 2.2, 2.3], 2.0] | [[0, 120]] | [[0, 120]] | Passed |
SHA-256 / 2124e7739a2d1288ac1670c351e6270b21c40efd6452bb64e9ed2893059b2e3c
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:08.144379+00:00.
Case digest / f6869c775027177b219405ad38dea60d48d568649310be89ff762037aad1d3bd