broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(sustained_kt, gust_kt):
    bounds = [0.5, 1.6, 3.4, 5.5, 8.0, 10.8, 13.9, 17.2, 20.8, 24.5, 28.5, 32.7]
    def force(kt):
        ms = round(kt * 0.514444, 1)
        for n, upper in enumerate(bounds):
            if ms <= upper:
                return n
        return 12
    b = force(sustained_kt)
    g = force(gust_kt)
    if g >= b + 2 and b < 12:
        b += 1
    if b < 6:
        warn = "none"
    elif b < 8:
        warn = "small craft"
    elif b < 10:
        warn = "gale"
    elif b < 12:
        warn = "storm"
    else:
        warn = "hurricane force"
    return [b, warn]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['sustained 0 kt gust +0', [0, 0], [0, 'none']], ['sustained 0 kt gust +2', [0, 2], [0, 'none']], ['sustained 0 kt gust +8', [0, 8], [1, 'none']], ['sustained 0 kt gust +16', [0, 16], [1, 'none']], ['sustained 0.9 kt gust +0', [0.9, 0.9], [1, 'none']], ['sustained 0.9 kt gust +2', [0.9, 2.9], [1, 'none']], ['sustained 0.9 kt gust +8', [0.9, 8.9], [2, 'none']], ['sustained 3 kt gust +2', [3, 5], [1, 'none']]], [['sustained 0.9 kt gust +16', [0.9, 16.9], [2, 'none']], ['sustained 1 kt gust +0', [1, 1], [1, 'none']], ['sustained 1 kt gust +2', [1, 3], [1, 'none']], ['sustained 1 kt gust +8', [1, 9], [2, 'none']], ['sustained 1 kt gust +16', [1, 17], [2, 'none']], ['sustained 3 kt gust +0', [3, 3], [1, 'none']], ['sustained 3 kt gust +2', [3, 5], [1, 'none']], ['sustained 55.3 kt gust +8', [55.3, 63.3], [10, 'storm']]], [['sustained 1 kt gust +8', [1, 9], [2, 'none']], ['sustained 3 kt gust +8', [3, 11], [2, 'none']], ['sustained 3 kt gust +16', [3, 19], [2, 'none']], ['sustained 6.6 kt gust +0', [6.6, 6.6], [3, 'none']], ['sustained 6.6 kt gust +2', [6.6, 8.6], [3, 'none']], ['sustained 6.6 kt gust +8', [6.6, 14.6], [3, 'none']], ['sustained 6.6 kt gust +16', [6.6, 22.6], [4, 'none']], ['sustained 55.3 kt gust +0', [55.3, 55.3], [10, 'storm']]], [['sustained 3 kt gust +8', [3, 11], [2, 'none']], ['sustained 6.6 kt gust +2', [6.6, 8.6], [3, 'none']], ['sustained 10.7 kt gust +2', [10.7, 12.7], [4, 'none']], ['sustained 10.7 kt gust +8', [10.7, 18.7], [4, 'none']], ['sustained 10.7 kt gust +16', [10.7, 26.7], [5, 'none']], ['sustained 16 kt gust +0', [16, 16], [5, 'none']], ['sustained 16 kt gust +2', [16, 18], [5, 'none']], ['sustained 16 kt gust +8', [16, 24], [5, 'none']]], [['sustained 3 kt gust +0', [3, 3], [1, 'none']], ['sustained 10.7 kt gust +2', [10.7, 12.7], [4, 'none']], ['sustained 21 kt gust +0', [21, 21], [6, 'small craft']], ['sustained 21 kt gust +2', [21, 23], [6, 'small craft']], ['sustained 21 kt gust +8', [21, 29], [6, 'small craft']], ['sustained 21 kt gust +16', [21, 37], [7, 'small craft']], ['sustained 27 kt gust +0', [27, 27], [7, 'small craft']], ['sustained 27 kt gust +2', [27, 29], [7, 'small craft']]]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(sustained_kt, gust_kt):
    bounds = [0.5, 1.6, 3.4, 5.5, 8.0, 10.8, 13.9, 17.2, 20.8, 24.5, 28.5, 32.7]
    def force(kt):
        ms = round(kt * 0.514444, 1)
        for n, upper in enumerate(bounds):
            if ms < upper - 0.1:
                return n
        return 12
    b = force(sustained_kt)
    g = force(gust_kt)
    if g >= b + 2 and b < 12:
        b += 1
    if b < 6:
        warn = "none"
    elif b < 8:
        warn = "small craft"
    elif b < 10:
        warn = "gale"
    elif b < 12:
        warn = "storm"
    else:
        warn = "hurricane force"
    return [b, warn]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['sustained 0 kt gust +0', [0, 0], [0, 'none']], ['sustained 0 kt gust +2', [0, 2], [0, 'none']], ['sustained 0 kt gust +8', [0, 8], [1, 'none']], ['sustained 0 kt gust +16', [0, 16], [1, 'none']], ['sustained 0.9 kt gust +0', [0.9, 0.9], [1, 'none']], ['sustained 0.9 kt gust +2', [0.9, 2.9], [1, 'none']], ['sustained 0.9 kt gust +8', [0.9, 8.9], [2, 'none']], ['sustained 3 kt gust +2', [3, 5], [1, 'none']]], [['sustained 0.9 kt gust +16', [0.9, 16.9], [2, 'none']], ['sustained 1 kt gust +0', [1, 1], [1, 'none']], ['sustained 1 kt gust +2', [1, 3], [1, 'none']], ['sustained 1 kt gust +8', [1, 9], [2, 'none']], ['sustained 1 kt gust +16', [1, 17], [2, 'none']], ['sustained 3 kt gust +0', [3, 3], [1, 'none']], ['sustained 3 kt gust +2', [3, 5], [1, 'none']], ['sustained 55.3 kt gust +8', [55.3, 63.3], [10, 'storm']]], [['sustained 1 kt gust +8', [1, 9], [2, 'none']], ['sustained 3 kt gust +8', [3, 11], [2, 'none']], ['sustained 3 kt gust +16', [3, 19], [2, 'none']], ['sustained 6.6 kt gust +0', [6.6, 6.6], [3, 'none']], ['sustained 6.6 kt gust +2', [6.6, 8.6], [3, 'none']], ['sustained 6.6 kt gust +8', [6.6, 14.6], [3, 'none']], ['sustained 6.6 kt gust +16', [6.6, 22.6], [4, 'none']], ['sustained 55.3 kt gust +0', [55.3, 55.3], [10, 'storm']]], [['sustained 3 kt gust +8', [3, 11], [2, 'none']], ['sustained 6.6 kt gust +2', [6.6, 8.6], [3, 'none']], ['sustained 10.7 kt gust +2', [10.7, 12.7], [4, 'none']], ['sustained 10.7 kt gust +8', [10.7, 18.7], [4, 'none']], ['sustained 10.7 kt gust +16', [10.7, 26.7], [5, 'none']], ['sustained 16 kt gust +0', [16, 16], [5, 'none']], ['sustained 16 kt gust +2', [16, 18], [5, 'none']], ['sustained 16 kt gust +8', [16, 24], [5, 'none']]], [['sustained 3 kt gust +0', [3, 3], [1, 'none']], ['sustained 10.7 kt gust +2', [10.7, 12.7], [4, 'none']], ['sustained 21 kt gust +0', [21, 21], [6, 'small craft']], ['sustained 21 kt gust +2', [21, 23], [6, 'small craft']], ['sustained 21 kt gust +8', [21, 29], [6, 'small craft']], ['sustained 21 kt gust +16', [21, 37], [7, 'small craft']], ['sustained 27 kt gust +0', [27, 27], [7, 'small craft']], ['sustained 27 kt gust +2', [27, 29], [7, 'small craft']]]]
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)

prompt:
A wind of exactly 17.2 m/s is reported as force 7.

Convert knots to m/s (x0.514444) and round to 0.1 m/s. Beaufort force n is the first n with speed < bounds[n], bounds=[0.5,1.6,3.4,5.5,8.0,10.8,13.9,17.2,20.8,24.5,28.5,32.7], else 12. If the gust force is at least sustained force + 2 (and force < 12) upgrade by one. Warning: <6 none, <8 small craft, <10 gale, <12 storm, 12 hurricane force. Return [force, warning].

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(sustained_kt, gust_kt):
    bounds = [0.5, 1.6, 3.4, 5.5, 8.0, 10.8, 13.9, 17.2, 20.8, 24.5, 28.5, 32.7]
    def force(kt):
        ms = round(kt * 0.514444, 1)
        for n, upper in enumerate(bounds):
            if ms < upper:
                return n
        return 12
    b = force(sustained_kt)
    g = force(gust_kt)
    if g >= b + 1 and b < 12:
        b += 1
    if b < 6:
        warn = "none"
    elif b < 8:
        warn = "small craft"
    elif b < 10:
        warn = "gale"
    elif b < 12:
        warn = "storm"
    else:
        warn = "hurricane force"
    return [b, warn]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['sustained 0 kt gust +0', [0, 0], [0, 'none']], ['sustained 0 kt gust +2', [0, 2], [0, 'none']], ['sustained 0 kt gust +8', [0, 8], [1, 'none']], ['sustained 0 kt gust +16', [0, 16], [1, 'none']], ['sustained 0.9 kt gust +0', [0.9, 0.9], [1, 'none']], ['sustained 0.9 kt gust +2', [0.9, 2.9], [1, 'none']], ['sustained 0.9 kt gust +8', [0.9, 8.9], [2, 'none']], ['sustained 1 kt gust +8', [1, 9], [2, 'none']]], [['sustained 0.9 kt gust +16', [0.9, 16.9], [2, 'none']], ['sustained 1 kt gust +0', [1, 1], [1, 'none']], ['sustained 1 kt gust +2', [1, 3], [1, 'none']], ['sustained 1 kt gust +8', [1, 9], [2, 'none']], ['sustained 1 kt gust +16', [1, 17], [2, 'none']], ['sustained 3 kt gust +0', [3, 3], [1, 'none']], ['sustained 10.7 kt gust +8', [10.7, 18.7], [4, 'none']], ['sustained 33.4 kt gust +16', [33.4, 49.4], [9, 'gale']]], [['sustained 3 kt gust +8', [3, 11], [2, 'none']], ['sustained 3 kt gust +16', [3, 19], [2, 'none']], ['sustained 6.6 kt gust +0', [6.6, 6.6], [3, 'none']], ['sustained 6.6 kt gust +2', [6.6, 8.6], [3, 'none']], ['sustained 6.6 kt gust +8', [6.6, 14.6], [3, 'none']], ['sustained 6.6 kt gust +16', [6.6, 22.6], [4, 'none']], ['sustained 27 kt gust +8', [27, 35], [7, 'small craft']], ['sustained 48 kt gust +16', [48, 64], [11, 'storm']]], [['sustained 10.7 kt gust +2', [10.7, 12.7], [4, 'none']], ['sustained 10.7 kt gust +8', [10.7, 18.7], [4, 'none']], ['sustained 10.7 kt gust +16', [10.7, 26.7], [5, 'none']], ['sustained 16 kt gust +0', [16, 16], [5, 'none']], ['sustained 16 kt gust +2', [16, 18], [5, 'none']], ['sustained 16 kt gust +8', [16, 24], [5, 'none']], ['sustained 16 kt gust +16', [16, 32], [6, 'small craft']], ['sustained 40.4 kt gust +8', [40.4, 48.4], [9, 'gale']]], [['sustained 21 kt gust +0', [21, 21], [6, 'small craft']], ['sustained 21 kt gust +2', [21, 23], [6, 'small craft']], ['sustained 21 kt gust +8', [21, 29], [6, 'small craft']], ['sustained 21 kt gust +16', [21, 37], [7, 'small craft']], ['sustained 27 kt gust +0', [27, 27], [7, 'small craft']], ['sustained 27 kt gust +2', [27, 29], [7, 'small craft']], ['sustained 40.4 kt gust +16', [40.4, 56.4], [10, 'storm']], ['sustained 48 kt gust +8', [48, 56], [10, 'storm']]]]
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)

meaning: Fixture-count band, not measured model difficulty

deps: stdlib

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(sustained_kt, gust_kt):
    bounds = [0.5, 1.6, 3.4, 5.5, 8.0, 10.8, 13.9, 17.2, 20.8, 24.5, 28.5, 32.7]
    def force(kt):
        ms = round(kt * 0.514444, 1)
        for n, upper in enumerate(bounds):
            if ms < upper:
                return n
        return 12
    b = force(sustained_kt)
    g = force(gust_kt)
    if g > b + 2 and b < 12:
        b += 1
    if b < 6:
        warn = "none"
    elif b < 8:
        warn = "small craft"
    elif b < 10:
        warn = "gale"
    elif b < 12:
        warn = "storm"
    else:
        warn = "hurricane force"
    return [b, warn]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['sustained 0 kt gust +0', [0, 0], [0, 'none']], ['sustained 0 kt gust +2', [0, 2], [0, 'none']], ['sustained 0 kt gust +8', [0, 8], [1, 'none']], ['sustained 0 kt gust +16', [0, 16], [1, 'none']], ['sustained 0.9 kt gust +0', [0.9, 0.9], [1, 'none']], ['sustained 0.9 kt gust +2', [0.9, 2.9], [1, 'none']], ['sustained 0.9 kt gust +8', [0.9, 8.9], [2, 'none']], ['sustained 1 kt gust +8', [1, 9], [2, 'none']]], [['sustained 0.9 kt gust +16', [0.9, 16.9], [2, 'none']], ['sustained 1 kt gust +0', [1, 1], [1, 'none']], ['sustained 1 kt gust +2', [1, 3], [1, 'none']], ['sustained 1 kt gust +8', [1, 9], [2, 'none']], ['sustained 1 kt gust +16', [1, 17], [2, 'none']], ['sustained 3 kt gust +0', [3, 3], [1, 'none']], ['sustained 10.7 kt gust +8', [10.7, 18.7], [4, 'none']], ['sustained 33.4 kt gust +16', [33.4, 49.4], [9, 'gale']]], [['sustained 3 kt gust +8', [3, 11], [2, 'none']], ['sustained 3 kt gust +16', [3, 19], [2, 'none']], ['sustained 6.6 kt gust +0', [6.6, 6.6], [3, 'none']], ['sustained 6.6 kt gust +2', [6.6, 8.6], [3, 'none']], ['sustained 6.6 kt gust +8', [6.6, 14.6], [3, 'none']], ['sustained 6.6 kt gust +16', [6.6, 22.6], [4, 'none']], ['sustained 27 kt gust +8', [27, 35], [7, 'small craft']], ['sustained 48 kt gust +16', [48, 64], [11, 'storm']]], [['sustained 10.7 kt gust +2', [10.7, 12.7], [4, 'none']], ['sustained 10.7 kt gust +8', [10.7, 18.7], [4, 'none']], ['sustained 10.7 kt gust +16', [10.7, 26.7], [5, 'none']], ['sustained 16 kt gust +0', [16, 16], [5, 'none']], ['sustained 16 kt gust +2', [16, 18], [5, 'none']], ['sustained 16 kt gust +8', [16, 24], [5, 'none']], ['sustained 16 kt gust +16', [16, 32], [6, 'small craft']], ['sustained 40.4 kt gust +8', [40.4, 48.4], [9, 'gale']]], [['sustained 21 kt gust +0', [21, 21], [6, 'small craft']], ['sustained 21 kt gust +2', [21, 23], [6, 'small craft']], ['sustained 21 kt gust +8', [21, 29], [6, 'small craft']], ['sustained 21 kt gust +16', [21, 37], [7, 'small craft']], ['sustained 27 kt gust +0', [27, 27], [7, 'small craft']], ['sustained 27 kt gust +2', [27, 29], [7, 'small craft']], ['sustained 40.4 kt gust +16', [40.4, 56.4], [10, 'storm']], ['sustained 48 kt gust +8', [48, 56], [10, 'storm']]]]
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)

prompt:
Ordinary gustiness upgrades nearly every warning.

Convert knots to m/s (x0.514444) and round to 0.1 m/s. Beaufort force n is the first n with speed < bounds[n], bounds=[0.5,1.6,3.4,5.5,8.0,10.8,13.9,17.2,20.8,24.5,28.5,32.7], else 12. If the gust force is at least sustained force + 2 (and force < 12) upgrade by one. Warning: <6 none, <8 small craft, <10 gale, <12 storm, 12 hurricane force. Return [force, warning].

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(sustained_kt, gust_kt):
    bounds = [0.5, 1.6, 3.4, 5.5, 8.0, 10.8, 13.9, 17.2, 20.8, 24.5, 28.5, 32.7]
    def force(kt):
        ms = round(kt * 0.514444, 1)
        for n, upper in enumerate(bounds):
            if ms < upper:
                return n
        return 12
    b = force(sustained_kt)
    g = force(gust_kt)
    if g >= b + 2 and b < 12:
        b += 1
    if b < 6:
        warn = "none"
    elif b <= 8:
        warn = "small craft"
    elif b < 10:
        warn = "gale"
    elif b < 12:
        warn = "storm"
    else:
        warn = "hurricane force"
    return [b, warn]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['sustained 0 kt gust +0', [0, 0], [0, 'none']], ['sustained 0 kt gust +2', [0, 2], [0, 'none']], ['sustained 0 kt gust +8', [0, 8], [1, 'none']], ['sustained 0 kt gust +16', [0, 16], [1, 'none']], ['sustained 0.9 kt gust +0', [0.9, 0.9], [1, 'none']], ['sustained 0.9 kt gust +2', [0.9, 2.9], [1, 'none']], ['sustained 27 kt gust +8', [27, 35], [7, 'small craft']], ['sustained 27 kt gust +16', [27, 43], [8, 'gale']]], [['sustained 0.9 kt gust +16', [0.9, 16.9], [2, 'none']], ['sustained 1 kt gust +0', [1, 1], [1, 'none']], ['sustained 1 kt gust +2', [1, 3], [1, 'none']], ['sustained 1 kt gust +8', [1, 9], [2, 'none']], ['sustained 1 kt gust +16', [1, 17], [2, 'none']], ['sustained 3 kt gust +0', [3, 3], [1, 'none']], ['sustained 21 kt gust +16', [21, 37], [7, 'small craft']], ['sustained 33.4 kt gust +8', [33.4, 41.4], [8, 'gale']]], [['sustained 3 kt gust +8', [3, 11], [2, 'none']], ['sustained 3 kt gust +16', [3, 19], [2, 'none']], ['sustained 6.6 kt gust +0', [6.6, 6.6], [3, 'none']], ['sustained 6.6 kt gust +2', [6.6, 8.6], [3, 'none']], ['sustained 6.6 kt gust +8', [6.6, 14.6], [3, 'none']], ['sustained 6.6 kt gust +16', [6.6, 22.6], [4, 'none']], ['sustained 27 kt gust +8', [27, 35], [7, 'small craft']], ['sustained 34 kt gust +8', [34, 42], [8, 'gale']]], [['sustained 10.7 kt gust +2', [10.7, 12.7], [4, 'none']], ['sustained 10.7 kt gust +8', [10.7, 18.7], [4, 'none']], ['sustained 10.7 kt gust +16', [10.7, 26.7], [5, 'none']], ['sustained 16 kt gust +0', [16, 16], [5, 'none']], ['sustained 16 kt gust +2', [16, 18], [5, 'none']], ['sustained 16 kt gust +8', [16, 24], [5, 'none']], ['sustained 21 kt gust +16', [21, 37], [7, 'small craft']], ['sustained 33.4 kt gust +2', [33.4, 35.4], [8, 'gale']]], [['sustained 21 kt gust +0', [21, 21], [6, 'small craft']], ['sustained 21 kt gust +2', [21, 23], [6, 'small craft']], ['sustained 21 kt gust +8', [21, 29], [6, 'small craft']], ['sustained 21 kt gust +16', [21, 37], [7, 'small craft']], ['sustained 27 kt gust +0', [27, 27], [7, 'small craft']], ['sustained 27 kt gust +2', [27, 29], [7, 'small craft']], ['sustained 27 kt gust +8', [27, 35], [7, 'small craft']], ['sustained 34 kt gust +2', [34, 36], [8, 'gale']]]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(sustained_kt, gust_kt):
    bounds = [0.5, 1.6, 3.4, 5.5, 8.0, 10.8, 13.9, 17.2, 20.8, 24.5, 28.5, 32.7]
    def force(kt):
        ms = round(kt * 0.514444, 1)
        for n, upper in enumerate(bounds):
            if ms < upper:
                return n
        return 12
    b = force(sustained_kt)
    g = force(gust_kt)
    if g >= b + 2 and b < 12:
        b += 1
    if b < 6:
        warn = "none"
    elif g < 8:
        warn = "small craft"
    elif b < 10:
        warn = "gale"
    elif b < 12:
        warn = "storm"
    else:
        warn = "hurricane force"
    return [b, warn]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['sustained 0 kt gust +0', [0, 0], [0, 'none']], ['sustained 0 kt gust +2', [0, 2], [0, 'none']], ['sustained 0 kt gust +8', [0, 8], [1, 'none']], ['sustained 0 kt gust +16', [0, 16], [1, 'none']], ['sustained 0.9 kt gust +0', [0.9, 0.9], [1, 'none']], ['sustained 0.9 kt gust +2', [0.9, 2.9], [1, 'none']], ['sustained 27 kt gust +8', [27, 35], [7, 'small craft']], ['sustained 27 kt gust +16', [27, 43], [8, 'gale']]], [['sustained 0.9 kt gust +16', [0.9, 16.9], [2, 'none']], ['sustained 1 kt gust +0', [1, 1], [1, 'none']], ['sustained 1 kt gust +2', [1, 3], [1, 'none']], ['sustained 1 kt gust +8', [1, 9], [2, 'none']], ['sustained 1 kt gust +16', [1, 17], [2, 'none']], ['sustained 3 kt gust +0', [3, 3], [1, 'none']], ['sustained 21 kt gust +16', [21, 37], [7, 'small craft']], ['sustained 33.4 kt gust +8', [33.4, 41.4], [8, 'gale']]], [['sustained 3 kt gust +8', [3, 11], [2, 'none']], ['sustained 3 kt gust +16', [3, 19], [2, 'none']], ['sustained 6.6 kt gust +0', [6.6, 6.6], [3, 'none']], ['sustained 6.6 kt gust +2', [6.6, 8.6], [3, 'none']], ['sustained 6.6 kt gust +8', [6.6, 14.6], [3, 'none']], ['sustained 6.6 kt gust +16', [6.6, 22.6], [4, 'none']], ['sustained 27 kt gust +8', [27, 35], [7, 'small craft']], ['sustained 34 kt gust +8', [34, 42], [8, 'gale']]], [['sustained 10.7 kt gust +2', [10.7, 12.7], [4, 'none']], ['sustained 10.7 kt gust +8', [10.7, 18.7], [4, 'none']], ['sustained 10.7 kt gust +16', [10.7, 26.7], [5, 'none']], ['sustained 16 kt gust +0', [16, 16], [5, 'none']], ['sustained 16 kt gust +2', [16, 18], [5, 'none']], ['sustained 16 kt gust +8', [16, 24], [5, 'none']], ['sustained 21 kt gust +16', [21, 37], [7, 'small craft']], ['sustained 33.4 kt gust +2', [33.4, 35.4], [8, 'gale']]], [['sustained 21 kt gust +0', [21, 21], [6, 'small craft']], ['sustained 21 kt gust +2', [21, 23], [6, 'small craft']], ['sustained 21 kt gust +8', [21, 29], [6, 'small craft']], ['sustained 21 kt gust +16', [21, 37], [7, 'small craft']], ['sustained 27 kt gust +0', [27, 27], [7, 'small craft']], ['sustained 27 kt gust +2', [27, 29], [7, 'small craft']], ['sustained 27 kt gust +8', [27, 35], [7, 'small craft']], ['sustained 34 kt gust +2', [34, 36], [8, 'gale']]]]
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)

prompt:
Force 8 winds only raise a small-craft advisory instead of a gale warning.

Convert knots to m/s (x0.514444) and round to 0.1 m/s. Beaufort force n is the first n with speed < bounds[n], bounds=[0.5,1.6,3.4,5.5,8.0,10.8,13.9,17.2,20.8,24.5,28.5,32.7], else 12. If the gust force is at least sustained force + 2 (and force < 12) upgrade by one. Warning: <6 none, <8 small craft, <10 gale, <12 storm, 12 hurricane force. Return [force, warning].

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(sustained_kt, gust_kt):
    bounds = [0.5, 1.6, 3.4, 5.5, 8.0, 10.8, 13.9, 17.2, 20.8, 24.5, 28.5, 32.7]
    def force(kt):
        ms = kt * 0.514444
        for n, upper in enumerate(bounds):
            if ms < upper:
                return n
        return 12
    b = force(sustained_kt)
    g = force(gust_kt)
    if g >= b + 2 and b < 12:
        b += 1
    if b < 6:
        warn = "none"
    elif b < 8:
        warn = "small craft"
    elif b < 10:
        warn = "gale"
    elif b < 12:
        warn = "storm"
    else:
        warn = "hurricane force"
    return [b, warn]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['sustained 0 kt gust +0', [0, 0], [0, 'none']], ['sustained 0 kt gust +2', [0, 2], [0, 'none']], ['sustained 0 kt gust +8', [0, 8], [1, 'none']], ['sustained 0 kt gust +16', [0, 16], [1, 'none']], ['sustained 0.9 kt gust +0', [0.9, 0.9], [1, 'none']], ['sustained 0.9 kt gust +2', [0.9, 2.9], [1, 'none']], ['sustained 0.9 kt gust +8', [0.9, 8.9], [2, 'none']], ['sustained 0.9 kt gust +16', [0.9, 16.9], [2, 'none']]], [['sustained 0.9 kt gust +16', [0.9, 16.9], [2, 'none']], ['sustained 1 kt gust +0', [1, 1], [1, 'none']], ['sustained 1 kt gust +2', [1, 3], [1, 'none']], ['sustained 1 kt gust +8', [1, 9], [2, 'none']], ['sustained 1 kt gust +16', [1, 17], [2, 'none']], ['sustained 3 kt gust +0', [3, 3], [1, 'none']], ['sustained 3 kt gust +2', [3, 5], [1, 'none']], ['sustained 6.6 kt gust +16', [6.6, 22.6], [4, 'none']]], [['sustained 3 kt gust +8', [3, 11], [2, 'none']], ['sustained 3 kt gust +16', [3, 19], [2, 'none']], ['sustained 6.6 kt gust +0', [6.6, 6.6], [3, 'none']], ['sustained 6.6 kt gust +2', [6.6, 8.6], [3, 'none']], ['sustained 6.6 kt gust +8', [6.6, 14.6], [3, 'none']], ['sustained 6.6 kt gust +16', [6.6, 22.6], [4, 'none']], ['sustained 10.7 kt gust +0', [10.7, 10.7], [4, 'none']], ['sustained 33.4 kt gust +2', [33.4, 35.4], [8, 'gale']]], [['sustained 10.7 kt gust +2', [10.7, 12.7], [4, 'none']], ['sustained 10.7 kt gust +8', [10.7, 18.7], [4, 'none']], ['sustained 10.7 kt gust +16', [10.7, 26.7], [5, 'none']], ['sustained 16 kt gust +0', [16, 16], [5, 'none']], ['sustained 16 kt gust +2', [16, 18], [5, 'none']], ['sustained 16 kt gust +8', [16, 24], [5, 'none']], ['sustained 27 kt gust +16', [27, 43], [8, 'gale']], ['sustained 47.6 kt gust +0', [47.6, 47.6], [10, 'storm']]], [['sustained 0.9 kt gust +8', [0.9, 8.9], [2, 'none']], ['sustained 21 kt gust +0', [21, 21], [6, 'small craft']], ['sustained 21 kt gust +2', [21, 23], [6, 'small craft']], ['sustained 21 kt gust +8', [21, 29], [6, 'small craft']], ['sustained 21 kt gust +16', [21, 37], [7, 'small craft']], ['sustained 27 kt gust +0', [27, 27], [7, 'small craft']], ['sustained 27 kt gust +2', [27, 29], [7, 'small craft']], ['sustained 33.4 kt gust +16', [33.4, 49.4], [9, 'gale']]]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(sustained_kt, gust_kt):
    bounds = [0.5, 1.6, 3.4, 5.5, 8.0, 10.8, 13.9, 17.2, 20.8, 24.5, 28.5, 32.7]
    def force(kt):
        ms = int(kt * 0.514444 * 10) / 10
        for n, upper in enumerate(bounds):
            if ms < upper:
                return n
        return 12
    b = force(sustained_kt)
    g = force(gust_kt)
    if g >= b + 2 and b < 12:
        b += 1
    if b < 6:
        warn = "none"
    elif b < 8:
        warn = "small craft"
    elif b < 10:
        warn = "gale"
    elif b < 12:
        warn = "storm"
    else:
        warn = "hurricane force"
    return [b, warn]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['sustained 0 kt gust +0', [0, 0], [0, 'none']], ['sustained 0 kt gust +2', [0, 2], [0, 'none']], ['sustained 0 kt gust +8', [0, 8], [1, 'none']], ['sustained 0 kt gust +16', [0, 16], [1, 'none']], ['sustained 0.9 kt gust +0', [0.9, 0.9], [1, 'none']], ['sustained 0.9 kt gust +2', [0.9, 2.9], [1, 'none']], ['sustained 0.9 kt gust +8', [0.9, 8.9], [2, 'none']], ['sustained 0.9 kt gust +16', [0.9, 16.9], [2, 'none']]], [['sustained 0.9 kt gust +16', [0.9, 16.9], [2, 'none']], ['sustained 1 kt gust +0', [1, 1], [1, 'none']], ['sustained 1 kt gust +2', [1, 3], [1, 'none']], ['sustained 1 kt gust +8', [1, 9], [2, 'none']], ['sustained 1 kt gust +16', [1, 17], [2, 'none']], ['sustained 3 kt gust +0', [3, 3], [1, 'none']], ['sustained 3 kt gust +2', [3, 5], [1, 'none']], ['sustained 6.6 kt gust +16', [6.6, 22.6], [4, 'none']]], [['sustained 3 kt gust +8', [3, 11], [2, 'none']], ['sustained 3 kt gust +16', [3, 19], [2, 'none']], ['sustained 6.6 kt gust +0', [6.6, 6.6], [3, 'none']], ['sustained 6.6 kt gust +2', [6.6, 8.6], [3, 'none']], ['sustained 6.6 kt gust +8', [6.6, 14.6], [3, 'none']], ['sustained 6.6 kt gust +16', [6.6, 22.6], [4, 'none']], ['sustained 10.7 kt gust +0', [10.7, 10.7], [4, 'none']], ['sustained 33.4 kt gust +2', [33.4, 35.4], [8, 'gale']]], [['sustained 10.7 kt gust +2', [10.7, 12.7], [4, 'none']], ['sustained 10.7 kt gust +8', [10.7, 18.7], [4, 'none']], ['sustained 10.7 kt gust +16', [10.7, 26.7], [5, 'none']], ['sustained 16 kt gust +0', [16, 16], [5, 'none']], ['sustained 16 kt gust +2', [16, 18], [5, 'none']], ['sustained 16 kt gust +8', [16, 24], [5, 'none']], ['sustained 27 kt gust +16', [27, 43], [8, 'gale']], ['sustained 47.6 kt gust +0', [47.6, 47.6], [10, 'storm']]], [['sustained 0.9 kt gust +8', [0.9, 8.9], [2, 'none']], ['sustained 21 kt gust +0', [21, 21], [6, 'small craft']], ['sustained 21 kt gust +2', [21, 23], [6, 'small craft']], ['sustained 21 kt gust +8', [21, 29], [6, 'small craft']], ['sustained 21 kt gust +16', [21, 37], [7, 'small craft']], ['sustained 27 kt gust +0', [27, 27], [7, 'small craft']], ['sustained 27 kt gust +2', [27, 29], [7, 'small craft']], ['sustained 33.4 kt gust +16', [33.4, 49.4], [9, 'gale']]]]
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)

prompt:
A 33.4 kt wind (17.18 m/s, reported 17.2) is classified force 7.

Convert knots to m/s (x0.514444) and round to 0.1 m/s. Beaufort force n is the first n with speed < bounds[n], bounds=[0.5,1.6,3.4,5.5,8.0,10.8,13.9,17.2,20.8,24.5,28.5,32.7], else 12. If the gust force is at least sustained force + 2 (and force < 12) upgrade by one. Warning: <6 none, <8 small craft, <10 gale, <12 storm, 12 hurricane force. Return [force, warning].

split: open-access


prompt:
Mid-elevation Haines values disagree with the published mid variant.

temps/dews map pressure level (hPa) to degC. low: stability T950-T850 (<=3:1, <=7:2, else 3), moisture T850-Td850 (<=5:1, <=9:2, else 3); mid: T850-T700 (<=5, <=10), T850-Td850 (<=5, <=12); high: T700-T500 (<=17, <=21), T700-Td700 (<=14, <=20). Unknown elevation returns None. Return [sum, label] with 2-3 very low, 4 low, 5 moderate, 6 high.

split: open-access


prompt:
Strong lapse rates score as stable while inversions score as unstable.

temps/dews map pressure level (hPa) to degC. low: stability T950-T850 (<=3:1, <=7:2, else 3), moisture T850-Td850 (<=5:1, <=9:2, else 3); mid: T850-T700 (<=5, <=10), T850-Td850 (<=5, <=12); high: T700-T500 (<=17, <=21), T700-Td700 (<=14, <=20). Unknown elevation returns None. Return [sum, label] with 2-3 very low, 4 low, 5 moderate, 6 high.

split: open-access


prompt:
Soundings exactly on a stability breakpoint are scored one category too high.

temps/dews map pressure level (hPa) to degC. low: stability T950-T850 (<=3:1, <=7:2, else 3), moisture T850-Td850 (<=5:1, <=9:2, else 3); mid: T850-T700 (<=5, <=10), T850-Td850 (<=5, <=12); high: T700-T500 (<=17, <=21), T700-Td700 (<=14, <=20). Unknown elevation returns None. Return [sum, label] with 2-3 very low, 4 low, 5 moderate, 6 high.

split: open-access


prompt:
An unsupported alpine variant silently reports the low-elevation Haines value.

temps/dews map pressure level (hPa) to degC. low: stability T950-T850 (<=3:1, <=7:2, else 3), moisture T850-Td850 (<=5:1, <=9:2, else 3); mid: T850-T700 (<=5, <=10), T850-Td850 (<=5, <=12); high: T700-T500 (<=17, <=21), T700-Td700 (<=14, <=20). Unknown elevation returns None. Return [sum, label] with 2-3 very low, 4 low, 5 moderate, 6 high.

split: open-access


prompt:
Warm autumn hours create a chill debt that later cold hours must repay.

Hourly degC readings (None = missing hour, skipped with no effect). Units: <=1.4:0, <=2.4:0.5, <=9.1:1, <=12.4:0.5, <=15.9:0, <=18.0:-0.5, else -1. The running total is floored at zero after every hour. Return the total.

split: open-access


prompt:
Hours at exactly 9.1 degC earn half a unit.

Hourly degC readings (None = missing hour, skipped with no effect). Units: <=1.4:0, <=2.4:0.5, <=9.1:1, <=12.4:0.5, <=15.9:0, <=18.0:-0.5, else -1. The running total is floored at zero after every hour. Return the total.

split: open-access


prompt:
Mild 16 to 18 degC afternoons add chill instead of removing it.

Hourly degC readings (None = missing hour, skipped with no effect). Units: <=1.4:0, <=2.4:0.5, <=9.1:1, <=12.4:0.5, <=15.9:0, <=18.0:-0.5, else -1. The running total is floored at zero after every hour. Return the total.

split: open-access


prompt:
A single dropped logger hour discards the rest of the night.

Hourly degC readings (None = missing hour, skipped with no effect). Units: <=1.4:0, <=2.4:0.5, <=9.1:1, <=12.4:0.5, <=15.9:0, <=18.0:-0.5, else -1. The running total is floored at zero after every hour. Return the total.

split: open-access


prompt:
Irrigation demand is about 2.5 times too high.

Daily tmax/tmin degC (tmax >= tmin) and extraterrestrial radiation Ra in MJ/m2/day. Convert Ra to mm/day with 0.408. ET0 = 0.0023*Ra_mm*(Tmean+17.8)*sqrt(tmax-tmin), Tmean=(tmax+tmin)/2; negative results clamp to 0; round to 0.01 mm.

split: open-access


prompt:
Moderate days show near-zero evapotranspiration.

Daily tmax/tmin degC (tmax >= tmin) and extraterrestrial radiation Ra in MJ/m2/day. Convert Ra to mm/day with 0.408. ET0 = 0.0023*Ra_mm*(Tmean+17.8)*sqrt(tmax-tmin), Tmean=(tmax+tmin)/2; negative results clamp to 0; round to 0.01 mm.

split: open-access


prompt:
Deep-cold days report negative evapotranspiration.

Daily tmax/tmin degC (tmax >= tmin) and extraterrestrial radiation Ra in MJ/m2/day. Convert Ra to mm/day with 0.408. ET0 = 0.0023*Ra_mm*(Tmean+17.8)*sqrt(tmax-tmin), Tmean=(tmax+tmin)/2; negative results clamp to 0; round to 0.01 mm.

split: open-access


prompt:
ET0 tracks the diurnal range instead of the air temperature.

Daily tmax/tmin degC (tmax >= tmin) and extraterrestrial radiation Ra in MJ/m2/day. Convert Ra to mm/day with 0.408. ET0 = 0.0023*Ra_mm*(Tmean+17.8)*sqrt(tmax-tmin), Tmean=(tmax+tmin)/2; negative results clamp to 0; round to 0.01 mm.

split: open-access


prompt:
Dry mid-levels increase the K-index instead of suppressing it.

K = (T850 - T500) + Td850 - (T700 - Td700); VT = T850 - T500; CT = Td850 - T500; TT = VT + CT. Thunderstorm potential from K: <20 none, <=25 isolated, <=30 widely scattered, <=35 scattered, else numerous. Severe flag "severe possible" when TT >= 50 else "weak". Return [K, TT, potential, flag].

split: open-access


prompt:
Total Totals ignores low-level moisture.

K = (T850 - T500) + Td850 - (T700 - Td700); VT = T850 - T500; CT = Td850 - T500; TT = VT + CT. Thunderstorm potential from K: <20 none, <=25 isolated, <=30 widely scattered, <=35 scattered, else numerous. Severe flag "severe possible" when TT >= 50 else "weak". Return [K, TT, potential, flag].

split: open-access


prompt:
K = 25 is upgraded to widely scattered storms.

K = (T850 - T500) + Td850 - (T700 - Td700); VT = T850 - T500; CT = Td850 - T500; TT = VT + CT. Thunderstorm potential from K: <20 none, <=25 isolated, <=30 widely scattered, <=35 scattered, else numerous. Severe flag "severe possible" when TT >= 50 else "weak". Return [K, TT, potential, flag].

split: open-access


prompt:
TT = 50 does not raise the severe flag.

K = (T850 - T500) + Td850 - (T700 - Td700); VT = T850 - T500; CT = Td850 - T500; TT = VT + CT. Thunderstorm potential from K: <20 none, <=25 isolated, <=30 widely scattered, <=35 scattered, else numerous. Severe flag "severe possible" when TT >= 50 else "weak". Return [K, TT, potential, flag].

split: open-access


prompt:
After a week without reports the index has barely decayed.

obs are [day, precip_mm] in any order; process in ascending day order (stable for equal days). Between observations API decays by k^(day gap); several reports on the same day accumulate without decay; negative precipitation is a sensor glitch treated as 0. Return API after each observation, rounded to 0.01.

split: open-access


prompt:
Two gauge reports for the same day decay the first report.

obs are [day, precip_mm] in any order; process in ascending day order (stable for equal days). Between observations API decays by k^(day gap); several reports on the same day accumulate without decay; negative precipitation is a sensor glitch treated as 0. Return API after each observation, rounded to 0.01.

split: open-access


prompt:
Backfilled late reports make the API grow instead of decay.

obs are [day, precip_mm] in any order; process in ascending day order (stable for equal days). Between observations API decays by k^(day gap); several reports on the same day accumulate without decay; negative precipitation is a sensor glitch treated as 0. Return API after each observation, rounded to 0.01.

split: open-access


prompt:
A negative tipping-bucket glitch lowers soil moisture.

obs are [day, precip_mm] in any order; process in ascending day order (stable for equal days). Between observations API decays by k^(day gap); several reports on the same day accumulate without decay; negative precipitation is a sensor glitch treated as 0. Return API after each observation, rounded to 0.01.

split: open-access


prompt:
Westerly winds are reported as southerly.

obs are [speed, direction_from_deg]. Components u=-s*sin(d), v=-s*cos(d); average them. Return [vector speed rounded 0.01, direction the wind blows FROM in [0,360) rounded 0.1 or None if the vector speed is below 1e-9, steadiness = vector speed / scalar mean speed rounded 0.001 (0.0 if calm)]; empty input returns None.

split: open-access


prompt:
North-westerly winds are reported with negative bearings.

obs are [speed, direction_from_deg]. Components u=-s*sin(d), v=-s*cos(d); average them. Return [vector speed rounded 0.01, direction the wind blows FROM in [0,360) rounded 0.1 or None if the vector speed is below 1e-9, steadiness = vector speed / scalar mean speed rounded 0.001 (0.0 if calm)]; empty input returns None.

split: open-access


prompt:
Steadiness falls as more samples are averaged even when the wind is constant.

obs are [speed, direction_from_deg]. Components u=-s*sin(d), v=-s*cos(d); average them. Return [vector speed rounded 0.01, direction the wind blows FROM in [0,360) rounded 0.1 or None if the vector speed is below 1e-9, steadiness = vector speed / scalar mean speed rounded 0.001 (0.0 if calm)]; empty input returns None.

split: open-access


prompt:
Directions from different sensors average to meaningless values.

obs are [speed, direction_from_deg]. Components u=-s*sin(d), v=-s*cos(d); average them. Return [vector speed rounded 0.01, direction the wind blows FROM in [0,360) rounded 0.1 or None if the vector speed is below 1e-9, steadiness = vector speed / scalar mean speed rounded 0.001 (0.0 if calm)]; empty input returns None.

split: open-access


prompt:
A scattered layer at 400 ft makes a clear day LIFR.

layers are [cover, height_ft]; the ceiling is the lowest BKN, OVC or VV layer (None if none). Ceiling class: None or >3000 VFR, 1000-3000 MVFR, 500-999 IFR, <500 LIFR. Visibility class: >5 VFR, 3-5 MVFR, 1 to <3 IFR, <1 LIFR. Report [ceiling, worse of the two classes].

split: open-access


prompt:
When a report lists a higher deck first, the lower ceiling is ignored.

layers are [cover, height_ft]; the ceiling is the lowest BKN, OVC or VV layer (None if none). Ceiling class: None or >3000 VFR, 1000-3000 MVFR, 500-999 IFR, <500 LIFR. Visibility class: >5 VFR, 3-5 MVFR, 1 to <3 IFR, <1 LIFR. Report [ceiling, worse of the two classes].

split: open-access


prompt:
Fog with a high ceiling is reported VFR.

layers are [cover, height_ft]; the ceiling is the lowest BKN, OVC or VV layer (None if none). Ceiling class: None or >3000 VFR, 1000-3000 MVFR, 500-999 IFR, <500 LIFR. Visibility class: >5 VFR, 3-5 MVFR, 1 to <3 IFR, <1 LIFR. Report [ceiling, worse of the two classes].

split: open-access


prompt:
A 3000 ft ceiling is reported VFR.

layers are [cover, height_ft]; the ceiling is the lowest BKN, OVC or VV layer (None if none). Ceiling class: None or >3000 VFR, 1000-3000 MVFR, 500-999 IFR, <500 LIFR. Visibility class: >5 VFR, 3-5 MVFR, 1 to <3 IFR, <1 LIFR. Report [ceiling, worse of the two classes].

split: open-access


prompt:
Exactly 3 statute miles is reported IFR.

layers are [cover, height_ft]; the ceiling is the lowest BKN, OVC or VV layer (None if none). Ceiling class: None or >3000 VFR, 1000-3000 MVFR, 500-999 IFR, <500 LIFR. Visibility class: >5 VFR, 3-5 MVFR, 1 to <3 IFR, <1 LIFR. Report [ceiling, worse of the two classes].

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(wind_ms, is_day, insolation, octas):
    day = {"strong": ["A", "A-B", "B", "C", "C"],
           "moderate": ["A-B", "B", "B-C", "C-D", "D"],
           "slight": ["B", "C", "C", "D", "D"]}
    thin = ["E", "E", "D", "D", "D"]
    clear = ["F", "F", "E", "D", "D"]
    if octas == 8:
        return "D"
    i = 0 if wind_ms < 2 else 1 if wind_ms < 3 else 2 if wind_ms <= 5 else 3 if wind_ms < 6 else 4
    if is_day:
        if insolation not in day:
            return None
        return day[insolation][i]
    return (thin if octas >= 4 else clear)[i]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['wind 1.0 day strong 2 octas', [1.0, True, 'strong', 2], 'A'], ['wind 1.0 day moderate 5 octas', [1.0, True, 'moderate', 5], 'A-B'], ['wind 1.0 day slight 8 octas', [1.0, True, 'slight', 8], 'D'], ['wind 1.0 day slight 3 octas', [1.0, True, 'slight', 3], 'B'], ['wind 1.0 night None 3 octas', [1.0, False, None, 3], 'F'], ['wind 1.0 night None 4 octas', [1.0, False, None, 4], 'E'], ['wind 4.9 day moderate 5 octas', [4.9, True, 'moderate', 5], 'B-C'], ['wind 5.0 day strong 2 octas', [5.0, True, 'strong', 2], 'C']], [['wind 1.0 day overcast-ish 4 octas', [1.0, True, 'overcast-ish', 4], None], ['wind 1.0 night None 7 octas', [1.0, False, None, 7], 'E'], ['wind 1.0 day strong 7 octas', [1.0, True, 'strong', 7], 'A'], ['wind 1.9 day strong 2 octas', [1.9, True, 'strong', 2], 'A'], ['wind 1.9 day moderate 5 octas', [1.9, True, 'moderate', 5], 'A-B'], ['wind 1.9 day slight 8 octas', [1.9, True, 'slight', 8], 'D'], ['wind 4.9 day moderate 5 octas', [4.9, True, 'moderate', 5], 'B-C'], ['wind 5.0 night None 3 octas', [5.0, False, None, 3], 'D']], [['wind 1.9 night None 3 octas', [1.9, False, None, 3], 'F'], ['wind 1.9 night None 4 octas', [1.9, False, None, 4], 'E'], ['wind 1.9 night None 8 octas', [1.9, False, None, 8], 'D'], ['wind 1.9 day overcast-ish 4 octas', [1.9, True, 'overcast-ish', 4], None], ['wind 1.9 night None 7 octas', [1.9, False, None, 7], 'E'], ['wind 1.9 day strong 7 octas', [1.9, True, 'strong', 7], 'A'], ['wind 4.9 day moderate 5 octas', [4.9, True, 'moderate', 5], 'B-C'], ['wind 5.0 day moderate 5 octas', [5.0, True, 'moderate', 5], 'C-D']], [['wind 2.0 day moderate 5 octas', [2.0, True, 'moderate', 5], 'B'], ['wind 2.0 day slight 8 octas', [2.0, True, 'slight', 8], 'D'], ['wind 2.0 day slight 3 octas', [2.0, True, 'slight', 3], 'C'], ['wind 2.0 night None 3 octas', [2.0, False, None, 3], 'F'], ['wind 2.0 night None 4 octas', [2.0, False, None, 4], 'E'], ['wind 2.0 night None 8 octas', [2.0, False, None, 8], 'D'], ['wind 4.9 day moderate 5 octas', [4.9, True, 'moderate', 5], 'B-C'], ['wind 5.0 day strong 7 octas', [5.0, True, 'strong', 7], 'C']], [['wind 2.0 night None 7 octas', [2.0, False, None, 7], 'E'], ['wind 2.0 day strong 7 octas', [2.0, True, 'strong', 7], 'A-B'], ['wind 2.9 day strong 2 octas', [2.9, True, 'strong', 2], 'A-B'], ['wind 2.9 day moderate 5 octas', [2.9, True, 'moderate', 5], 'B'], ['wind 2.9 day slight 8 octas', [2.9, True, 'slight', 8], 'D'], ['wind 2.9 day slight 3 octas', [2.9, True, 'slight', 3], 'C'], ['wind 4.9 day moderate 5 octas', [4.9, True, 'moderate', 5], 'B-C'], ['wind 5.0 day slight 3 octas', [5.0, True, 'slight', 3], 'D']]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(wind_ms, is_day, insolation, octas):
    day = {"strong": ["A", "A-B", "B", "C", "C"],
           "moderate": ["A-B", "B", "B-C", "C-D", "D"],
           "slight": ["B", "C", "C", "D", "D"]}
    thin = ["E", "E", "D", "D", "D"]
    clear = ["F", "F", "E", "D", "D"]
    if octas == 8:
        return "D"
    i = 0 if wind_ms < 2 else 1 if wind_ms < 3 else 2 if wind_ms < 4 else 3 if wind_ms < 6 else 4
    if is_day:
        if insolation not in day:
            return None
        return day[insolation][i]
    return (thin if octas >= 4 else clear)[i]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['wind 1.0 day strong 2 octas', [1.0, True, 'strong', 2], 'A'], ['wind 1.0 day moderate 5 octas', [1.0, True, 'moderate', 5], 'A-B'], ['wind 1.0 day slight 8 octas', [1.0, True, 'slight', 8], 'D'], ['wind 1.0 day slight 3 octas', [1.0, True, 'slight', 3], 'B'], ['wind 1.0 night None 3 octas', [1.0, False, None, 3], 'F'], ['wind 1.0 night None 4 octas', [1.0, False, None, 4], 'E'], ['wind 4.9 day moderate 5 octas', [4.9, True, 'moderate', 5], 'B-C'], ['wind 5.0 day strong 2 octas', [5.0, True, 'strong', 2], 'C']], [['wind 1.0 day overcast-ish 4 octas', [1.0, True, 'overcast-ish', 4], None], ['wind 1.0 night None 7 octas', [1.0, False, None, 7], 'E'], ['wind 1.0 day strong 7 octas', [1.0, True, 'strong', 7], 'A'], ['wind 1.9 day strong 2 octas', [1.9, True, 'strong', 2], 'A'], ['wind 1.9 day moderate 5 octas', [1.9, True, 'moderate', 5], 'A-B'], ['wind 1.9 day slight 8 octas', [1.9, True, 'slight', 8], 'D'], ['wind 4.9 day moderate 5 octas', [4.9, True, 'moderate', 5], 'B-C'], ['wind 5.0 night None 3 octas', [5.0, False, None, 3], 'D']], [['wind 1.9 night None 3 octas', [1.9, False, None, 3], 'F'], ['wind 1.9 night None 4 octas', [1.9, False, None, 4], 'E'], ['wind 1.9 night None 8 octas', [1.9, False, None, 8], 'D'], ['wind 1.9 day overcast-ish 4 octas', [1.9, True, 'overcast-ish', 4], None], ['wind 1.9 night None 7 octas', [1.9, False, None, 7], 'E'], ['wind 1.9 day strong 7 octas', [1.9, True, 'strong', 7], 'A'], ['wind 4.9 day moderate 5 octas', [4.9, True, 'moderate', 5], 'B-C'], ['wind 5.0 day moderate 5 octas', [5.0, True, 'moderate', 5], 'C-D']], [['wind 2.0 day moderate 5 octas', [2.0, True, 'moderate', 5], 'B'], ['wind 2.0 day slight 8 octas', [2.0, True, 'slight', 8], 'D'], ['wind 2.0 day slight 3 octas', [2.0, True, 'slight', 3], 'C'], ['wind 2.0 night None 3 octas', [2.0, False, None, 3], 'F'], ['wind 2.0 night None 4 octas', [2.0, False, None, 4], 'E'], ['wind 2.0 night None 8 octas', [2.0, False, None, 8], 'D'], ['wind 4.9 day moderate 5 octas', [4.9, True, 'moderate', 5], 'B-C'], ['wind 5.0 day strong 7 octas', [5.0, True, 'strong', 7], 'C']], [['wind 2.0 night None 7 octas', [2.0, False, None, 7], 'E'], ['wind 2.0 day strong 7 octas', [2.0, True, 'strong', 7], 'A-B'], ['wind 2.9 day strong 2 octas', [2.9, True, 'strong', 2], 'A-B'], ['wind 2.9 day moderate 5 octas', [2.9, True, 'moderate', 5], 'B'], ['wind 2.9 day slight 8 octas', [2.9, True, 'slight', 8], 'D'], ['wind 2.9 day slight 3 octas', [2.9, True, 'slight', 3], 'C'], ['wind 4.9 day moderate 5 octas', [4.9, True, 'moderate', 5], 'B-C'], ['wind 5.0 day slight 3 octas', [5.0, True, 'slight', 3], 'D']]]
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)

prompt:
A 5.0 m/s wind is assigned the lighter-wind class.

Wind class: <2, <3, <5, <6, >=6 (index 0..4). 8 octas returns "D" day or night. Day: tables by insolation strong [A,A-B,B,C,C], moderate [A-B,B,B-C,C-D,D], slight [B,C,C,D,D]; unknown insolation returns None. Night: >=4 octas [E,E,D,D,D], <=3 octas [F,F,E,D,D].

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(wind_ms, is_day, insolation, octas):
    day = {"strong": ["A", "A-B", "B", "C", "C"],
           "moderate": ["A-B", "B", "B-C", "C-D", "D"],
           "slight": ["B", "C", "C", "D", "D"]}
    thin = ["E", "E", "D", "D", "D"]
    clear = ["F", "F", "E", "D", "D"]
    if octas == 8:
        return "D"
    i = 0 if wind_ms < 2 else 1 if wind_ms < 3 else 2 if wind_ms < 5 else 3 if wind_ms < 6 else 4
    if is_day:
        if insolation not in day:
            return None
        return day[insolation][i]
    return (thin if octas > 4 else clear)[i]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['wind 1.0 day strong 2 octas', [1.0, True, 'strong', 2], 'A'], ['wind 1.0 day moderate 5 octas', [1.0, True, 'moderate', 5], 'A-B'], ['wind 1.0 day slight 8 octas', [1.0, True, 'slight', 8], 'D'], ['wind 1.0 day slight 3 octas', [1.0, True, 'slight', 3], 'B'], ['wind 1.0 night None 3 octas', [1.0, False, None, 3], 'F'], ['wind 1.0 night None 4 octas', [1.0, False, None, 4], 'E'], ['wind 1.0 night None 8 octas', [1.0, False, None, 8], 'D'], ['wind 1.9 night None 3 octas', [1.9, False, None, 3], 'F']], [['wind 1.0 night None 3 octas', [1.0, False, None, 3], 'F'], ['wind 1.0 day overcast-ish 4 octas', [1.0, True, 'overcast-ish', 4], None], ['wind 1.0 night None 7 octas', [1.0, False, None, 7], 'E'], ['wind 1.0 day strong 7 octas', [1.0, True, 'strong', 7], 'A'], ['wind 1.9 day strong 2 octas', [1.9, True, 'strong', 2], 'A'], ['wind 1.9 day moderate 5 octas', [1.9, True, 'moderate', 5], 'A-B'], ['wind 1.9 day slight 8 octas', [1.9, True, 'slight', 8], 'D'], ['wind 2.9 night None 4 octas', [2.9, False, None, 4], 'E']], [['wind 1.0 night None 4 octas', [1.0, False, None, 4], 'E'], ['wind 1.9 night None 3 octas', [1.9, False, None, 3], 'F'], ['wind 1.9 night None 4 octas', [1.9, False, None, 4], 'E'], ['wind 1.9 night None 8 octas', [1.9, False, None, 8], 'D'], ['wind 1.9 day overcast-ish 4 octas', [1.9, True, 'overcast-ish', 4], None], ['wind 1.9 night None 7 octas', [1.9, False, None, 7], 'E'], ['wind 1.9 day strong 7 octas', [1.9, True, 'strong', 7], 'A'], ['wind 4.9 night None 3 octas', [4.9, False, None, 3], 'E']], [['wind 2.0 day moderate 5 octas', [2.0, True, 'moderate', 5], 'B'], ['wind 2.0 day slight 8 octas', [2.0, True, 'slight', 8], 'D'], ['wind 2.0 day slight 3 octas', [2.0, True, 'slight', 3], 'C'], ['wind 2.0 night None 3 octas', [2.0, False, None, 3], 'F'], ['wind 2.0 night None 4 octas', [2.0, False, None, 4], 'E'], ['wind 2.0 night None 8 octas', [2.0, False, None, 8], 'D'], ['wind 2.9 night None 4 octas', [2.9, False, None, 4], 'E'], ['wind 3.0 night None 3 octas', [3.0, False, None, 3], 'E']], [['wind 1.0 night None 4 octas', [1.0, False, None, 4], 'E'], ['wind 2.0 night None 7 octas', [2.0, False, None, 7], 'E'], ['wind 2.0 day strong 7 octas', [2.0, True, 'strong', 7], 'A-B'], ['wind 2.9 day strong 2 octas', [2.9, True, 'strong', 2], 'A-B'], ['wind 2.9 day moderate 5 octas', [2.9, True, 'moderate', 5], 'B'], ['wind 2.9 day slight 8 octas', [2.9, True, 'slight', 8], 'D'], ['wind 2.9 day slight 3 octas', [2.9, True, 'slight', 3], 'C'], ['wind 2.9 night None 3 octas', [2.9, False, None, 3], 'F']]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(wind_ms, is_day, insolation, octas):
    day = {"strong": ["A", "A-B", "B", "C", "C"],
           "moderate": ["A-B", "B", "B-C", "C-D", "D"],
           "slight": ["B", "C", "C", "D", "D"]}
    thin = ["E", "E", "D", "D", "D"]
    clear = ["F", "F", "E", "D", "D"]
    if octas == 8:
        return "D"
    i = 0 if wind_ms < 2 else 1 if wind_ms < 3 else 2 if wind_ms < 5 else 3 if wind_ms < 6 else 4
    if is_day:
        if insolation not in day:
            return None
        return day[insolation][i]
    return (thin if octas >= 3 else clear)[i]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['wind 1.0 day strong 2 octas', [1.0, True, 'strong', 2], 'A'], ['wind 1.0 day moderate 5 octas', [1.0, True, 'moderate', 5], 'A-B'], ['wind 1.0 day slight 8 octas', [1.0, True, 'slight', 8], 'D'], ['wind 1.0 day slight 3 octas', [1.0, True, 'slight', 3], 'B'], ['wind 1.0 night None 3 octas', [1.0, False, None, 3], 'F'], ['wind 1.0 night None 4 octas', [1.0, False, None, 4], 'E'], ['wind 1.0 night None 8 octas', [1.0, False, None, 8], 'D'], ['wind 1.9 night None 3 octas', [1.9, False, None, 3], 'F']], [['wind 1.0 night None 3 octas', [1.0, False, None, 3], 'F'], ['wind 1.0 day overcast-ish 4 octas', [1.0, True, 'overcast-ish', 4], None], ['wind 1.0 night None 7 octas', [1.0, False, None, 7], 'E'], ['wind 1.0 day strong 7 octas', [1.0, True, 'strong', 7], 'A'], ['wind 1.9 day strong 2 octas', [1.9, True, 'strong', 2], 'A'], ['wind 1.9 day moderate 5 octas', [1.9, True, 'moderate', 5], 'A-B'], ['wind 1.9 day slight 8 octas', [1.9, True, 'slight', 8], 'D'], ['wind 2.9 night None 4 octas', [2.9, False, None, 4], 'E']], [['wind 1.0 night None 4 octas', [1.0, False, None, 4], 'E'], ['wind 1.9 night None 3 octas', [1.9, False, None, 3], 'F'], ['wind 1.9 night None 4 octas', [1.9, False, None, 4], 'E'], ['wind 1.9 night None 8 octas', [1.9, False, None, 8], 'D'], ['wind 1.9 day overcast-ish 4 octas', [1.9, True, 'overcast-ish', 4], None], ['wind 1.9 night None 7 octas', [1.9, False, None, 7], 'E'], ['wind 1.9 day strong 7 octas', [1.9, True, 'strong', 7], 'A'], ['wind 4.9 night None 3 octas', [4.9, False, None, 3], 'E']], [['wind 2.0 day moderate 5 octas', [2.0, True, 'moderate', 5], 'B'], ['wind 2.0 day slight 8 octas', [2.0, True, 'slight', 8], 'D'], ['wind 2.0 day slight 3 octas', [2.0, True, 'slight', 3], 'C'], ['wind 2.0 night None 3 octas', [2.0, False, None, 3], 'F'], ['wind 2.0 night None 4 octas', [2.0, False, None, 4], 'E'], ['wind 2.0 night None 8 octas', [2.0, False, None, 8], 'D'], ['wind 2.9 night None 4 octas', [2.9, False, None, 4], 'E'], ['wind 3.0 night None 3 octas', [3.0, False, None, 3], 'E']], [['wind 1.0 night None 4 octas', [1.0, False, None, 4], 'E'], ['wind 2.0 night None 7 octas', [2.0, False, None, 7], 'E'], ['wind 2.0 day strong 7 octas', [2.0, True, 'strong', 7], 'A-B'], ['wind 2.9 day strong 2 octas', [2.9, True, 'strong', 2], 'A-B'], ['wind 2.9 day moderate 5 octas', [2.9, True, 'moderate', 5], 'B'], ['wind 2.9 day slight 8 octas', [2.9, True, 'slight', 8], 'D'], ['wind 2.9 day slight 3 octas', [2.9, True, 'slight', 3], 'C'], ['wind 2.9 night None 3 octas', [2.9, False, None, 3], 'F']]]
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)

prompt:
Four-octa nights are treated as clear and too stable.

Wind class: <2, <3, <5, <6, >=6 (index 0..4). 8 octas returns "D" day or night. Day: tables by insolation strong [A,A-B,B,C,C], moderate [A-B,B,B-C,C-D,D], slight [B,C,C,D,D]; unknown insolation returns None. Night: >=4 octas [E,E,D,D,D], <=3 octas [F,F,E,D,D].

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(wind_ms, is_day, insolation, octas):
    day = {"strong": ["A", "A-B", "B", "C", "C"],
           "moderate": ["A-B", "B", "B-C", "C-D", "D"],
           "slight": ["B", "C", "C", "D", "D"]}
    thin = ["E", "E", "D", "D", "D"]
    clear = ["F", "F", "E", "D", "D"]
    if octas == 8 and not is_day:
        return "D"
    i = 0 if wind_ms < 2 else 1 if wind_ms < 3 else 2 if wind_ms < 5 else 3 if wind_ms < 6 else 4
    if is_day:
        if insolation not in day:
            return None
        return day[insolation][i]
    return (thin if octas >= 4 else clear)[i]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['wind 1.0 day strong 2 octas', [1.0, True, 'strong', 2], 'A'], ['wind 1.0 day moderate 5 octas', [1.0, True, 'moderate', 5], 'A-B'], ['wind 1.0 day slight 8 octas', [1.0, True, 'slight', 8], 'D'], ['wind 1.0 day slight 3 octas', [1.0, True, 'slight', 3], 'B'], ['wind 1.0 night None 3 octas', [1.0, False, None, 3], 'F'], ['wind 1.0 night None 4 octas', [1.0, False, None, 4], 'E'], ['wind 1.0 night None 8 octas', [1.0, False, None, 8], 'D'], ['wind 1.0 day strong 7 octas', [1.0, True, 'strong', 7], 'A']], [['wind 1.0 day overcast-ish 4 octas', [1.0, True, 'overcast-ish', 4], None], ['wind 1.0 night None 7 octas', [1.0, False, None, 7], 'E'], ['wind 1.0 day strong 7 octas', [1.0, True, 'strong', 7], 'A'], ['wind 1.9 day strong 2 octas', [1.9, True, 'strong', 2], 'A'], ['wind 1.9 day moderate 5 octas', [1.9, True, 'moderate', 5], 'A-B'], ['wind 1.9 day slight 8 octas', [1.9, True, 'slight', 8], 'D'], ['wind 2.9 day slight 8 octas', [2.9, True, 'slight', 8], 'D'], ['wind 2.9 night None 7 octas', [2.9, False, None, 7], 'E']], [['wind 1.0 day slight 8 octas', [1.0, True, 'slight', 8], 'D'], ['wind 1.9 night None 3 octas', [1.9, False, None, 3], 'F'], ['wind 1.9 night None 4 octas', [1.9, False, None, 4], 'E'], ['wind 1.9 night None 8 octas', [1.9, False, None, 8], 'D'], ['wind 1.9 day overcast-ish 4 octas', [1.9, True, 'overcast-ish', 4], None], ['wind 1.9 night None 7 octas', [1.9, False, None, 7], 'E'], ['wind 1.9 day strong 7 octas', [1.9, True, 'strong', 7], 'A'], ['wind 5.9 day strong 7 octas', [5.9, True, 'strong', 7], 'C']], [['wind 1.9 night None 7 octas', [1.9, False, None, 7], 'E'], ['wind 2.0 day moderate 5 octas', [2.0, True, 'moderate', 5], 'B'], ['wind 2.0 day slight 8 octas', [2.0, True, 'slight', 8], 'D'], ['wind 2.0 day slight 3 octas', [2.0, True, 'slight', 3], 'C'], ['wind 2.0 night None 3 octas', [2.0, False, None, 3], 'F'], ['wind 2.0 night None 4 octas', [2.0, False, None, 4], 'E'], ['wind 2.0 night None 8 octas', [2.0, False, None, 8], 'D'], ['wind 2.9 day slight 8 octas', [2.9, True, 'slight', 8], 'D']], [['wind 1.0 day slight 8 octas', [1.0, True, 'slight', 8], 'D'], ['wind 2.0 night None 7 octas', [2.0, False, None, 7], 'E'], ['wind 2.0 day strong 7 octas', [2.0, True, 'strong', 7], 'A-B'], ['wind 2.9 day strong 2 octas', [2.9, True, 'strong', 2], 'A-B'], ['wind 2.9 day moderate 5 octas', [2.9, True, 'moderate', 5], 'B'], ['wind 2.9 day slight 8 octas', [2.9, True, 'slight', 8], 'D'], ['wind 2.9 day slight 3 octas', [2.9, True, 'slight', 3], 'C'], ['wind 2.9 day strong 7 octas', [2.9, True, 'strong', 7], 'A-B']]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(wind_ms, is_day, insolation, octas):
    day = {"strong": ["A", "A-B", "B", "C", "C"],
           "moderate": ["A-B", "B", "B-C", "C-D", "D"],
           "slight": ["B", "C", "C", "D", "D"]}
    thin = ["E", "E", "D", "D", "D"]
    clear = ["F", "F", "E", "D", "D"]
    if octas >= 7:
        return "D"
    i = 0 if wind_ms < 2 else 1 if wind_ms < 3 else 2 if wind_ms < 5 else 3 if wind_ms < 6 else 4
    if is_day:
        if insolation not in day:
            return None
        return day[insolation][i]
    return (thin if octas >= 4 else clear)[i]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['wind 1.0 day strong 2 octas', [1.0, True, 'strong', 2], 'A'], ['wind 1.0 day moderate 5 octas', [1.0, True, 'moderate', 5], 'A-B'], ['wind 1.0 day slight 8 octas', [1.0, True, 'slight', 8], 'D'], ['wind 1.0 day slight 3 octas', [1.0, True, 'slight', 3], 'B'], ['wind 1.0 night None 3 octas', [1.0, False, None, 3], 'F'], ['wind 1.0 night None 4 octas', [1.0, False, None, 4], 'E'], ['wind 1.0 night None 8 octas', [1.0, False, None, 8], 'D'], ['wind 1.0 day strong 7 octas', [1.0, True, 'strong', 7], 'A']], [['wind 1.0 day overcast-ish 4 octas', [1.0, True, 'overcast-ish', 4], None], ['wind 1.0 night None 7 octas', [1.0, False, None, 7], 'E'], ['wind 1.0 day strong 7 octas', [1.0, True, 'strong', 7], 'A'], ['wind 1.9 day strong 2 octas', [1.9, True, 'strong', 2], 'A'], ['wind 1.9 day moderate 5 octas', [1.9, True, 'moderate', 5], 'A-B'], ['wind 1.9 day slight 8 octas', [1.9, True, 'slight', 8], 'D'], ['wind 2.9 day slight 8 octas', [2.9, True, 'slight', 8], 'D'], ['wind 2.9 night None 7 octas', [2.9, False, None, 7], 'E']], [['wind 1.0 day slight 8 octas', [1.0, True, 'slight', 8], 'D'], ['wind 1.9 night None 3 octas', [1.9, False, None, 3], 'F'], ['wind 1.9 night None 4 octas', [1.9, False, None, 4], 'E'], ['wind 1.9 night None 8 octas', [1.9, False, None, 8], 'D'], ['wind 1.9 day overcast-ish 4 octas', [1.9, True, 'overcast-ish', 4], None], ['wind 1.9 night None 7 octas', [1.9, False, None, 7], 'E'], ['wind 1.9 day strong 7 octas', [1.9, True, 'strong', 7], 'A'], ['wind 5.9 day strong 7 octas', [5.9, True, 'strong', 7], 'C']], [['wind 1.9 night None 7 octas', [1.9, False, None, 7], 'E'], ['wind 2.0 day moderate 5 octas', [2.0, True, 'moderate', 5], 'B'], ['wind 2.0 day slight 8 octas', [2.0, True, 'slight', 8], 'D'], ['wind 2.0 day slight 3 octas', [2.0, True, 'slight', 3], 'C'], ['wind 2.0 night None 3 octas', [2.0, False, None, 3], 'F'], ['wind 2.0 night None 4 octas', [2.0, False, None, 4], 'E'], ['wind 2.0 night None 8 octas', [2.0, False, None, 8], 'D'], ['wind 2.9 day slight 8 octas', [2.9, True, 'slight', 8], 'D']], [['wind 1.0 day slight 8 octas', [1.0, True, 'slight', 8], 'D'], ['wind 2.0 night None 7 octas', [2.0, False, None, 7], 'E'], ['wind 2.0 day strong 7 octas', [2.0, True, 'strong', 7], 'A-B'], ['wind 2.9 day strong 2 octas', [2.9, True, 'strong', 2], 'A-B'], ['wind 2.9 day moderate 5 octas', [2.9, True, 'moderate', 5], 'B'], ['wind 2.9 day slight 8 octas', [2.9, True, 'slight', 8], 'D'], ['wind 2.9 day slight 3 octas', [2.9, True, 'slight', 3], 'C'], ['wind 2.9 day strong 7 octas', [2.9, True, 'strong', 7], 'A-B']]]
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)

prompt:
Overcast days receive unstable daytime classes.

Wind class: <2, <3, <5, <6, >=6 (index 0..4). 8 octas returns "D" day or night. Day: tables by insolation strong [A,A-B,B,C,C], moderate [A-B,B,B-C,C-D,D], slight [B,C,C,D,D]; unknown insolation returns None. Night: >=4 octas [E,E,D,D,D], <=3 octas [F,F,E,D,D].

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(wind_ms, is_day, insolation, octas):
    day = {"strong": ["A", "A-B", "B", "C", "C"],
           "moderate": ["A-B", "B", "B-C", "C-D", "D"],
           "slight": ["B", "C", "C", "D", "D"]}
    thin = ["E", "E", "D", "D", "D"]
    clear = ["F", "F", "E", "D", "D"]
    if octas == 8:
        return "D"
    i = 0 if wind_ms < 2 else 1 if wind_ms < 3 else 2 if wind_ms < 5 else 3 if wind_ms < 6 else 4
    if is_day:
        if insolation not in day:
            insolation = "slight"
        return day[insolation][i]
    return (thin if octas >= 4 else clear)[i]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['wind 1.0 day strong 2 octas', [1.0, True, 'strong', 2], 'A'], ['wind 1.0 day moderate 5 octas', [1.0, True, 'moderate', 5], 'A-B'], ['wind 1.0 day slight 8 octas', [1.0, True, 'slight', 8], 'D'], ['wind 1.0 day slight 3 octas', [1.0, True, 'slight', 3], 'B'], ['wind 1.0 night None 3 octas', [1.0, False, None, 3], 'F'], ['wind 1.0 night None 4 octas', [1.0, False, None, 4], 'E'], ['wind 1.0 day overcast-ish 4 octas', [1.0, True, 'overcast-ish', 4], None], ['wind 1.9 day overcast-ish 4 octas', [1.9, True, 'overcast-ish', 4], None]], [['wind 1.0 day overcast-ish 4 octas', [1.0, True, 'overcast-ish', 4], None], ['wind 1.0 night None 7 octas', [1.0, False, None, 7], 'E'], ['wind 1.0 day strong 7 octas', [1.0, True, 'strong', 7], 'A'], ['wind 1.9 day strong 2 octas', [1.9, True, 'strong', 2], 'A'], ['wind 1.9 day moderate 5 octas', [1.9, True, 'moderate', 5], 'A-B'], ['wind 1.9 day slight 8 octas', [1.9, True, 'slight', 8], 'D'], ['wind 2.9 day overcast-ish 4 octas', [2.9, True, 'overcast-ish', 4], None], ['wind 5.0 day overcast-ish 4 octas', [5.0, True, 'overcast-ish', 4], None]], [['wind 1.9 night None 3 octas', [1.9, False, None, 3], 'F'], ['wind 1.9 night None 4 octas', [1.9, False, None, 4], 'E'], ['wind 1.9 night None 8 octas', [1.9, False, None, 8], 'D'], ['wind 1.9 day overcast-ish 4 octas', [1.9, True, 'overcast-ish', 4], None], ['wind 1.9 night None 7 octas', [1.9, False, None, 7], 'E'], ['wind 1.9 day strong 7 octas', [1.9, True, 'strong', 7], 'A'], ['wind 2.0 day strong 2 octas', [2.0, True, 'strong', 2], 'A-B'], ['wind 5.0 day overcast-ish 4 octas', [5.0, True, 'overcast-ish', 4], None]], [['wind 2.0 day moderate 5 octas', [2.0, True, 'moderate', 5], 'B'], ['wind 2.0 day slight 8 octas', [2.0, True, 'slight', 8], 'D'], ['wind 2.0 day slight 3 octas', [2.0, True, 'slight', 3], 'C'], ['wind 2.0 night None 3 octas', [2.0, False, None, 3], 'F'], ['wind 2.0 night None 4 octas', [2.0, False, None, 4], 'E'], ['wind 2.0 night None 8 octas', [2.0, False, None, 8], 'D'], ['wind 5.0 day overcast-ish 4 octas', [5.0, True, 'overcast-ish', 4], None], ['wind 8.0 day overcast-ish 4 octas', [8.0, True, 'overcast-ish', 4], None]], [['wind 1.9 day overcast-ish 4 octas', [1.9, True, 'overcast-ish', 4], None], ['wind 2.0 day overcast-ish 4 octas', [2.0, True, 'overcast-ish', 4], None], ['wind 2.0 night None 7 octas', [2.0, False, None, 7], 'E'], ['wind 2.0 day strong 7 octas', [2.0, True, 'strong', 7], 'A-B'], ['wind 2.9 day strong 2 octas', [2.9, True, 'strong', 2], 'A-B'], ['wind 2.9 day moderate 5 octas', [2.9, True, 'moderate', 5], 'B'], ['wind 2.9 day slight 8 octas', [2.9, True, 'slight', 8], 'D'], ['wind 2.9 day slight 3 octas', [2.9, True, 'slight', 3], 'C']]]
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)

source:
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(wind_ms, is_day, insolation, octas):
    day = {"strong": ["A", "A-B", "B", "C", "C"],
           "moderate": ["A-B", "B", "B-C", "C-D", "D"],
           "slight": ["B", "C", "C", "D", "D"]}
    thin = ["E", "E", "D", "D", "D"]
    clear = ["F", "F", "E", "D", "D"]
    if octas == 8:
        return "D"
    i = 0 if wind_ms < 2 else 1 if wind_ms < 3 else 2 if wind_ms < 5 else 3 if wind_ms < 6 else 4
    if is_day:
        if insolation not in day:
            return "D"
        return day[insolation][i]
    return (thin if octas >= 4 else clear)[i]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['wind 1.0 day strong 2 octas', [1.0, True, 'strong', 2], 'A'], ['wind 1.0 day moderate 5 octas', [1.0, True, 'moderate', 5], 'A-B'], ['wind 1.0 day slight 8 octas', [1.0, True, 'slight', 8], 'D'], ['wind 1.0 day slight 3 octas', [1.0, True, 'slight', 3], 'B'], ['wind 1.0 night None 3 octas', [1.0, False, None, 3], 'F'], ['wind 1.0 night None 4 octas', [1.0, False, None, 4], 'E'], ['wind 1.0 day overcast-ish 4 octas', [1.0, True, 'overcast-ish', 4], None], ['wind 1.9 day overcast-ish 4 octas', [1.9, True, 'overcast-ish', 4], None]], [['wind 1.0 day overcast-ish 4 octas', [1.0, True, 'overcast-ish', 4], None], ['wind 1.0 night None 7 octas', [1.0, False, None, 7], 'E'], ['wind 1.0 day strong 7 octas', [1.0, True, 'strong', 7], 'A'], ['wind 1.9 day strong 2 octas', [1.9, True, 'strong', 2], 'A'], ['wind 1.9 day moderate 5 octas', [1.9, True, 'moderate', 5], 'A-B'], ['wind 1.9 day slight 8 octas', [1.9, True, 'slight', 8], 'D'], ['wind 2.9 day overcast-ish 4 octas', [2.9, True, 'overcast-ish', 4], None], ['wind 5.0 day overcast-ish 4 octas', [5.0, True, 'overcast-ish', 4], None]], [['wind 1.9 night None 3 octas', [1.9, False, None, 3], 'F'], ['wind 1.9 night None 4 octas', [1.9, False, None, 4], 'E'], ['wind 1.9 night None 8 octas', [1.9, False, None, 8], 'D'], ['wind 1.9 day overcast-ish 4 octas', [1.9, True, 'overcast-ish', 4], None], ['wind 1.9 night None 7 octas', [1.9, False, None, 7], 'E'], ['wind 1.9 day strong 7 octas', [1.9, True, 'strong', 7], 'A'], ['wind 2.0 day strong 2 octas', [2.0, True, 'strong', 2], 'A-B'], ['wind 5.0 day overcast-ish 4 octas', [5.0, True, 'overcast-ish', 4], None]], [['wind 2.0 day moderate 5 octas', [2.0, True, 'moderate', 5], 'B'], ['wind 2.0 day slight 8 octas', [2.0, True, 'slight', 8], 'D'], ['wind 2.0 day slight 3 octas', [2.0, True, 'slight', 3], 'C'], ['wind 2.0 night None 3 octas', [2.0, False, None, 3], 'F'], ['wind 2.0 night None 4 octas', [2.0, False, None, 4], 'E'], ['wind 2.0 night None 8 octas', [2.0, False, None, 8], 'D'], ['wind 5.0 day overcast-ish 4 octas', [5.0, True, 'overcast-ish', 4], None], ['wind 8.0 day overcast-ish 4 octas', [8.0, True, 'overcast-ish', 4], None]], [['wind 1.9 day overcast-ish 4 octas', [1.9, True, 'overcast-ish', 4], None], ['wind 2.0 day overcast-ish 4 octas', [2.0, True, 'overcast-ish', 4], None], ['wind 2.0 night None 7 octas', [2.0, False, None, 7], 'E'], ['wind 2.0 day strong 7 octas', [2.0, True, 'strong', 7], 'A-B'], ['wind 2.9 day strong 2 octas', [2.9, True, 'strong', 2], 'A-B'], ['wind 2.9 day moderate 5 octas', [2.9, True, 'moderate', 5], 'B'], ['wind 2.9 day slight 8 octas', [2.9, True, 'slight', 8], 'D'], ['wind 2.9 day slight 3 octas', [2.9, True, 'slight', 3], 'C']]]
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)

prompt:
An unrecognised insolation code silently yields a slight-insolation class.

Wind class: <2, <3, <5, <6, >=6 (index 0..4). 8 octas returns "D" day or night. Day: tables by insolation strong [A,A-B,B,C,C], moderate [A-B,B,B-C,C-D,D], slight [B,C,C,D,D]; unknown insolation returns None. Night: >=4 octas [E,E,D,D,D], <=3 octas [F,F,E,D,D].

split: open-access


prompt:
Heatwaves are flagged a day before the hot three-day window starts.

temps are daily mean degC. For each day i with 6 prior days and 2 following days: m3 = mean of days i..i+2, prior = mean of days i-6..i-1, EHIsig = m3 - t95, EHIaccl = m3 - prior, EHF = EHIsig * max(1, EHIaccl). Return [[i, EHF rounded 0.01]] for days with EHF > 0.

split: open-access


prompt:
The acclimatisation baseline includes the first hot day.

temps are daily mean degC. For each day i with 6 prior days and 2 following days: m3 = mean of days i..i+2, prior = mean of days i-6..i-1, EHIsig = m3 - t95, EHIaccl = m3 - prior, EHF = EHIsig * max(1, EHIaccl). Return [[i, EHF rounded 0.01]] for days with EHF > 0.

split: open-access


prompt:
A cool spell after a hot week turns negative significance into a positive EHF.

temps are daily mean degC. For each day i with 6 prior days and 2 following days: m3 = mean of days i..i+2, prior = mean of days i-6..i-1, EHIsig = m3 - t95, EHIaccl = m3 - prior, EHF = EHIsig * max(1, EHIaccl). Return [[i, EHF rounded 0.01]] for days with EHF > 0.

split: open-access


prompt:
The most recent day with a complete forecast window is never assessed.

temps are daily mean degC. For each day i with 6 prior days and 2 following days: m3 = mean of days i..i+2, prior = mean of days i-6..i-1, EHIsig = m3 - t95, EHIaccl = m3 - prior, EHF = EHIsig * max(1, EHIaccl). Return [[i, EHF rounded 0.01]] for days with EHF > 0.

split: open-access


prompt:
Days warmer than last week but below the threshold are reported.

temps are daily mean degC. For each day i with 6 prior days and 2 following days: m3 = mean of days i..i+2, prior = mean of days i-6..i-1, EHIsig = m3 - t95, EHIaccl = m3 - prior, EHF = EHIsig * max(1, EHIaccl). Return [[i, EHF rounded 0.01]] for days with EHF > 0.

split: open-access


prompt:
Snow at exactly -5 degC is reported with the wet 10:1 ratio instead of 15:1.

hours are [liquid_mm, temp_c]. Snow-to-liquid ratio: T>1 rain (0), 0<T<=1: 5, -5<T<=0: 10, -12<T<=-5: 15, T<=-12: 20. New snow cm = liquid*ratio/10. Each hour the existing depth settles by 2% before the new snow is added; rain (ratio 0, liquid > 0) melts 0.5 cm per mm, floored at 0. Return [total new snowfall rounded 0.1, final depth rounded 0.1].

split: open-access


prompt:
Freshly fallen snow is compacted in the same hour it falls; depth under-reads after bursts.

hours are [liquid_mm, temp_c]. Snow-to-liquid ratio: T>1 rain (0), 0<T<=1: 5, -5<T<=0: 10, -12<T<=-5: 15, T<=-12: 20. New snow cm = liquid*ratio/10. Each hour the existing depth settles by 2% before the new snow is added; rain (ratio 0, liquid > 0) melts 0.5 cm per mm, floored at 0. Return [total new snowfall rounded 0.1, final depth rounded 0.1].

split: open-access


prompt:
Heavy rain on a thin pack reports negative snow depth.

hours are [liquid_mm, temp_c]. Snow-to-liquid ratio: T>1 rain (0), 0<T<=1: 5, -5<T<=0: 10, -12<T<=-5: 15, T<=-12: 20. New snow cm = liquid*ratio/10. Each hour the existing depth settles by 2% before the new snow is added; rain (ratio 0, liquid > 0) melts 0.5 cm per mm, floored at 0. Return [total new snowfall rounded 0.1, final depth rounded 0.1].

split: open-access


prompt:
Every station magnitude is 0.30 units too large.

Input the Wood-Anderson peak-to-peak amplitude in nm, epicentral distance and depth in km. Non-positive amplitude returns None. A (mm, zero-to-peak) = p2p/2 * 1e-6; r = hypocentral distance; ML = log10(A) + 1.11 log10(r/100) + 0.00189 (r - 100) + 3.0, rounded to 0.01.

split: open-access


prompt:
Magnitudes are three units too large.

Input the Wood-Anderson peak-to-peak amplitude in nm, epicentral distance and depth in km. Non-positive amplitude returns None. A (mm, zero-to-peak) = p2p/2 * 1e-6; r = hypocentral distance; ML = log10(A) + 1.11 log10(r/100) + 0.00189 (r - 100) + 3.0, rounded to 0.01.

split: open-access


prompt:
Events recorded directly above the source crash or read far too small.

Input the Wood-Anderson peak-to-peak amplitude in nm, epicentral distance and depth in km. Non-positive amplitude returns None. A (mm, zero-to-peak) = p2p/2 * 1e-6; r = hypocentral distance; ML = log10(A) + 1.11 log10(r/100) + 0.00189 (r - 100) + 3.0, rounded to 0.01.

split: open-access


prompt:
All magnitudes are about 0.19 high and near-field events are biased.

Input the Wood-Anderson peak-to-peak amplitude in nm, epicentral distance and depth in km. Non-positive amplitude returns None. A (mm, zero-to-peak) = p2p/2 * 1e-6; r = hypocentral distance; ML = log10(A) + 1.11 log10(r/100) + 0.00189 (r - 100) + 3.0, rounded to 0.01.

split: open-access


prompt:
Distant stations report magnitudes that grow with distance.

Input the Wood-Anderson peak-to-peak amplitude in nm, epicentral distance and depth in km. Non-positive amplitude returns None. A (mm, zero-to-peak) = p2p/2 * 1e-6; r = hypocentral distance; ML = log10(A) + 1.11 log10(r/100) + 0.00189 (r - 100) + 3.0, rounded to 0.01.

split: open-access


prompt:
With an even number of stations the magnitude is biased upward.

Station magnitudes are integers in hundredths (None = no reading; 0 and negatives are valid). Require min_stations readings; take the median (mean of the middle pair for even counts), keep stations within 50 hundredths of it inclusive, require min_stations again, take the median of the kept set and round half up to 0.1 magnitude. Return [magnitude, kept count] or None.

split: open-access


prompt:
Stations exactly half a unit from the median are discarded.

Station magnitudes are integers in hundredths (None = no reading; 0 and negatives are valid). Require min_stations readings; take the median (mean of the middle pair for even counts), keep stations within 50 hundredths of it inclusive, require min_stations again, take the median of the kept set and round half up to 0.1 magnitude. Return [magnitude, kept count] or None.

split: open-access


prompt:
A single wild station drags the rejection window and good stations are dropped.

Station magnitudes are integers in hundredths (None = no reading; 0 and negatives are valid). Require min_stations readings; take the median (mean of the middle pair for even counts), keep stations within 50 hundredths of it inclusive, require min_stations again, take the median of the kept set and round half up to 0.1 magnitude. Return [magnitude, kept count] or None.

split: open-access


prompt:
Events keep a published magnitude after rejection leaves too few stations.

Station magnitudes are integers in hundredths (None = no reading; 0 and negatives are valid). Require min_stations readings; take the median (mean of the middle pair for even counts), keep stations within 50 hundredths of it inclusive, require min_stations again, take the median of the kept set and round half up to 0.1 magnitude. Return [magnitude, kept count] or None.

split: open-access


prompt:
An exact x.x5 median such as 3.25 is published as 3.2.

Station magnitudes are integers in hundredths (None = no reading; 0 and negatives are valid). Require min_stations readings; take the median (mean of the middle pair for even counts), keep stations within 50 hundredths of it inclusive, require min_stations again, take the median of the kept set and round half up to 0.1 magnitude. Return [magnitude, kept count] or None.

split: open-access


prompt:
Microearthquake station magnitudes of exactly 0.00 are discarded.

Station magnitudes are integers in hundredths (None = no reading; 0 and negatives are valid). Require min_stations readings; take the median (mean of the middle pair for even counts), keep stations within 50 hundredths of it inclusive, require min_stations again, take the median of the kept set and round half up to 0.1 magnitude. Return [magnitude, kept count] or None.

split: open-access


prompt:
Scenario magnitudes are two units low.

Rigidity in GPa, rupture length and width in km, average slip in m; any non-positive value returns None. M0 = mu * area * slip in N*m (SI), Mw = 2/3 (log10 M0 - 9.1). Return [M0 formatted %.3e, Mw rounded 0.01].

split: open-access


prompt:
Moment is a thousand times too small and Mw is 2 units low.

Rigidity in GPa, rupture length and width in km, average slip in m; any non-positive value returns None. M0 = mu * area * slip in N*m (SI), Mw = 2/3 (log10 M0 - 9.1). Return [M0 formatted %.3e, Mw rounded 0.01].

split: open-access


prompt:
Every moment magnitude is 4.7 units low.

Rigidity in GPa, rupture length and width in km, average slip in m; any non-positive value returns None. M0 = mu * area * slip in N*m (SI), Mw = 2/3 (log10 M0 - 9.1). Return [M0 formatted %.3e, Mw rounded 0.01].

split: open-access


prompt:
Large ruptures come out with implausible magnitudes above 15.

Rigidity in GPa, rupture length and width in km, average slip in m; any non-positive value returns None. M0 = mu * area * slip in N*m (SI), Mw = 2/3 (log10 M0 - 9.1). Return [M0 formatted %.3e, Mw rounded 0.01].

split: open-access


prompt:
A swarm with one large event is reported far smaller than that event alone.

Surface-wave magnitudes of a swarm; energy per event log10 E = 1.5 Ms + 4.8 (J). Sum energies and invert to the single equivalent magnitude. Return [Meq rounded 0.01, total energy "%.2e"] or None for an empty swarm.

split: open-access


prompt:
The equivalent magnitude of a single M5 event is reported as M11.25.

Surface-wave magnitudes of a swarm; energy per event log10 E = 1.5 Ms + 4.8 (J). Sum energies and invert to the single equivalent magnitude. Return [Meq rounded 0.01, total energy "%.2e"] or None for an empty swarm.

split: open-access


prompt:
Totals are many orders of magnitude too small.

Surface-wave magnitudes of a swarm; energy per event log10 E = 1.5 Ms + 4.8 (J). Sum energies and invert to the single equivalent magnitude. Return [Meq rounded 0.01, total energy "%.2e"] or None for an empty swarm.

split: open-access


prompt:
Long-period readings inflate mb.

P amplitude in micrometres, period in s, epicentral distance in degrees. Valid only for 20 <= delta <= 100 and 0 < period <= 3.0 (else None). Q(delta) is linearly interpolated from [(20,6.0),(30,6.5),(40,6.8),(60,6.9),(80,7.0),(100,7.4)]. mb = log10(A/T) + Q, rounded 0.01.

split: open-access


prompt:
Between table nodes the correction runs backward.

P amplitude in micrometres, period in s, epicentral distance in degrees. Valid only for 20 <= delta <= 100 and 0 < period <= 3.0 (else None). Q(delta) is linearly interpolated from [(20,6.0),(30,6.5),(40,6.8),(60,6.9),(80,7.0),(100,7.4)]. mb = log10(A/T) + Q, rounded 0.01.

split: open-access


prompt:
Stations at exactly 100 degrees are rejected.

P amplitude in micrometres, period in s, epicentral distance in degrees. Valid only for 20 <= delta <= 100 and 0 < period <= 3.0 (else None). Q(delta) is linearly interpolated from [(20,6.0),(30,6.5),(40,6.8),(60,6.9),(80,7.0),(100,7.4)]. mb = log10(A/T) + Q, rounded 0.01.

split: open-access


prompt:
3.0 s readings are discarded.

P amplitude in micrometres, period in s, epicentral distance in degrees. Valid only for 20 <= delta <= 100 and 0 < period <= 3.0 (else None). Q(delta) is linearly interpolated from [(20,6.0),(30,6.5),(40,6.8),(60,6.9),(80,7.0),(100,7.4)]. mb = log10(A/T) + Q, rounded 0.01.

split: open-access


prompt:
18 s Rayleigh readings are excluded.

readings are [amplitude um, period s, distance deg]. Events with depth >= 60 km return None. Use only readings with 18 <= T <= 22, 20 <= delta <= 160 and positive amplitude; Ms_i = log10(A/T) + 1.66 log10(delta) + 3.3; return [mean rounded 0.01, count] or None.

split: open-access


prompt:
Ms is about 1.5 units too high.

readings are [amplitude um, period s, distance deg]. Events with depth >= 60 km return None. Use only readings with 18 <= T <= 22, 20 <= delta <= 160 and positive amplitude; Ms_i = log10(A/T) + 1.66 log10(delta) + 3.3; return [mean rounded 0.01, count] or None.

split: open-access


prompt:
Events at exactly 60 km receive an Ms.

readings are [amplitude um, period s, distance deg]. Events with depth >= 60 km return None. Use only readings with 18 <= T <= 22, 20 <= delta <= 160 and positive amplitude; Ms_i = log10(A/T) + 1.66 log10(delta) + 3.3; return [mean rounded 0.01, count] or None.

split: open-access


prompt:
Event Ms follows the single loudest station.

readings are [amplitude um, period s, distance deg]. Events with depth >= 60 km return None. Use only readings with 18 <= T <= 22, 20 <= delta <= 160 and positive amplitude; Ms_i = log10(A/T) + 1.66 log10(delta) + 3.3; return [mean rounded 0.01, count] or None.

split: open-access


prompt:
Records with long pre-event buffers yield inflated durations.

envelope is a list of amplitude samples, dt s per sample, p_index the P pick sample, noise the pre-event noise level. From the peak at or after the pick (first maximum), the coda ends at the first sample with amplitude <= 2*noise. tau = (end - p_index)*dt; Md = -0.87 + 2.0 log10(tau) + 0.0035 epi_km. Return [tau rounded 0.01, Md rounded 0.01] or None when no end or tau <= 0.

split: open-access


prompt:
Coda end is delayed when the envelope settles exactly at twice the noise.

envelope is a list of amplitude samples, dt s per sample, p_index the P pick sample, noise the pre-event noise level. From the peak at or after the pick (first maximum), the coda ends at the first sample with amplitude <= 2*noise. tau = (end - p_index)*dt; Md = -0.87 + 2.0 log10(tau) + 0.0035 epi_km. Return [tau rounded 0.01, Md rounded 0.01] or None when no end or tau <= 0.

split: open-access


prompt:
A quiet sample right after the pick terminates the coda before the S wave peak.

envelope is a list of amplitude samples, dt s per sample, p_index the P pick sample, noise the pre-event noise level. From the peak at or after the pick (first maximum), the coda ends at the first sample with amplitude <= 2*noise. tau = (end - p_index)*dt; Md = -0.87 + 2.0 log10(tau) + 0.0035 epi_km. Return [tau rounded 0.01, Md rounded 0.01] or None when no end or tau <= 0.

split: open-access


prompt:
Md grows too fast with duration.

envelope is a list of amplitude samples, dt s per sample, p_index the P pick sample, noise the pre-event noise level. From the peak at or after the pick (first maximum), the coda ends at the first sample with amplitude <= 2*noise. tau = (end - p_index)*dt; Md = -0.87 + 2.0 log10(tau) + 0.0035 epi_km. Return [tau rounded 0.01, Md rounded 0.01] or None when no end or tau <= 0.

split: open-access


prompt:
Events exactly at the completeness magnitude are dropped and b is biased low.

Magnitudes, completeness and bin width in tenths. Use events with M >= Mc; fewer than 2 returns None. b = log10(e) / (mean(M) - (Mc - dM/2)); non-positive denominator returns None. Return [b rounded 0.001, n, sigma = b/sqrt(n) rounded 0.001].

split: open-access


prompt:
b-values are systematically too high for binned catalogues.

Magnitudes, completeness and bin width in tenths. Use events with M >= Mc; fewer than 2 returns None. b = log10(e) / (mean(M) - (Mc - dM/2)); non-positive denominator returns None. Return [b rounded 0.001, n, sigma = b/sqrt(n) rounded 0.001].

split: open-access


prompt:
b-values are about 5.3 times too large.

Magnitudes, completeness and bin width in tenths. Use events with M >= Mc; fewer than 2 returns None. b = log10(e) / (mean(M) - (Mc - dM/2)); non-positive denominator returns None. Return [b rounded 0.001, n, sigma = b/sqrt(n) rounded 0.001].

split: open-access


prompt:
A single event above Mc produces a b-value.

Magnitudes, completeness and bin width in tenths. Use events with M >= Mc; fewer than 2 returns None. b = log10(e) / (mean(M) - (Mc - dM/2)); non-positive denominator returns None. Return [b rounded 0.001, n, sigma = b/sqrt(n) rounded 0.001].

split: open-access


prompt:
Reported uncertainties shrink far too quickly with catalogue size.

Magnitudes, completeness and bin width in tenths. Use events with M >= Mc; fewer than 2 returns None. b = log10(e) / (mean(M) - (Mc - dM/2)); non-positive denominator returns None. Return [b rounded 0.001, n, sigma = b/sqrt(n) rounded 0.001].

split: open-access


prompt:
Magnitudes such as 1.46 fall in the 1.4 bin, shifting Mc down.

Magnitudes in hundredths are binned to 0.1 by rounding half up (floor((m+5)/10) tenths). Mc is the bin with the highest count (ties: lowest bin) plus a 0.2 correction. Return Mc in magnitude units rounded 0.1, or None when empty.

split: open-access


prompt:
Ties choose the higher bin and Mc is overstated.

Magnitudes in hundredths are binned to 0.1 by rounding half up (floor((m+5)/10) tenths). Mc is the bin with the highest count (ties: lowest bin) plus a 0.2 correction. Return Mc in magnitude units rounded 0.1, or None when empty.

split: open-access


prompt:
Mc is 0.2 units too low, admitting incomplete bins.

Magnitudes in hundredths are binned to 0.1 by rounding half up (floor((m+5)/10) tenths). Mc is the bin with the highest count (ties: lowest bin) plus a 0.2 correction. Return Mc in magnitude units rounded 0.1, or None when empty.

split: open-access


prompt:
East-west distances are wildly wrong while north-south ones are fine.

event [lat, lon] and stations [code, lat, lon] in degrees. Haversine distance with R = 6371 km. Keep stations within 600 km inclusive. Return [[code, km rounded 0.1, degrees rounded 0.001]] sorted by distance then code.

split: open-access


prompt:
Distances in degrees are reported in radians.

event [lat, lon] and stations [code, lat, lon] in degrees. Haversine distance with R = 6371 km. Keep stations within 600 km inclusive. Return [[code, km rounded 0.1, degrees rounded 0.001]] sorted by distance then code.

split: open-access


prompt:
Station lists are alphabetical instead of nearest first.

event [lat, lon] and stations [code, lat, lon] in degrees. Haversine distance with R = 6371 km. Keep stations within 600 km inclusive. Return [[code, km rounded 0.1, degrees rounded 0.001]] sorted by distance then code.

split: open-access


prompt:
North-south separations are doubled.

event [lat, lon] and stations [code, lat, lon] in degrees. Haversine distance with R = 6371 km. Keep stations within 600 km inclusive. Return [[code, km rounded 0.1, degrees rounded 0.001]] sorted by distance then code.

split: open-access


prompt:
Traces with a DC offset integrate into huge drifting displacements.

Velocity-sensor counts, sensitivity counts per m/s, sample interval s. Remove the mean, convert to m/s, integrate with the trapezoid rule from 0, take the maximum absolute displacement, multiply by the Wood-Anderson gain 2080 and convert to mm. Return mm rounded to 1e-4, None for an empty trace.

split: open-access


prompt:
Displacement amplitudes shift by half a sample of velocity.

Velocity-sensor counts, sensitivity counts per m/s, sample interval s. Remove the mean, convert to m/s, integrate with the trapezoid rule from 0, take the maximum absolute displacement, multiply by the Wood-Anderson gain 2080 and convert to mm. Return mm rounded to 1e-4, None for an empty trace.

split: open-access


prompt:
Local magnitudes are 0.13 units high.

Velocity-sensor counts, sensitivity counts per m/s, sample interval s. Remove the mean, convert to m/s, integrate with the trapezoid rule from 0, take the maximum absolute displacement, multiply by the Wood-Anderson gain 2080 and convert to mm. Return mm rounded to 1e-4, None for an empty trace.

split: open-access


prompt:
Negative-going pulses are ignored.

Velocity-sensor counts, sensitivity counts per m/s, sample interval s. Remove the mean, convert to m/s, integrate with the trapezoid rule from 0, take the maximum absolute displacement, multiply by the Wood-Anderson gain 2080 and convert to mm. Return mm rounded to 1e-4, None for an empty trace.

split: open-access


prompt:
A record touching 95% of full scale is used for magnitude.

Integer counts. If any |sample| >= 0.95*full_scale (integer-truncated) return ["clipped", None]. Otherwise turning points are the first sample, every interior sample that is a peak (b > a and b >= c) or trough (b < a and b <= c), and the last sample; the amplitude is half the largest absolute difference between consecutive turning points. Return ["ok", amplitude].

split: open-access


prompt:
Amplitudes are double and magnitudes 0.3 high.

Integer counts. If any |sample| >= 0.95*full_scale (integer-truncated) return ["clipped", None]. Otherwise turning points are the first sample, every interior sample that is a peak (b > a and b >= c) or trough (b < a and b <= c), and the last sample; the amplitude is half the largest absolute difference between consecutive turning points. Return ["ok", amplitude].

split: open-access


prompt:
Non-adjacent extremes several cycles apart are combined into one swing.

Integer counts. If any |sample| >= 0.95*full_scale (integer-truncated) return ["clipped", None]. Otherwise turning points are the first sample, every interior sample that is a peak (b > a and b >= c) or trough (b < a and b <= c), and the last sample; the amplitude is half the largest absolute difference between consecutive turning points. Return ["ok", amplitude].

split: open-access


prompt:
A swing that ends at the window edge is missed.

Integer counts. If any |sample| >= 0.95*full_scale (integer-truncated) return ["clipped", None]. Otherwise turning points are the first sample, every interior sample that is a peak (b > a and b >= c) or trough (b < a and b <= c), and the last sample; the amplitude is half the largest absolute difference between consecutive turning points. Return ["ok", amplitude].

split: open-access


prompt:
Events at exactly 70 km prefer mb over Ms.

mags maps type to value (any value including 0 or negative is valid when the key is present). Choose in order: Mw; if depth > 70 km then mb; Ms if Ms >= 5.5; ML if delta <= 5 degrees; mb; Md; else None. Return [type, value].

split: open-access


prompt:
An Ms of exactly 5.5 is passed over for ML or mb.

mags maps type to value (any value including 0 or negative is valid when the key is present). Choose in order: Mw; if depth > 70 km then mb; Ms if Ms >= 5.5; ML if delta <= 5 degrees; mb; Md; else None. Return [type, value].

split: open-access


prompt:
Local events almost never report ML.

mags maps type to value (any value including 0 or negative is valid when the key is present). Choose in order: Mw; if depth > 70 km then mb; Ms if Ms >= 5.5; ML if delta <= 5 degrees; mb; Md; else None. Return [type, value].

split: open-access


prompt:
A microearthquake with ML 0.0 falls through to Md.

mags maps type to value (any value including 0 or negative is valid when the key is present). Choose in order: Mw; if depth > 70 km then mb; Ms if Ms >= 5.5; ML if delta <= 5 degrees; mb; Md; else None. Return [type, value].

split: open-access


prompt:
Deep events with a moment magnitude publish mb instead.

mags maps type to value (any value including 0 or negative is valid when the key is present). Choose in order: Mw; if depth > 70 km then mb; Ms if Ms >= 5.5; ML if delta <= 5 degrees; mb; Md; else None. Return [type, value].

split: open-access


prompt:
Forecasts for p = 1 sequences are 2.3 times too low.

Rate K/(t+c)^p aftershocks per day. Expected count on [t1, t2] days: for p == 1 (within 1e-12) K ln((t2+c)/(t1+c)); otherwise K((t1+c)^(1-p) - (t2+c)^(1-p))/(p-1). t1 < 0 or t2 <= t1 returns None. Round to 0.001.

split: open-access


prompt:
Expected aftershock counts are negative.

Rate K/(t+c)^p aftershocks per day. Expected count on [t1, t2] days: for p == 1 (within 1e-12) K ln((t2+c)/(t1+c)); otherwise K((t1+c)^(1-p) - (t2+c)^(1-p))/(p-1). t1 < 0 or t2 <= t1 returns None. Round to 0.001.

split: open-access


prompt:
A zero-length window returns a zero forecast instead of None.

Rate K/(t+c)^p aftershocks per day. Expected count on [t1, t2] days: for p == 1 (within 1e-12) K ln((t2+c)/(t1+c)); otherwise K((t1+c)^(1-p) - (t2+c)^(1-p))/(p-1). t1 < 0 or t2 <= t1 returns None. Round to 0.001.

split: open-access


prompt:
Early-window forecasts are badly inflated.

Rate K/(t+c)^p aftershocks per day. Expected count on [t1, t2] days: for p == 1 (within 1e-12) K ln((t2+c)/(t1+c)); otherwise K((t1+c)^(1-p) - (t2+c)^(1-p))/(p-1). t1 < 0 or t2 <= t1 returns None. Round to 0.001.

split: open-access


prompt:
PGD magnitudes are several units too high and distance-independent.

obs are [PGD in m, epicentral km]. Per station PGD in cm, R = hypocentral distance; skip PGD < 2 cm or R > 1000 km. log10(PGD) = A + B M + C M log10 R with A=-4.434, B=1.047, C=-0.138, solved for M. Return [mean M rounded 0.01, stations used] or None.

split: open-access


prompt:
Every station magnitude is about one unit high and small signals pass the noise gate.

obs are [PGD in m, epicentral km]. Per station PGD in cm, R = hypocentral distance; skip PGD < 2 cm or R > 1000 km. log10(PGD) = A + B M + C M log10 R with A=-4.434, B=1.047, C=-0.138, solved for M. Return [mean M rounded 0.01, stations used] or None.

split: open-access


prompt:
Stations at exactly the 2 cm floor are dropped.

obs are [PGD in m, epicentral km]. Per station PGD in cm, R = hypocentral distance; skip PGD < 2 cm or R > 1000 km. log10(PGD) = A + B M + C M log10 R with A=-4.434, B=1.047, C=-0.138, solved for M. Return [mean M rounded 0.01, stations used] or None.

split: open-access


prompt:
Nearby stations of deep events give inflated magnitudes.

obs are [PGD in m, epicentral km]. Per station PGD in cm, R = hypocentral distance; skip PGD < 2 cm or R > 1000 km. log10(PGD) = A + B M + C M log10 R with A=-4.434, B=1.047, C=-0.138, solved for M. Return [mean M rounded 0.01, stations used] or None.

split: open-access


prompt:
Intensity V is labelled VI.

R = max(hypocentral distance, 1 km). I = 1.45M - 2.46 log10(R) + 1.5, rounded half up to an integer and clamped to 1..12. Return [I, Roman numeral].

split: open-access


prompt:
Distant small events show negative intensities and wrap around the numeral table.

R = max(hypocentral distance, 1 km). I = 1.45M - 2.46 log10(R) + 1.5, rounded half up to an integer and clamped to 1..12. Return [I, Roman numeral].

split: open-access


prompt:
Intensity 6.7 is reported as VI.

R = max(hypocentral distance, 1 km). I = 1.45M - 2.46 log10(R) + 1.5, rounded half up to an integer and clamped to 1..12. Return [I, Roman numeral].

split: open-access


prompt:
Very shallow events directly under a site produce extreme intensities.

R = max(hypocentral distance, 1 km). I = 1.45M - 2.46 log10(R) + 1.5, rounded half up to an integer and clamped to 1..12. Return [I, Roman numeral].

split: open-access


prompt:
Source radii are a thousand times too small and stress drops astronomically high.

Seismic moment N*m, corner frequency Hz, shear velocity km/s; non-positive input returns None. r = 2.34 beta / (2 pi fc) in m; stress drop = 7/16 M0 / r^3 Pa. Return [r rounded 0.1 m, stress drop in MPa rounded 0.001].

split: open-access


prompt:
Radii are 6.3 times too large and stress drops 250 times too small.

Seismic moment N*m, corner frequency Hz, shear velocity km/s; non-positive input returns None. r = 2.34 beta / (2 pi fc) in m; stress drop = 7/16 M0 / r^3 Pa. Return [r rounded 0.1 m, stress drop in MPa rounded 0.001].

split: open-access


prompt:
Every stress drop is exactly zero.

Seismic moment N*m, corner frequency Hz, shear velocity km/s; non-positive input returns None. r = 2.34 beta / (2 pi fc) in m; stress drop = 7/16 M0 / r^3 Pa. Return [r rounded 0.1 m, stress drop in MPa rounded 0.001].

split: open-access


prompt:
Stress drops carry units of force per length and are orders of magnitude off.

Seismic moment N*m, corner frequency Hz, shear velocity km/s; non-positive input returns None. r = 2.34 beta / (2 pi fc) in m; stress drop = 7/16 M0 / r^3 Pa. Return [r rounded 0.1 m, stress drop in MPa rounded 0.001].

split: open-access


prompt:
Stress drops are reported ten times too large.

Seismic moment N*m, corner frequency Hz, shear velocity km/s; non-positive input returns None. r = 2.34 beta / (2 pi fc) in m; stress drop = 7/16 M0 / r^3 Pa. Return [r rounded 0.1 m, stress drop in MPa rounded 0.001].

split: open-access


prompt:
Unequal component amplitudes bias ML upward.

Zero-to-peak Wood-Anderson amplitudes on two horizontal components in mm (0 = dead channel, ignored; both dead returns None). -log A0 is linearly interpolated from [(0,1.4),(10,1.5),(20,1.7),(30,2.1),(50,2.6),(100,3.0),(200,3.5),(300,4.0),(400,4.5),(600,5.1)] with 0 <= dist <= 600 inclusive, else None. ML = mean of per-component log10 amplitudes + (-log A0), rounded 0.01.

split: open-access