FAILURE MAP
← Case archive

FA-69066 / Tide and marine navigation tables / Open access

Tidal height window: Crossing time is interpolated from the wrong end · case 01

Windows open and close at mirrored times within the sample interval.

Verified by executionVariant 1 · 7 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The interpolation fraction uses (b-req)/(b-a) but is added to the earlier sample time.

VERIFIED REPAIR

Add (req-a)/(b-a) of the interval to the earlier sample.

Unsuccessful approach: Measuring the same fraction back from the later sample mirrors it again for falling crossings.

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=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])*(b-req)/(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, 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], [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, 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], [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 [[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], [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, 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, 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], [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, 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, 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, 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], [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, 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 fixtureActualExpectedOutcome
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][[82, 260]][[99, 280]]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], 3.3][[146, 204]][[155, 216]]Failed
tidal height window [[0, 60, 120, 180, 240], [3.0, 2.6, 2.0, 2.4, 2.8], 2.5][[0, 110], [225, 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][[0, 110], [225, 240]][[0, 70], [195, 240]]Failed
tidal height window [[0, 30, 60, 90, 120], [1.0, 2.0, 3.0, 2.0, 1.0], 2.0][[0, 120]][[30, 90]]Failed
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 / 1e6855a5313abaf421b82a8f37685ddc14885648dc1a2105736c935810a2fe5e

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]-(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, 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], [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, 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], [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 [[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], [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, 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, 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], [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, 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, 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, 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], [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, 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 fixtureActualExpectedOutcome
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][[82, 260]][[99, 280]]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], 3.3][[146, 204]][[155, 216]]Failed
tidal height window [[0, 60, 120, 180, 240], [3.0, 2.6, 2.0, 2.4, 2.8], 2.5][[0, 110], [225, 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][[0, 110], [225, 240]][[0, 70], [195, 240]]Failed
tidal height window [[0, 30, 60, 90, 120], [1.0, 2.0, 3.0, 2.0, 1.0], 2.0][[0, 120]][[30, 90]]Failed
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 / 8824280ff3951ffbb5650d9260c1bb2e40945b71eee49ed61cdd092e8ad1f8ee

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, 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], [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, 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], [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 [[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], [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, 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, 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], [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, 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, 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, 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], [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, 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 fixtureActualExpectedOutcome
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, 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, 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 / b8bd76ab0a784494d85c925543a2c312d104766a21fba06dfb6f8382fa0cffcd

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.059154+00:00.

Case digest / 05140c958b2e4f534574c73b7fa22de234674bd790af4f25d24e08931be57c3e