FAILURE MAP
← Case archive

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

Slack water from current samples: The previous moving sample is only set once · case 01

After the first reversal later slacks are missed or mistimed.

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

ROOT CAUSE

The reference sample is not advanced after every nonzero sample.

VERIFIED REPAIR

Update prev at every nonzero sample.

Unsuccessful approach: Advancing only on reversals interpolates against the first sample of each run.

Case contract

Input [ts, vs]: sample times (minutes) and signed current (flood positive). Zero samples are skipped; a slack occurs between consecutive nonzero samples of opposite sign. With no zero samples in between, slack time is linearly interpolated; across a run of zero samples it is the midpoint of the zero run. Times round half up to minutes; the label says which stream begins. Return [[minute, "flood-begins"|"ebb-begins"], ...].

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,vs=x
    out=[]
    prev=None
    for k in range(len(vs)):
        if vs[k]==0: continue
        if prev is not None and (vs[prev]>0)!=(vs[k]>0):
            if k-prev>1:
                tc=(ts[prev+1]+ts[k-1])/2
            else:
                tc=ts[prev]+(ts[k]-ts[prev])*vs[prev]/(vs[prev]-vs[k])
            out.append([math.floor(tc+0.5),'flood-begins' if vs[k]>0 else 'ebb-begins'])
        if prev is None: prev=k
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('slack water from current samples [[0, 30, 60, 90, 120, 150], [1.2, 0.8, 0.3, -0.4, -1.1, -1.5]]', [[0, 30, 60, 90, 120, 150], [1.2, 0.8, 0.3, -0.4, -1.1, -1.5]], [[73, 'ebb-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120, 150], [-1.0, -0.5, 0.0, 0.0, 0.6, 1.0]]', [[0, 30, 60, 90, 120, 150], [-1.0, -0.5, 0.0, 0.0, 0.6, 1.0]], [[75, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120], [1.0, 0.0, 0.7, 1.2, 0.4]]', [[0, 30, 60, 90, 120], [1.0, 0.0, 0.7, 1.2, 0.4]], []), ('slack water from current samples [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]]', [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]], [[30, 'ebb-begins'], [90, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90], [0.0, 0.0, 1.0, 2.0]]', [[0, 30, 60, 90], [0.0, 0.0, 1.0, 2.0]], []), ('slack water from current samples [[0, 60, 120, 180, 240], [-0.9, -0.3, 0.2, 0.0, -0.4]]', [[0, 60, 120, 180, 240], [-0.9, -0.3, 0.2, 0.0, -0.4]], [[96, 'flood-begins'], [180, 'ebb-begins']]), ('slack water from current samples [[0, 15, 30, 45, 60], [0.5, 0.3, 0.1, -0.2, -0.3]]', [[0, 15, 30, 45, 60], [0.5, 0.3, 0.1, -0.2, -0.3]], [[35, 'ebb-begins']])], [('slack water from current samples [[0, 30, 60, 90, 120, 150], [-1.0, -0.5, 0.0, 0.0, 0.6, 1.0]]', [[0, 30, 60, 90, 120, 150], [-1.0, -0.5, 0.0, 0.0, 0.6, 1.0]], [[75, 'flood-begins']]), ('slack water from current samples [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]]', [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]], [[30, 'ebb-begins'], [90, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90], [0.0, 0.0, 1.0, 2.0]]', [[0, 30, 60, 90], [0.0, 0.0, 1.0, 2.0]], []), ('slack water from current samples [[0, 60, 120, 180, 240], [-0.9, -0.3, 0.2, 0.0, -0.4]]', [[0, 60, 120, 180, 240], [-0.9, -0.3, 0.2, 0.0, -0.4]], [[96, 'flood-begins'], [180, 'ebb-begins']]), ('slack water from current samples [[0, 15, 30, 45, 60], [0.5, 0.3, 0.1, -0.2, -0.3]]', [[0, 15, 30, 45, 60], [0.5, 0.3, 0.1, -0.2, -0.3]], [[35, 'ebb-begins']]), ('slack water from current samples [[0, 60, 120, 180], [1.0, 0.0, 0.0, -1.0]]', [[0, 60, 120, 180], [1.0, 0.0, 0.0, -1.0]], [[90, 'ebb-begins']]), ('slack water from current samples [[0, 60, 120], [-3.0, -1.0, 1.0]]', [[0, 60, 120], [-3.0, -1.0, 1.0]], [[90, 'flood-begins']])], [('slack water from current samples [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]]', [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]], [[30, 'ebb-begins'], [90, 'flood-begins']]), ('slack water from current samples [[0, 15, 30, 45, 60], [0.5, 0.3, 0.1, -0.2, -0.3]]', [[0, 15, 30, 45, 60], [0.5, 0.3, 0.1, -0.2, -0.3]], [[35, 'ebb-begins']]), ('slack water from current samples [[0, 60, 120, 180], [1.0, 0.0, 0.0, -1.0]]', [[0, 60, 120, 180], [1.0, 0.0, 0.0, -1.0]], [[90, 'ebb-begins']]), ('slack water from current samples [[0, 60, 120], [-3.0, -1.0, 1.0]]', [[0, 60, 120], [-3.0, -1.0, 1.0]], [[90, 'flood-begins']]), ('slack water from current samples [[0, 10, 20, 30, 40], [1.0, -1.0, 1.0, -1.0, 1.0]]', [[0, 10, 20, 30, 40], [1.0, -1.0, 1.0, -1.0, 1.0]], [[5, 'ebb-begins'], [15, 'flood-begins'], [25, 'ebb-begins'], [35, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120, 150, 180], [0.9, 0.4, 0.0, -0.3, -0.2, 0.0, 0.6]]', [[0, 30, 60, 90, 120, 150, 180], [0.9, 0.4, 0.0, -0.3, -0.2, 0.0, 0.6]], [[60, 'ebb-begins'], [150, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120, 150], [1.2, 0.8, 0.3, -0.4, -1.1, -1.5]]', [[0, 30, 60, 90, 120, 150], [1.2, 0.8, 0.3, -0.4, -1.1, -1.5]], [[73, 'ebb-begins']])], [('slack water from current samples [[0, 60, 120, 180, 240], [-0.9, -0.3, 0.2, 0.0, -0.4]]', [[0, 60, 120, 180, 240], [-0.9, -0.3, 0.2, 0.0, -0.4]], [[96, 'flood-begins'], [180, 'ebb-begins']]), ('slack water from current samples [[0, 10, 20, 30, 40], [1.0, -1.0, 1.0, -1.0, 1.0]]', [[0, 10, 20, 30, 40], [1.0, -1.0, 1.0, -1.0, 1.0]], [[5, 'ebb-begins'], [15, 'flood-begins'], [25, 'ebb-begins'], [35, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120, 150, 180], [0.9, 0.4, 0.0, -0.3, -0.2, 0.0, 0.6]]', [[0, 30, 60, 90, 120, 150, 180], [0.9, 0.4, 0.0, -0.3, -0.2, 0.0, 0.6]], [[60, 'ebb-begins'], [150, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120, 150], [1.2, 0.8, 0.3, -0.4, -1.1, -1.5]]', [[0, 30, 60, 90, 120, 150], [1.2, 0.8, 0.3, -0.4, -1.1, -1.5]], [[73, 'ebb-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120, 150], [-1.0, -0.5, 0.0, 0.0, 0.6, 1.0]]', [[0, 30, 60, 90, 120, 150], [-1.0, -0.5, 0.0, 0.0, 0.6, 1.0]], [[75, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120], [1.0, 0.0, 0.7, 1.2, 0.4]]', [[0, 30, 60, 90, 120], [1.0, 0.0, 0.7, 1.2, 0.4]], []), ('slack water from current samples [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]]', [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]], [[30, 'ebb-begins'], [90, 'flood-begins']])], [('slack water from current samples [[0, 15, 30, 45, 60], [0.5, 0.3, 0.1, -0.2, -0.3]]', [[0, 15, 30, 45, 60], [0.5, 0.3, 0.1, -0.2, -0.3]], [[35, 'ebb-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120, 150], [-1.0, -0.5, 0.0, 0.0, 0.6, 1.0]]', [[0, 30, 60, 90, 120, 150], [-1.0, -0.5, 0.0, 0.0, 0.6, 1.0]], [[75, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120], [1.0, 0.0, 0.7, 1.2, 0.4]]', [[0, 30, 60, 90, 120], [1.0, 0.0, 0.7, 1.2, 0.4]], []), ('slack water from current samples [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]]', [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]], [[30, 'ebb-begins'], [90, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90], [0.0, 0.0, 1.0, 2.0]]', [[0, 30, 60, 90], [0.0, 0.0, 1.0, 2.0]], []), ('slack water from current samples [[0, 60, 120, 180, 240], [-0.9, -0.3, 0.2, 0.0, -0.4]]', [[0, 60, 120, 180, 240], [-0.9, -0.3, 0.2, 0.0, -0.4]], [[96, 'flood-begins'], [180, 'ebb-begins']]), ('slack water from current samples [[0, 60, 120, 180], [1.0, 0.0, 0.0, -1.0]]', [[0, 60, 120, 180], [1.0, 0.0, 0.0, -1.0]], [[90, 'ebb-begins']])]]
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
slack water from current samples [[0, 30, 60, 90, 120, 150], [1.2, 0.8, 0.3, -0.4, -1.1, -1.5]][[45, 'ebb-begins'], [60, 'ebb-begins'], [75, 'ebb-begins']][[73, 'ebb-begins']]Failed
slack water from current samples [[0, 30, 60, 90, 120, 150], [-1.0, -0.5, 0.0, 0.0, 0.6, 1.0]][[60, 'flood-begins'], [75, 'flood-begins']][[75, 'flood-begins']]Failed
slack water from current samples [[0, 30, 60, 90, 120], [1.0, 0.0, 0.7, 1.2, 0.4]][][]Passed
slack water from current samples [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]][[20, 'ebb-begins'], [30, 'ebb-begins'], [40, 'ebb-begins']][[30, 'ebb-begins'], [90, 'flood-begins']]Failed
slack water from current samples [[0, 30, 60, 90], [0.0, 0.0, 1.0, 2.0]][][]Passed
slack water from current samples [[0, 60, 120, 180, 240], [-0.9, -0.3, 0.2, 0.0, -0.4]][[60, 'flood-begins']][[96, 'flood-begins'], [180, 'ebb-begins']]Failed
slack water from current samples [[0, 15, 30, 45, 60], [0.5, 0.3, 0.1, -0.2, -0.3]][[23, 'ebb-begins'], [30, 'ebb-begins']][[35, 'ebb-begins']]Failed

SHA-256 / 683b8d91c671ac287b86bc8d1091112a1057c73948e177d26c5ac3f0827cea32

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,vs=x
    out=[]
    prev=None
    for k in range(len(vs)):
        if vs[k]==0: continue
        if prev is not None and (vs[prev]>0)!=(vs[k]>0):
            if k-prev>1:
                tc=(ts[prev+1]+ts[k-1])/2
            else:
                tc=ts[prev]+(ts[k]-ts[prev])*vs[prev]/(vs[prev]-vs[k])
            out.append([math.floor(tc+0.5),'flood-begins' if vs[k]>0 else 'ebb-begins'])
        if prev is None or (vs[prev]>0)!=(vs[k]>0): prev=k
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('slack water from current samples [[0, 30, 60, 90, 120, 150], [1.2, 0.8, 0.3, -0.4, -1.1, -1.5]]', [[0, 30, 60, 90, 120, 150], [1.2, 0.8, 0.3, -0.4, -1.1, -1.5]], [[73, 'ebb-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120, 150], [-1.0, -0.5, 0.0, 0.0, 0.6, 1.0]]', [[0, 30, 60, 90, 120, 150], [-1.0, -0.5, 0.0, 0.0, 0.6, 1.0]], [[75, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120], [1.0, 0.0, 0.7, 1.2, 0.4]]', [[0, 30, 60, 90, 120], [1.0, 0.0, 0.7, 1.2, 0.4]], []), ('slack water from current samples [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]]', [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]], [[30, 'ebb-begins'], [90, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90], [0.0, 0.0, 1.0, 2.0]]', [[0, 30, 60, 90], [0.0, 0.0, 1.0, 2.0]], []), ('slack water from current samples [[0, 60, 120, 180, 240], [-0.9, -0.3, 0.2, 0.0, -0.4]]', [[0, 60, 120, 180, 240], [-0.9, -0.3, 0.2, 0.0, -0.4]], [[96, 'flood-begins'], [180, 'ebb-begins']]), ('slack water from current samples [[0, 15, 30, 45, 60], [0.5, 0.3, 0.1, -0.2, -0.3]]', [[0, 15, 30, 45, 60], [0.5, 0.3, 0.1, -0.2, -0.3]], [[35, 'ebb-begins']])], [('slack water from current samples [[0, 30, 60, 90, 120, 150], [-1.0, -0.5, 0.0, 0.0, 0.6, 1.0]]', [[0, 30, 60, 90, 120, 150], [-1.0, -0.5, 0.0, 0.0, 0.6, 1.0]], [[75, 'flood-begins']]), ('slack water from current samples [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]]', [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]], [[30, 'ebb-begins'], [90, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90], [0.0, 0.0, 1.0, 2.0]]', [[0, 30, 60, 90], [0.0, 0.0, 1.0, 2.0]], []), ('slack water from current samples [[0, 60, 120, 180, 240], [-0.9, -0.3, 0.2, 0.0, -0.4]]', [[0, 60, 120, 180, 240], [-0.9, -0.3, 0.2, 0.0, -0.4]], [[96, 'flood-begins'], [180, 'ebb-begins']]), ('slack water from current samples [[0, 15, 30, 45, 60], [0.5, 0.3, 0.1, -0.2, -0.3]]', [[0, 15, 30, 45, 60], [0.5, 0.3, 0.1, -0.2, -0.3]], [[35, 'ebb-begins']]), ('slack water from current samples [[0, 60, 120, 180], [1.0, 0.0, 0.0, -1.0]]', [[0, 60, 120, 180], [1.0, 0.0, 0.0, -1.0]], [[90, 'ebb-begins']]), ('slack water from current samples [[0, 60, 120], [-3.0, -1.0, 1.0]]', [[0, 60, 120], [-3.0, -1.0, 1.0]], [[90, 'flood-begins']])], [('slack water from current samples [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]]', [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]], [[30, 'ebb-begins'], [90, 'flood-begins']]), ('slack water from current samples [[0, 15, 30, 45, 60], [0.5, 0.3, 0.1, -0.2, -0.3]]', [[0, 15, 30, 45, 60], [0.5, 0.3, 0.1, -0.2, -0.3]], [[35, 'ebb-begins']]), ('slack water from current samples [[0, 60, 120, 180], [1.0, 0.0, 0.0, -1.0]]', [[0, 60, 120, 180], [1.0, 0.0, 0.0, -1.0]], [[90, 'ebb-begins']]), ('slack water from current samples [[0, 60, 120], [-3.0, -1.0, 1.0]]', [[0, 60, 120], [-3.0, -1.0, 1.0]], [[90, 'flood-begins']]), ('slack water from current samples [[0, 10, 20, 30, 40], [1.0, -1.0, 1.0, -1.0, 1.0]]', [[0, 10, 20, 30, 40], [1.0, -1.0, 1.0, -1.0, 1.0]], [[5, 'ebb-begins'], [15, 'flood-begins'], [25, 'ebb-begins'], [35, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120, 150, 180], [0.9, 0.4, 0.0, -0.3, -0.2, 0.0, 0.6]]', [[0, 30, 60, 90, 120, 150, 180], [0.9, 0.4, 0.0, -0.3, -0.2, 0.0, 0.6]], [[60, 'ebb-begins'], [150, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120, 150], [1.2, 0.8, 0.3, -0.4, -1.1, -1.5]]', [[0, 30, 60, 90, 120, 150], [1.2, 0.8, 0.3, -0.4, -1.1, -1.5]], [[73, 'ebb-begins']])], [('slack water from current samples [[0, 60, 120, 180, 240], [-0.9, -0.3, 0.2, 0.0, -0.4]]', [[0, 60, 120, 180, 240], [-0.9, -0.3, 0.2, 0.0, -0.4]], [[96, 'flood-begins'], [180, 'ebb-begins']]), ('slack water from current samples [[0, 10, 20, 30, 40], [1.0, -1.0, 1.0, -1.0, 1.0]]', [[0, 10, 20, 30, 40], [1.0, -1.0, 1.0, -1.0, 1.0]], [[5, 'ebb-begins'], [15, 'flood-begins'], [25, 'ebb-begins'], [35, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120, 150, 180], [0.9, 0.4, 0.0, -0.3, -0.2, 0.0, 0.6]]', [[0, 30, 60, 90, 120, 150, 180], [0.9, 0.4, 0.0, -0.3, -0.2, 0.0, 0.6]], [[60, 'ebb-begins'], [150, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120, 150], [1.2, 0.8, 0.3, -0.4, -1.1, -1.5]]', [[0, 30, 60, 90, 120, 150], [1.2, 0.8, 0.3, -0.4, -1.1, -1.5]], [[73, 'ebb-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120, 150], [-1.0, -0.5, 0.0, 0.0, 0.6, 1.0]]', [[0, 30, 60, 90, 120, 150], [-1.0, -0.5, 0.0, 0.0, 0.6, 1.0]], [[75, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120], [1.0, 0.0, 0.7, 1.2, 0.4]]', [[0, 30, 60, 90, 120], [1.0, 0.0, 0.7, 1.2, 0.4]], []), ('slack water from current samples [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]]', [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]], [[30, 'ebb-begins'], [90, 'flood-begins']])], [('slack water from current samples [[0, 15, 30, 45, 60], [0.5, 0.3, 0.1, -0.2, -0.3]]', [[0, 15, 30, 45, 60], [0.5, 0.3, 0.1, -0.2, -0.3]], [[35, 'ebb-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120, 150], [-1.0, -0.5, 0.0, 0.0, 0.6, 1.0]]', [[0, 30, 60, 90, 120, 150], [-1.0, -0.5, 0.0, 0.0, 0.6, 1.0]], [[75, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120], [1.0, 0.0, 0.7, 1.2, 0.4]]', [[0, 30, 60, 90, 120], [1.0, 0.0, 0.7, 1.2, 0.4]], []), ('slack water from current samples [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]]', [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]], [[30, 'ebb-begins'], [90, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90], [0.0, 0.0, 1.0, 2.0]]', [[0, 30, 60, 90], [0.0, 0.0, 1.0, 2.0]], []), ('slack water from current samples [[0, 60, 120, 180, 240], [-0.9, -0.3, 0.2, 0.0, -0.4]]', [[0, 60, 120, 180, 240], [-0.9, -0.3, 0.2, 0.0, -0.4]], [[96, 'flood-begins'], [180, 'ebb-begins']]), ('slack water from current samples [[0, 60, 120, 180], [1.0, 0.0, 0.0, -1.0]]', [[0, 60, 120, 180], [1.0, 0.0, 0.0, -1.0]], [[90, 'ebb-begins']])]]
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
slack water from current samples [[0, 30, 60, 90, 120, 150], [1.2, 0.8, 0.3, -0.4, -1.1, -1.5]][[45, 'ebb-begins']][[73, 'ebb-begins']]Failed
slack water from current samples [[0, 30, 60, 90, 120, 150], [-1.0, -0.5, 0.0, 0.0, 0.6, 1.0]][[60, 'flood-begins']][[75, 'flood-begins']]Failed
slack water from current samples [[0, 30, 60, 90, 120], [1.0, 0.0, 0.7, 1.2, 0.4]][][]Passed
slack water from current samples [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]][[20, 'ebb-begins'], [70, 'flood-begins']][[30, 'ebb-begins'], [90, 'flood-begins']]Failed
slack water from current samples [[0, 30, 60, 90], [0.0, 0.0, 1.0, 2.0]][][]Passed
slack water from current samples [[0, 60, 120, 180, 240], [-0.9, -0.3, 0.2, 0.0, -0.4]][[60, 'flood-begins'], [180, 'ebb-begins']][[96, 'flood-begins'], [180, 'ebb-begins']]Failed
slack water from current samples [[0, 15, 30, 45, 60], [0.5, 0.3, 0.1, -0.2, -0.3]][[23, 'ebb-begins']][[35, 'ebb-begins']]Failed

SHA-256 / a35366e113387427fa554d59b108b0e787f7986c9d4498ebbbc3783eef445b67

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,vs=x
    out=[]
    prev=None
    for k in range(len(vs)):
        if vs[k]==0: continue
        if prev is not None and (vs[prev]>0)!=(vs[k]>0):
            if k-prev>1:
                tc=(ts[prev+1]+ts[k-1])/2
            else:
                tc=ts[prev]+(ts[k]-ts[prev])*vs[prev]/(vs[prev]-vs[k])
            out.append([math.floor(tc+0.5),'flood-begins' if vs[k]>0 else 'ebb-begins'])
        prev=k
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('slack water from current samples [[0, 30, 60, 90, 120, 150], [1.2, 0.8, 0.3, -0.4, -1.1, -1.5]]', [[0, 30, 60, 90, 120, 150], [1.2, 0.8, 0.3, -0.4, -1.1, -1.5]], [[73, 'ebb-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120, 150], [-1.0, -0.5, 0.0, 0.0, 0.6, 1.0]]', [[0, 30, 60, 90, 120, 150], [-1.0, -0.5, 0.0, 0.0, 0.6, 1.0]], [[75, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120], [1.0, 0.0, 0.7, 1.2, 0.4]]', [[0, 30, 60, 90, 120], [1.0, 0.0, 0.7, 1.2, 0.4]], []), ('slack water from current samples [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]]', [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]], [[30, 'ebb-begins'], [90, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90], [0.0, 0.0, 1.0, 2.0]]', [[0, 30, 60, 90], [0.0, 0.0, 1.0, 2.0]], []), ('slack water from current samples [[0, 60, 120, 180, 240], [-0.9, -0.3, 0.2, 0.0, -0.4]]', [[0, 60, 120, 180, 240], [-0.9, -0.3, 0.2, 0.0, -0.4]], [[96, 'flood-begins'], [180, 'ebb-begins']]), ('slack water from current samples [[0, 15, 30, 45, 60], [0.5, 0.3, 0.1, -0.2, -0.3]]', [[0, 15, 30, 45, 60], [0.5, 0.3, 0.1, -0.2, -0.3]], [[35, 'ebb-begins']])], [('slack water from current samples [[0, 30, 60, 90, 120, 150], [-1.0, -0.5, 0.0, 0.0, 0.6, 1.0]]', [[0, 30, 60, 90, 120, 150], [-1.0, -0.5, 0.0, 0.0, 0.6, 1.0]], [[75, 'flood-begins']]), ('slack water from current samples [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]]', [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]], [[30, 'ebb-begins'], [90, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90], [0.0, 0.0, 1.0, 2.0]]', [[0, 30, 60, 90], [0.0, 0.0, 1.0, 2.0]], []), ('slack water from current samples [[0, 60, 120, 180, 240], [-0.9, -0.3, 0.2, 0.0, -0.4]]', [[0, 60, 120, 180, 240], [-0.9, -0.3, 0.2, 0.0, -0.4]], [[96, 'flood-begins'], [180, 'ebb-begins']]), ('slack water from current samples [[0, 15, 30, 45, 60], [0.5, 0.3, 0.1, -0.2, -0.3]]', [[0, 15, 30, 45, 60], [0.5, 0.3, 0.1, -0.2, -0.3]], [[35, 'ebb-begins']]), ('slack water from current samples [[0, 60, 120, 180], [1.0, 0.0, 0.0, -1.0]]', [[0, 60, 120, 180], [1.0, 0.0, 0.0, -1.0]], [[90, 'ebb-begins']]), ('slack water from current samples [[0, 60, 120], [-3.0, -1.0, 1.0]]', [[0, 60, 120], [-3.0, -1.0, 1.0]], [[90, 'flood-begins']])], [('slack water from current samples [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]]', [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]], [[30, 'ebb-begins'], [90, 'flood-begins']]), ('slack water from current samples [[0, 15, 30, 45, 60], [0.5, 0.3, 0.1, -0.2, -0.3]]', [[0, 15, 30, 45, 60], [0.5, 0.3, 0.1, -0.2, -0.3]], [[35, 'ebb-begins']]), ('slack water from current samples [[0, 60, 120, 180], [1.0, 0.0, 0.0, -1.0]]', [[0, 60, 120, 180], [1.0, 0.0, 0.0, -1.0]], [[90, 'ebb-begins']]), ('slack water from current samples [[0, 60, 120], [-3.0, -1.0, 1.0]]', [[0, 60, 120], [-3.0, -1.0, 1.0]], [[90, 'flood-begins']]), ('slack water from current samples [[0, 10, 20, 30, 40], [1.0, -1.0, 1.0, -1.0, 1.0]]', [[0, 10, 20, 30, 40], [1.0, -1.0, 1.0, -1.0, 1.0]], [[5, 'ebb-begins'], [15, 'flood-begins'], [25, 'ebb-begins'], [35, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120, 150, 180], [0.9, 0.4, 0.0, -0.3, -0.2, 0.0, 0.6]]', [[0, 30, 60, 90, 120, 150, 180], [0.9, 0.4, 0.0, -0.3, -0.2, 0.0, 0.6]], [[60, 'ebb-begins'], [150, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120, 150], [1.2, 0.8, 0.3, -0.4, -1.1, -1.5]]', [[0, 30, 60, 90, 120, 150], [1.2, 0.8, 0.3, -0.4, -1.1, -1.5]], [[73, 'ebb-begins']])], [('slack water from current samples [[0, 60, 120, 180, 240], [-0.9, -0.3, 0.2, 0.0, -0.4]]', [[0, 60, 120, 180, 240], [-0.9, -0.3, 0.2, 0.0, -0.4]], [[96, 'flood-begins'], [180, 'ebb-begins']]), ('slack water from current samples [[0, 10, 20, 30, 40], [1.0, -1.0, 1.0, -1.0, 1.0]]', [[0, 10, 20, 30, 40], [1.0, -1.0, 1.0, -1.0, 1.0]], [[5, 'ebb-begins'], [15, 'flood-begins'], [25, 'ebb-begins'], [35, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120, 150, 180], [0.9, 0.4, 0.0, -0.3, -0.2, 0.0, 0.6]]', [[0, 30, 60, 90, 120, 150, 180], [0.9, 0.4, 0.0, -0.3, -0.2, 0.0, 0.6]], [[60, 'ebb-begins'], [150, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120, 150], [1.2, 0.8, 0.3, -0.4, -1.1, -1.5]]', [[0, 30, 60, 90, 120, 150], [1.2, 0.8, 0.3, -0.4, -1.1, -1.5]], [[73, 'ebb-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120, 150], [-1.0, -0.5, 0.0, 0.0, 0.6, 1.0]]', [[0, 30, 60, 90, 120, 150], [-1.0, -0.5, 0.0, 0.0, 0.6, 1.0]], [[75, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120], [1.0, 0.0, 0.7, 1.2, 0.4]]', [[0, 30, 60, 90, 120], [1.0, 0.0, 0.7, 1.2, 0.4]], []), ('slack water from current samples [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]]', [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]], [[30, 'ebb-begins'], [90, 'flood-begins']])], [('slack water from current samples [[0, 15, 30, 45, 60], [0.5, 0.3, 0.1, -0.2, -0.3]]', [[0, 15, 30, 45, 60], [0.5, 0.3, 0.1, -0.2, -0.3]], [[35, 'ebb-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120, 150], [-1.0, -0.5, 0.0, 0.0, 0.6, 1.0]]', [[0, 30, 60, 90, 120, 150], [-1.0, -0.5, 0.0, 0.0, 0.6, 1.0]], [[75, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90, 120], [1.0, 0.0, 0.7, 1.2, 0.4]]', [[0, 30, 60, 90, 120], [1.0, 0.0, 0.7, 1.2, 0.4]], []), ('slack water from current samples [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]]', [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]], [[30, 'ebb-begins'], [90, 'flood-begins']]), ('slack water from current samples [[0, 30, 60, 90], [0.0, 0.0, 1.0, 2.0]]', [[0, 30, 60, 90], [0.0, 0.0, 1.0, 2.0]], []), ('slack water from current samples [[0, 60, 120, 180, 240], [-0.9, -0.3, 0.2, 0.0, -0.4]]', [[0, 60, 120, 180, 240], [-0.9, -0.3, 0.2, 0.0, -0.4]], [[96, 'flood-begins'], [180, 'ebb-begins']]), ('slack water from current samples [[0, 60, 120, 180], [1.0, 0.0, 0.0, -1.0]]', [[0, 60, 120, 180], [1.0, 0.0, 0.0, -1.0]], [[90, 'ebb-begins']])]]
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
slack water from current samples [[0, 30, 60, 90, 120, 150], [1.2, 0.8, 0.3, -0.4, -1.1, -1.5]][[73, 'ebb-begins']][[73, 'ebb-begins']]Passed
slack water from current samples [[0, 30, 60, 90, 120, 150], [-1.0, -0.5, 0.0, 0.0, 0.6, 1.0]][[75, 'flood-begins']][[75, 'flood-begins']]Passed
slack water from current samples [[0, 30, 60, 90, 120], [1.0, 0.0, 0.7, 1.2, 0.4]][][]Passed
slack water from current samples [[0, 20, 40, 60, 80, 100, 120], [2.0, 1.0, -1.0, -2.0, -0.5, 0.5, 1.5]][[30, 'ebb-begins'], [90, 'flood-begins']][[30, 'ebb-begins'], [90, 'flood-begins']]Passed
slack water from current samples [[0, 30, 60, 90], [0.0, 0.0, 1.0, 2.0]][][]Passed
slack water from current samples [[0, 60, 120, 180, 240], [-0.9, -0.3, 0.2, 0.0, -0.4]][[96, 'flood-begins'], [180, 'ebb-begins']][[96, 'flood-begins'], [180, 'ebb-begins']]Passed
slack water from current samples [[0, 15, 30, 45, 60], [0.5, 0.3, 0.1, -0.2, -0.3]][[35, 'ebb-begins']][[35, 'ebb-begins']]Passed

SHA-256 / 6ede038d22bbe352e9437b4365bd321892a64a82a85b9dfb73ae3c05cd0ca163

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

Case digest / d89bf7a3e045dc54576fc7e33a6a6e294b3bb46687f84f3941d5ff73636ef112