broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json
import datetime as dt
import calendar
N = 1
observations = []
def solve(dtstart, interval, count, until, offset_min):
    first = dt.datetime.fromisoformat(dtstart)
    if until is None:
        limit = None
    elif until.endswith('Z'):
        limit = dt.datetime.fromisoformat(until[:-1]) + dt.timedelta(minutes=offset_min)
    elif len(until) == 10:
        limit = dt.datetime.combine(dt.date.fromisoformat(until), dt.time(23, 59))
    else:
        limit = dt.datetime.fromisoformat(until)
    out = []
    for k in range(40):
        t = first + dt.timedelta(days=k * interval)
        if limit is not None and t > limit:
            break
        if count is not None and limit is None and len(out) >= count:
            break
        out.append(t.isoformat(timespec='minutes'))
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: count and until both set',
   ['2024-01-01T09:00', 1, 3, '2024-01-10', 0],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00']),
  ('date until includes that day',
   ['2024-01-01T09:00', 2, None, '2024-01-07', 0],
   ['2024-01-01T09:00', '2024-01-03T09:00', '2024-01-05T09:00', '2024-01-07T09:00']),
  ('date until evening event',
   ['2024-01-01T20:00', 1, None, '2024-01-03', 60],
   ['2024-01-01T20:00', '2024-01-02T20:00', '2024-01-03T20:00']),
  ('local until exact',
   ['2024-01-01T09:00', 1, None, '2024-01-04T09:00', 0],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00', '2024-01-04T09:00']),
  ('local until earlier time',
   ['2024-01-01T09:00', 1, None, '2024-01-04T08:00', 0],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00']),
  ('utc until east offset',
   ['2024-01-01T09:00', 1, None, '2024-01-03T07:00Z', 120],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00']),
  ('utc until west offset',
   ['2024-01-01T09:00', 1, None, '2024-01-03T15:30Z', -300],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00']),
  ('count zero', ['2024-01-01T09:00', 1, 0, None, 0], [])],
 [('date until evening event',
   ['2024-01-01T20:00', 1, None, '2024-01-03', 60],
   ['2024-01-01T20:00', '2024-01-02T20:00', '2024-01-03T20:00']),
  ('local until exact',
   ['2024-01-01T09:00', 1, None, '2024-01-04T09:00', 0],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00', '2024-01-04T09:00']),
  ('local until earlier time',
   ['2024-01-01T09:00', 1, None, '2024-01-04T08:00', 0],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00']),
  ('utc until east offset',
   ['2024-01-01T09:00', 1, None, '2024-01-03T07:00Z', 120],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00']),
  ('utc until west offset',
   ['2024-01-01T09:00', 1, None, '2024-01-03T15:30Z', -300],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00']),
  ('count zero', ['2024-01-01T09:00', 1, 0, None, 0], []),
  ('count zero with until', ['2024-01-01T09:00', 1, 0, '2024-02-01', 0], [])],
 [('local until earlier time',
   ['2024-01-01T09:00', 1, None, '2024-01-04T08:00', 0],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00']),
  ('utc until east offset',
   ['2024-01-01T09:00', 1, None, '2024-01-03T07:00Z', 120],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00']),
  ('utc until west offset',
   ['2024-01-01T09:00', 1, None, '2024-01-03T15:30Z', -300],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00']),
  ('count zero', ['2024-01-01T09:00', 1, 0, None, 0], []),
  ('count zero with until', ['2024-01-01T09:00', 1, 0, '2024-02-01', 0], []),
  ('until before count reached',
   ['2024-01-01T09:00', 3, 10, '2024-01-08', 0],
   ['2024-01-01T09:00', '2024-01-04T09:00', '2024-01-07T09:00']),
  ('count before until reached',
   ['2024-03-01T18:30', 7, 2, '2024-12-31T00:00Z', 60],
   ['2024-03-01T18:30', '2024-03-08T18:30'])],
 [('utc until west offset',
   ['2024-01-01T09:00', 1, None, '2024-01-03T15:30Z', -300],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00']),
  ('count zero', ['2024-01-01T09:00', 1, 0, None, 0], []),
  ('count zero with until', ['2024-01-01T09:00', 1, 0, '2024-02-01', 0], []),
  ('until before count reached',
   ['2024-01-01T09:00', 3, 10, '2024-01-08', 0],
   ['2024-01-01T09:00', '2024-01-04T09:00', '2024-01-07T09:00']),
  ('count before until reached',
   ['2024-03-01T18:30', 7, 2, '2024-12-31T00:00Z', 60],
   ['2024-03-01T18:30', '2024-03-08T18:30']),
  ('regression: count and until both set',
   ['2024-01-01T09:00', 1, 3, '2024-01-10', 0],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00']),
  ('date until includes that day',
   ['2024-01-01T09:00', 2, None, '2024-01-07', 0],
   ['2024-01-01T09:00', '2024-01-03T09:00', '2024-01-05T09:00', '2024-01-07T09:00'])],
 [('count zero with until', ['2024-01-01T09:00', 1, 0, '2024-02-01', 0], []),
  ('until before count reached',
   ['2024-01-01T09:00', 3, 10, '2024-01-08', 0],
   ['2024-01-01T09:00', '2024-01-04T09:00', '2024-01-07T09:00']),
  ('count before until reached',
   ['2024-03-01T18:30', 7, 2, '2024-12-31T00:00Z', 60],
   ['2024-03-01T18:30', '2024-03-08T18:30']),
  ('regression: count and until both set',
   ['2024-01-01T09:00', 1, 3, '2024-01-10', 0],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00']),
  ('date until includes that day',
   ['2024-01-01T09:00', 2, None, '2024-01-07', 0],
   ['2024-01-01T09:00', '2024-01-03T09:00', '2024-01-05T09:00', '2024-01-07T09:00']),
  ('date until evening event',
   ['2024-01-01T20:00', 1, None, '2024-01-03', 60],
   ['2024-01-01T20:00', '2024-01-02T20:00', '2024-01-03T20:00']),
  ('local until exact',
   ['2024-01-01T09:00', 1, None, '2024-01-04T09:00', 0],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00', '2024-01-04T09:00'])]]
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
import datetime as dt
import calendar
N = 1
observations = []
def solve(dtstart, interval, count, until, offset_min):
    first = dt.datetime.fromisoformat(dtstart)
    if until is None:
        limit = None
    elif until.endswith('Z'):
        limit = dt.datetime.fromisoformat(until[:-1]) + dt.timedelta(minutes=offset_min)
    elif len(until) == 10:
        limit = dt.datetime.combine(dt.date.fromisoformat(until), dt.time(23, 59))
    else:
        limit = dt.datetime.fromisoformat(until)
    out = []
    for k in range(40):
        t = first + dt.timedelta(days=k * interval)
        if limit is not None and t > limit:
            break
        if count and len(out) >= count:
            break
        out.append(t.isoformat(timespec='minutes'))
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: count and until both set',
   ['2024-01-01T09:00', 1, 3, '2024-01-10', 0],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00']),
  ('date until includes that day',
   ['2024-01-01T09:00', 2, None, '2024-01-07', 0],
   ['2024-01-01T09:00', '2024-01-03T09:00', '2024-01-05T09:00', '2024-01-07T09:00']),
  ('date until evening event',
   ['2024-01-01T20:00', 1, None, '2024-01-03', 60],
   ['2024-01-01T20:00', '2024-01-02T20:00', '2024-01-03T20:00']),
  ('local until exact',
   ['2024-01-01T09:00', 1, None, '2024-01-04T09:00', 0],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00', '2024-01-04T09:00']),
  ('local until earlier time',
   ['2024-01-01T09:00', 1, None, '2024-01-04T08:00', 0],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00']),
  ('utc until east offset',
   ['2024-01-01T09:00', 1, None, '2024-01-03T07:00Z', 120],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00']),
  ('utc until west offset',
   ['2024-01-01T09:00', 1, None, '2024-01-03T15:30Z', -300],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00']),
  ('count zero', ['2024-01-01T09:00', 1, 0, None, 0], [])],
 [('date until evening event',
   ['2024-01-01T20:00', 1, None, '2024-01-03', 60],
   ['2024-01-01T20:00', '2024-01-02T20:00', '2024-01-03T20:00']),
  ('local until exact',
   ['2024-01-01T09:00', 1, None, '2024-01-04T09:00', 0],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00', '2024-01-04T09:00']),
  ('local until earlier time',
   ['2024-01-01T09:00', 1, None, '2024-01-04T08:00', 0],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00']),
  ('utc until east offset',
   ['2024-01-01T09:00', 1, None, '2024-01-03T07:00Z', 120],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00']),
  ('utc until west offset',
   ['2024-01-01T09:00', 1, None, '2024-01-03T15:30Z', -300],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00']),
  ('count zero', ['2024-01-01T09:00', 1, 0, None, 0], []),
  ('count zero with until', ['2024-01-01T09:00', 1, 0, '2024-02-01', 0], [])],
 [('local until earlier time',
   ['2024-01-01T09:00', 1, None, '2024-01-04T08:00', 0],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00']),
  ('utc until east offset',
   ['2024-01-01T09:00', 1, None, '2024-01-03T07:00Z', 120],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00']),
  ('utc until west offset',
   ['2024-01-01T09:00', 1, None, '2024-01-03T15:30Z', -300],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00']),
  ('count zero', ['2024-01-01T09:00', 1, 0, None, 0], []),
  ('count zero with until', ['2024-01-01T09:00', 1, 0, '2024-02-01', 0], []),
  ('until before count reached',
   ['2024-01-01T09:00', 3, 10, '2024-01-08', 0],
   ['2024-01-01T09:00', '2024-01-04T09:00', '2024-01-07T09:00']),
  ('count before until reached',
   ['2024-03-01T18:30', 7, 2, '2024-12-31T00:00Z', 60],
   ['2024-03-01T18:30', '2024-03-08T18:30'])],
 [('utc until west offset',
   ['2024-01-01T09:00', 1, None, '2024-01-03T15:30Z', -300],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00']),
  ('count zero', ['2024-01-01T09:00', 1, 0, None, 0], []),
  ('count zero with until', ['2024-01-01T09:00', 1, 0, '2024-02-01', 0], []),
  ('until before count reached',
   ['2024-01-01T09:00', 3, 10, '2024-01-08', 0],
   ['2024-01-01T09:00', '2024-01-04T09:00', '2024-01-07T09:00']),
  ('count before until reached',
   ['2024-03-01T18:30', 7, 2, '2024-12-31T00:00Z', 60],
   ['2024-03-01T18:30', '2024-03-08T18:30']),
  ('regression: count and until both set',
   ['2024-01-01T09:00', 1, 3, '2024-01-10', 0],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00']),
  ('date until includes that day',
   ['2024-01-01T09:00', 2, None, '2024-01-07', 0],
   ['2024-01-01T09:00', '2024-01-03T09:00', '2024-01-05T09:00', '2024-01-07T09:00'])],
 [('count zero with until', ['2024-01-01T09:00', 1, 0, '2024-02-01', 0], []),
  ('until before count reached',
   ['2024-01-01T09:00', 3, 10, '2024-01-08', 0],
   ['2024-01-01T09:00', '2024-01-04T09:00', '2024-01-07T09:00']),
  ('count before until reached',
   ['2024-03-01T18:30', 7, 2, '2024-12-31T00:00Z', 60],
   ['2024-03-01T18:30', '2024-03-08T18:30']),
  ('regression: count and until both set',
   ['2024-01-01T09:00', 1, 3, '2024-01-10', 0],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00']),
  ('date until includes that day',
   ['2024-01-01T09:00', 2, None, '2024-01-07', 0],
   ['2024-01-01T09:00', '2024-01-03T09:00', '2024-01-05T09:00', '2024-01-07T09:00']),
  ('date until evening event',
   ['2024-01-01T20:00', 1, None, '2024-01-03', 60],
   ['2024-01-01T20:00', '2024-01-02T20:00', '2024-01-03T20:00']),
  ('local until exact',
   ['2024-01-01T09:00', 1, None, '2024-01-04T09:00', 0],
   ['2024-01-01T09:00', '2024-01-02T09:00', '2024-01-03T09:00', '2024-01-04T09:00'])]]
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 series with both COUNT and UNTIL runs past COUNT until UNTIL is reached.

A daily-interval timed series in a fixed local offset (offset_min east of UTC). until may be None, a date (inclusive through the end of that local day, i.e. 23:59), a local date-time (inclusive), or a UTC date-time ending in Z (converted to local by adding offset_min). count may be None; count 0 means no instances. When both are given the series stops at whichever limit is reached first. Unbounded series are capped at 40 instances. Return ISO local date-times.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json
import re
N = 1
observations = []
def solve(text):
    parts = {}
    for chunk in text.split(';'):
        if not chunk:
            continue
        if '=' not in chunk:
            return {'error': 'malformed'}
        name, value = chunk.split('=', 1)
        name = name
        if name in parts:
            return {'error': 'duplicate ' + name}
        parts[name] = value
    if 'FREQ' not in parts:
        return {'error': 'missing FREQ'}
    interval = int(parts.get('INTERVAL', '1'))
    if interval < 1:
        return {'error': 'bad INTERVAL'}
    days = []
    for token in (parts['BYDAY'].split(',') if 'BYDAY' in parts else []):
        m = re.fullmatch(r'([+-]?\d{1,2})?(MO|TU|WE|TH|FR|SA|SU)', token)
        if not m:
            return {'error': 'bad BYDAY ' + token}
        n = int(m.group(1)) if m.group(1) else 0
        if m.group(1) and not 1 <= abs(n) <= 53:
            return {'error': 'bad ordinal'}
        days.append([n, m.group(2)])
    return {'freq': parts['FREQ'], 'interval': interval, 'byday': days,
            'count': int(parts['COUNT']) if 'COUNT' in parts else None, 'until': parts.get('UNTIL')}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: lowercase names',
   ['freq=WEEKLY;interval=2;byday=MO,WE'],
   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None}),
  ('duplicate count', ['FREQ=DAILY;COUNT=3;COUNT=5'], {'error': 'duplicate COUNT'}),
  ('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'}),
  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),
  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None})],
 [('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'}),
  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),
  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('regression: lowercase names',
   ['freq=WEEKLY;interval=2;byday=MO,WE'],
   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None})],
 [('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),
  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'})],
 [('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),
  ('missing freq', ['COUNT=3;BYDAY=MO'], {'error': 'missing FREQ'}),
  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'})],
 [('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),
  ('missing freq', ['COUNT=3;BYDAY=MO'], {'error': 'missing FREQ'}),
  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'}),
  ('regression: lowercase names',
   ['freq=WEEKLY;interval=2;byday=MO,WE'],
   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None}),
  ('duplicate count', ['FREQ=DAILY;COUNT=3;COUNT=5'], {'error': 'duplicate COUNT'})]]
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
import re
N = 1
observations = []
def solve(text):
    parts = {}
    for chunk in text.split(';'):
        if not chunk:
            continue
        if '=' not in chunk:
            return {'error': 'malformed'}
        name, value = chunk.split('=', 1)
        name = name.strip()
        if name in parts:
            return {'error': 'duplicate ' + name}
        parts[name] = value
    if 'FREQ' not in parts:
        return {'error': 'missing FREQ'}
    interval = int(parts.get('INTERVAL', '1'))
    if interval < 1:
        return {'error': 'bad INTERVAL'}
    days = []
    for token in (parts['BYDAY'].split(',') if 'BYDAY' in parts else []):
        m = re.fullmatch(r'([+-]?\d{1,2})?(MO|TU|WE|TH|FR|SA|SU)', token)
        if not m:
            return {'error': 'bad BYDAY ' + token}
        n = int(m.group(1)) if m.group(1) else 0
        if m.group(1) and not 1 <= abs(n) <= 53:
            return {'error': 'bad ordinal'}
        days.append([n, m.group(2)])
    return {'freq': parts['FREQ'], 'interval': interval, 'byday': days,
            'count': int(parts['COUNT']) if 'COUNT' in parts else None, 'until': parts.get('UNTIL')}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: lowercase names',
   ['freq=WEEKLY;interval=2;byday=MO,WE'],
   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None}),
  ('duplicate count', ['FREQ=DAILY;COUNT=3;COUNT=5'], {'error': 'duplicate COUNT'}),
  ('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'}),
  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),
  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None})],
 [('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'}),
  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),
  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('regression: lowercase names',
   ['freq=WEEKLY;interval=2;byday=MO,WE'],
   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None})],
 [('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),
  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'})],
 [('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),
  ('missing freq', ['COUNT=3;BYDAY=MO'], {'error': 'missing FREQ'}),
  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'})],
 [('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),
  ('missing freq', ['COUNT=3;BYDAY=MO'], {'error': 'missing FREQ'}),
  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'}),
  ('regression: lowercase names',
   ['freq=WEEKLY;interval=2;byday=MO,WE'],
   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None}),
  ('duplicate count', ['FREQ=DAILY;COUNT=3;COUNT=5'], {'error': 'duplicate COUNT'})]]
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 rule written as "freq=weekly" is rejected as missing FREQ.

Parse "NAME=VALUE;..." rule text. Part names are case-insensitive; empty parts (a trailing ";") are ignored; a part without "=" is malformed; any repeated part name is an error; FREQ is required. INTERVAL defaults to 1 and must be >= 1. BYDAY tokens are an optional signed 1-2 digit ordinal (explicit "+" allowed) followed by MO..SU; a present ordinal must satisfy 1 <= |n| <= 53. Errors are returned as {"error": message}; otherwise {"freq","interval","byday":[[n, day]],"count","until"}.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json
import re
N = 1
observations = []
def solve(text):
    parts = {}
    for chunk in text.split(';'):
        if not chunk:
            continue
        if '=' not in chunk:
            return {'error': 'malformed'}
        name, value = chunk.split('=', 1)
        name = name.upper()
        if name == 'FREQ' and name in parts:
            return {'error': 'duplicate ' + name}
        parts[name] = value
    if 'FREQ' not in parts:
        return {'error': 'missing FREQ'}
    interval = int(parts.get('INTERVAL', '1'))
    if interval < 1:
        return {'error': 'bad INTERVAL'}
    days = []
    for token in (parts['BYDAY'].split(',') if 'BYDAY' in parts else []):
        m = re.fullmatch(r'([+-]?\d{1,2})?(MO|TU|WE|TH|FR|SA|SU)', token)
        if not m:
            return {'error': 'bad BYDAY ' + token}
        n = int(m.group(1)) if m.group(1) else 0
        if m.group(1) and not 1 <= abs(n) <= 53:
            return {'error': 'bad ordinal'}
        days.append([n, m.group(2)])
    return {'freq': parts['FREQ'], 'interval': interval, 'byday': days,
            'count': int(parts['COUNT']) if 'COUNT' in parts else None, 'until': parts.get('UNTIL')}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: lowercase names',
   ['freq=WEEKLY;interval=2;byday=MO,WE'],
   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None}),
  ('duplicate count', ['FREQ=DAILY;COUNT=3;COUNT=5'], {'error': 'duplicate COUNT'}),
  ('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'}),
  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),
  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None})],
 [('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'}),
  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),
  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None})],
 [('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),
  ('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'})],
 [('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),
  ('missing freq', ['COUNT=3;BYDAY=MO'], {'error': 'missing FREQ'}),
  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'}),
  ('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'})],
 [('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),
  ('missing freq', ['COUNT=3;BYDAY=MO'], {'error': 'missing FREQ'}),
  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'}),
  ('regression: lowercase names',
   ['freq=WEEKLY;interval=2;byday=MO,WE'],
   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None}),
  ('duplicate count', ['FREQ=DAILY;COUNT=3;COUNT=5'], {'error': 'duplicate COUNT'}),
  ('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'})]]
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
import re
N = 1
observations = []
def solve(text):
    parts = {}
    for chunk in text.split(';'):
        if not chunk:
            continue
        if '=' not in chunk:
            return {'error': 'malformed'}
        name, value = chunk.split('=', 1)
        name = name.upper()
        if name in parts and parts[name] != value:
            return {'error': 'duplicate ' + name}
        parts[name] = value
    if 'FREQ' not in parts:
        return {'error': 'missing FREQ'}
    interval = int(parts.get('INTERVAL', '1'))
    if interval < 1:
        return {'error': 'bad INTERVAL'}
    days = []
    for token in (parts['BYDAY'].split(',') if 'BYDAY' in parts else []):
        m = re.fullmatch(r'([+-]?\d{1,2})?(MO|TU|WE|TH|FR|SA|SU)', token)
        if not m:
            return {'error': 'bad BYDAY ' + token}
        n = int(m.group(1)) if m.group(1) else 0
        if m.group(1) and not 1 <= abs(n) <= 53:
            return {'error': 'bad ordinal'}
        days.append([n, m.group(2)])
    return {'freq': parts['FREQ'], 'interval': interval, 'byday': days,
            'count': int(parts['COUNT']) if 'COUNT' in parts else None, 'until': parts.get('UNTIL')}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: lowercase names',
   ['freq=WEEKLY;interval=2;byday=MO,WE'],
   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None}),
  ('duplicate count', ['FREQ=DAILY;COUNT=3;COUNT=5'], {'error': 'duplicate COUNT'}),
  ('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'}),
  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),
  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None})],
 [('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'}),
  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),
  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None})],
 [('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),
  ('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'})],
 [('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),
  ('missing freq', ['COUNT=3;BYDAY=MO'], {'error': 'missing FREQ'}),
  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'}),
  ('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'})],
 [('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),
  ('missing freq', ['COUNT=3;BYDAY=MO'], {'error': 'missing FREQ'}),
  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'}),
  ('regression: lowercase names',
   ['freq=WEEKLY;interval=2;byday=MO,WE'],
   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None}),
  ('duplicate count', ['FREQ=DAILY;COUNT=3;COUNT=5'], {'error': 'duplicate COUNT'}),
  ('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'})]]
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 rule with two COUNT parts silently keeps the last one.

Parse "NAME=VALUE;..." rule text. Part names are case-insensitive; empty parts (a trailing ";") are ignored; a part without "=" is malformed; any repeated part name is an error; FREQ is required. INTERVAL defaults to 1 and must be >= 1. BYDAY tokens are an optional signed 1-2 digit ordinal (explicit "+" allowed) followed by MO..SU; a present ordinal must satisfy 1 <= |n| <= 53. Errors are returned as {"error": message}; otherwise {"freq","interval","byday":[[n, day]],"count","until"}.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json
import re
N = 1
observations = []
def solve(text):
    parts = {}
    for chunk in text.split(';'):
        if not chunk:
            continue
        if '=' not in chunk:
            return {'error': 'malformed'}
        name, value = chunk.split('=', 1)
        name = name.upper()
        if name in parts:
            return {'error': 'duplicate ' + name}
        parts[name] = value
    if 'FREQ' not in parts:
        return {'error': 'missing FREQ'}
    interval = int(parts.get('INTERVAL', '1'))
    if interval < 0:
        return {'error': 'bad INTERVAL'}
    days = []
    for token in (parts['BYDAY'].split(',') if 'BYDAY' in parts else []):
        m = re.fullmatch(r'([+-]?\d{1,2})?(MO|TU|WE|TH|FR|SA|SU)', token)
        if not m:
            return {'error': 'bad BYDAY ' + token}
        n = int(m.group(1)) if m.group(1) else 0
        if m.group(1) and not 1 <= abs(n) <= 53:
            return {'error': 'bad ordinal'}
        days.append([n, m.group(2)])
    return {'freq': parts['FREQ'], 'interval': interval, 'byday': days,
            'count': int(parts['COUNT']) if 'COUNT' in parts else None, 'until': parts.get('UNTIL')}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: lowercase names',
   ['freq=WEEKLY;interval=2;byday=MO,WE'],
   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None}),
  ('duplicate count', ['FREQ=DAILY;COUNT=3;COUNT=5'], {'error': 'duplicate COUNT'}),
  ('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'}),
  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),
  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None})],
 [('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'}),
  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),
  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None})],
 [('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),
  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'})],
 [('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),
  ('missing freq', ['COUNT=3;BYDAY=MO'], {'error': 'missing FREQ'}),
  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'}),
  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),
  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'})],
 [('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),
  ('missing freq', ['COUNT=3;BYDAY=MO'], {'error': 'missing FREQ'}),
  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'}),
  ('regression: lowercase names',
   ['freq=WEEKLY;interval=2;byday=MO,WE'],
   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None}),
  ('duplicate count', ['FREQ=DAILY;COUNT=3;COUNT=5'], {'error': 'duplicate COUNT'}),
  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),
  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'})]]
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
import re
N = 1
observations = []
def solve(text):
    parts = {}
    for chunk in text.split(';'):
        if not chunk:
            continue
        if '=' not in chunk:
            return {'error': 'malformed'}
        name, value = chunk.split('=', 1)
        name = name.upper()
        if name in parts:
            return {'error': 'duplicate ' + name}
        parts[name] = value
    if 'FREQ' not in parts:
        return {'error': 'missing FREQ'}
    interval = int(parts.get('INTERVAL', '1'))
    if interval == 0:
        return {'error': 'bad INTERVAL'}
    days = []
    for token in (parts['BYDAY'].split(',') if 'BYDAY' in parts else []):
        m = re.fullmatch(r'([+-]?\d{1,2})?(MO|TU|WE|TH|FR|SA|SU)', token)
        if not m:
            return {'error': 'bad BYDAY ' + token}
        n = int(m.group(1)) if m.group(1) else 0
        if m.group(1) and not 1 <= abs(n) <= 53:
            return {'error': 'bad ordinal'}
        days.append([n, m.group(2)])
    return {'freq': parts['FREQ'], 'interval': interval, 'byday': days,
            'count': int(parts['COUNT']) if 'COUNT' in parts else None, 'until': parts.get('UNTIL')}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: lowercase names',
   ['freq=WEEKLY;interval=2;byday=MO,WE'],
   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None}),
  ('duplicate count', ['FREQ=DAILY;COUNT=3;COUNT=5'], {'error': 'duplicate COUNT'}),
  ('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'}),
  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),
  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None})],
 [('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'}),
  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),
  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None})],
 [('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),
  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'})],
 [('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),
  ('missing freq', ['COUNT=3;BYDAY=MO'], {'error': 'missing FREQ'}),
  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'}),
  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),
  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'})],
 [('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),
  ('missing freq', ['COUNT=3;BYDAY=MO'], {'error': 'missing FREQ'}),
  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'}),
  ('regression: lowercase names',
   ['freq=WEEKLY;interval=2;byday=MO,WE'],
   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None}),
  ('duplicate count', ['FREQ=DAILY;COUNT=3;COUNT=5'], {'error': 'duplicate COUNT'}),
  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),
  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'})]]
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:
INTERVAL=0 is accepted and later makes expansion loop forever.

Parse "NAME=VALUE;..." rule text. Part names are case-insensitive; empty parts (a trailing ";") are ignored; a part without "=" is malformed; any repeated part name is an error; FREQ is required. INTERVAL defaults to 1 and must be >= 1. BYDAY tokens are an optional signed 1-2 digit ordinal (explicit "+" allowed) followed by MO..SU; a present ordinal must satisfy 1 <= |n| <= 53. Errors are returned as {"error": message}; otherwise {"freq","interval","byday":[[n, day]],"count","until"}.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json
import re
N = 1
observations = []
def solve(text):
    parts = {}
    for chunk in text.split(';'):
        if not chunk:
            continue
        if '=' not in chunk:
            return {'error': 'malformed'}
        name, value = chunk.split('=', 1)
        name = name.upper()
        if name in parts:
            return {'error': 'duplicate ' + name}
        parts[name] = value
    if 'FREQ' not in parts:
        return {'error': 'missing FREQ'}
    interval = int(parts.get('INTERVAL', '1'))
    if interval < 1:
        return {'error': 'bad INTERVAL'}
    days = []
    for token in (parts['BYDAY'].split(',') if 'BYDAY' in parts else []):
        m = re.fullmatch(r'(-?\d{1,2})?(MO|TU|WE|TH|FR|SA|SU)', token)
        if not m:
            return {'error': 'bad BYDAY ' + token}
        n = int(m.group(1)) if m.group(1) else 0
        if m.group(1) and not 1 <= abs(n) <= 53:
            return {'error': 'bad ordinal'}
        days.append([n, m.group(2)])
    return {'freq': parts['FREQ'], 'interval': interval, 'byday': days,
            'count': int(parts['COUNT']) if 'COUNT' in parts else None, 'until': parts.get('UNTIL')}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: lowercase names',
   ['freq=WEEKLY;interval=2;byday=MO,WE'],
   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None}),
  ('duplicate count', ['FREQ=DAILY;COUNT=3;COUNT=5'], {'error': 'duplicate COUNT'}),
  ('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'}),
  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),
  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None})],
 [('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'}),
  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),
  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None})],
 [('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'})],
 [('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),
  ('missing freq', ['COUNT=3;BYDAY=MO'], {'error': 'missing FREQ'}),
  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None})],
 [('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),
  ('missing freq', ['COUNT=3;BYDAY=MO'], {'error': 'missing FREQ'}),
  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'}),
  ('regression: lowercase names',
   ['freq=WEEKLY;interval=2;byday=MO,WE'],
   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None}),
  ('duplicate count', ['FREQ=DAILY;COUNT=3;COUNT=5'], {'error': 'duplicate COUNT'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None})]]
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
import re
N = 1
observations = []
def solve(text):
    parts = {}
    for chunk in text.split(';'):
        if not chunk:
            continue
        if '=' not in chunk:
            return {'error': 'malformed'}
        name, value = chunk.split('=', 1)
        name = name.upper()
        if name in parts:
            return {'error': 'duplicate ' + name}
        parts[name] = value
    if 'FREQ' not in parts:
        return {'error': 'missing FREQ'}
    interval = int(parts.get('INTERVAL', '1'))
    if interval < 1:
        return {'error': 'bad INTERVAL'}
    days = []
    for token in (parts['BYDAY'].split(',') if 'BYDAY' in parts else []):
        m = re.fullmatch(r'([+-]?\d)?(MO|TU|WE|TH|FR|SA|SU)', token)
        if not m:
            return {'error': 'bad BYDAY ' + token}
        n = int(m.group(1)) if m.group(1) else 0
        if m.group(1) and not 1 <= abs(n) <= 53:
            return {'error': 'bad ordinal'}
        days.append([n, m.group(2)])
    return {'freq': parts['FREQ'], 'interval': interval, 'byday': days,
            'count': int(parts['COUNT']) if 'COUNT' in parts else None, 'until': parts.get('UNTIL')}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: lowercase names',
   ['freq=WEEKLY;interval=2;byday=MO,WE'],
   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None}),
  ('duplicate count', ['FREQ=DAILY;COUNT=3;COUNT=5'], {'error': 'duplicate COUNT'}),
  ('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'}),
  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),
  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None})],
 [('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'}),
  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),
  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None})],
 [('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'})],
 [('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),
  ('missing freq', ['COUNT=3;BYDAY=MO'], {'error': 'missing FREQ'}),
  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None})],
 [('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),
  ('missing freq', ['COUNT=3;BYDAY=MO'], {'error': 'missing FREQ'}),
  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'}),
  ('regression: lowercase names',
   ['freq=WEEKLY;interval=2;byday=MO,WE'],
   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None}),
  ('duplicate count', ['FREQ=DAILY;COUNT=3;COUNT=5'], {'error': 'duplicate COUNT'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None})]]
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:
BYDAY=+2TU is rejected as malformed.

Parse "NAME=VALUE;..." rule text. Part names are case-insensitive; empty parts (a trailing ";") are ignored; a part without "=" is malformed; any repeated part name is an error; FREQ is required. INTERVAL defaults to 1 and must be >= 1. BYDAY tokens are an optional signed 1-2 digit ordinal (explicit "+" allowed) followed by MO..SU; a present ordinal must satisfy 1 <= |n| <= 53. Errors are returned as {"error": message}; otherwise {"freq","interval","byday":[[n, day]],"count","until"}.

split: open-access


broken_source:
"""Failure Map reference implementation. Python standard library only."""
import json
import re
N = 1
observations = []
def solve(text):
    parts = {}
    for chunk in text.split(';'):
        if not chunk:
            continue
        if '=' not in chunk:
            return {'error': 'malformed'}
        name, value = chunk.split('=', 1)
        name = name.upper()
        if name in parts:
            return {'error': 'duplicate ' + name}
        parts[name] = value
    if 'FREQ' not in parts:
        return {'error': 'missing FREQ'}
    interval = int(parts.get('INTERVAL', '1'))
    if interval < 1:
        return {'error': 'bad INTERVAL'}
    days = []
    for token in (parts['BYDAY'].split(',') if 'BYDAY' in parts else []):
        m = re.fullmatch(r'([+-]?\d{1,2})?(MO|TU|WE|TH|FR|SA|SU)', token)
        if not m:
            return {'error': 'bad BYDAY ' + token}
        n = int(m.group(1)) if m.group(1) else 0
        if not -53 <= n <= 53:
            return {'error': 'bad ordinal'}
        days.append([n, m.group(2)])
    return {'freq': parts['FREQ'], 'interval': interval, 'byday': days,
            'count': int(parts['COUNT']) if 'COUNT' in parts else None, 'until': parts.get('UNTIL')}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: lowercase names',
   ['freq=WEEKLY;interval=2;byday=MO,WE'],
   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None}),
  ('duplicate count', ['FREQ=DAILY;COUNT=3;COUNT=5'], {'error': 'duplicate COUNT'}),
  ('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'}),
  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),
  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None})],
 [('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'}),
  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),
  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None})],
 [('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'})],
 [('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),
  ('missing freq', ['COUNT=3;BYDAY=MO'], {'error': 'missing FREQ'}),
  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'})],
 [('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),
  ('missing freq', ['COUNT=3;BYDAY=MO'], {'error': 'missing FREQ'}),
  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'}),
  ('regression: lowercase names',
   ['freq=WEEKLY;interval=2;byday=MO,WE'],
   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None}),
  ('duplicate count', ['FREQ=DAILY;COUNT=3;COUNT=5'], {'error': 'duplicate COUNT'}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'})]]
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
import re
N = 1
observations = []
def solve(text):
    parts = {}
    for chunk in text.split(';'):
        if not chunk:
            continue
        if '=' not in chunk:
            return {'error': 'malformed'}
        name, value = chunk.split('=', 1)
        name = name.upper()
        if name in parts:
            return {'error': 'duplicate ' + name}
        parts[name] = value
    if 'FREQ' not in parts:
        return {'error': 'missing FREQ'}
    interval = int(parts.get('INTERVAL', '1'))
    if interval < 1:
        return {'error': 'bad INTERVAL'}
    days = []
    for token in (parts['BYDAY'].split(',') if 'BYDAY' in parts else []):
        m = re.fullmatch(r'([+-]?\d{1,2})?(MO|TU|WE|TH|FR|SA|SU)', token)
        if not m:
            return {'error': 'bad BYDAY ' + token}
        n = int(m.group(1)) if m.group(1) else 0
        if m.group(1) and not 1 <= n <= 53:
            return {'error': 'bad ordinal'}
        days.append([n, m.group(2)])
    return {'freq': parts['FREQ'], 'interval': interval, 'byday': days,
            'count': int(parts['COUNT']) if 'COUNT' in parts else None, 'until': parts.get('UNTIL')}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: lowercase names',
   ['freq=WEEKLY;interval=2;byday=MO,WE'],
   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None}),
  ('duplicate count', ['FREQ=DAILY;COUNT=3;COUNT=5'], {'error': 'duplicate COUNT'}),
  ('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'}),
  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),
  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None})],
 [('identical duplicate', ['FREQ=DAILY;COUNT=3;COUNT=3'], {'error': 'duplicate COUNT'}),
  ('interval zero', ['FREQ=DAILY;INTERVAL=0'], {'error': 'bad INTERVAL'}),
  ('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None})],
 [('interval negative', ['FREQ=DAILY;INTERVAL=-2'], {'error': 'bad INTERVAL'}),
  ('plus ordinal',
   ['FREQ=MONTHLY;BYDAY=+2TU'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[2, 'TU']], 'count': None, 'until': None}),
  ('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'})],
 [('two digit ordinal',
   ['FREQ=YEARLY;BYDAY=20MO'],
   {'freq': 'YEARLY', 'interval': 1, 'byday': [[20, 'MO']], 'count': None, 'until': None}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'}),
  ('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),
  ('missing freq', ['COUNT=3;BYDAY=MO'], {'error': 'missing FREQ'}),
  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'})],
 [('negative ordinal',
   ['FREQ=MONTHLY;BYDAY=-1FR;COUNT=4'],
   {'freq': 'MONTHLY', 'interval': 1, 'byday': [[-1, 'FR']], 'count': 4, 'until': None}),
  ('ordinal too large', ['FREQ=YEARLY;BYDAY=54MO'], {'error': 'bad ordinal'}),
  ('trailing semicolon',
   ['FREQ=WEEKLY;UNTIL=20240301;'],
   {'freq': 'WEEKLY', 'interval': 1, 'byday': [], 'count': None, 'until': '20240301'}),
  ('missing freq', ['COUNT=3;BYDAY=MO'], {'error': 'missing FREQ'}),
  ('mixed-case duplicate', ['FREQ=DAILY;Count=2;COUNT=4'], {'error': 'duplicate COUNT'}),
  ('regression: lowercase names',
   ['freq=WEEKLY;interval=2;byday=MO,WE'],
   {'freq': 'WEEKLY', 'interval': 2, 'byday': [[0, 'MO'], [0, 'WE']], 'count': None, 'until': None}),
  ('duplicate count', ['FREQ=DAILY;COUNT=3;COUNT=5'], {'error': 'duplicate COUNT'}),
  ('zero ordinal', ['FREQ=MONTHLY;BYDAY=0MO'], {'error': 'bad ordinal'})]]
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:
BYDAY=0MO is accepted as if it had no ordinal.

Parse "NAME=VALUE;..." rule text. Part names are case-insensitive; empty parts (a trailing ";") are ignored; a part without "=" is malformed; any repeated part name is an error; FREQ is required. INTERVAL defaults to 1 and must be >= 1. BYDAY tokens are an optional signed 1-2 digit ordinal (explicit "+" allowed) followed by MO..SU; a present ordinal must satisfy 1 <= |n| <= 53. Errors are returned as {"error": message}; otherwise {"freq","interval","byday":[[n, day]],"count","until"}.

split: open-access


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

N = 1
observations = []
def solve(freq, interval, byday, ordinal, count):
    unit = {'DAILY': 'day', 'WEEKLY': 'week', 'MONTHLY': 'month', 'YEARLY': 'year'}[freq]
    text = 'every %d %ss' % (interval, unit)
    names = {'MO': 'Monday', 'TU': 'Tuesday', 'WE': 'Wednesday', 'TH': 'Thursday', 'FR': 'Friday', 'SA': 'Saturday', 'SU': 'Sunday'}
    order = ['MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU']
    def nth(n):
        return str(n) + {1: 'st', 2: 'nd', 3: 'rd'}.get(n, 'th')
    if ordinal:
        word = ('last' if ordinal == -1 else nth(-ordinal) + ' to last') if ordinal < 0 else nth(ordinal)
        text += ' on the ' + word + ' ' + names[byday[0]]
    elif byday:
        if set(byday) == {'MO', 'TU', 'WE', 'TH', 'FR'}:
            text += ' on weekdays'
        else:
            words = [names[d] for d in sorted(set(byday), key=order.index)]
            text += ' on ' + (words[0] if len(words) == 1 else ', '.join(words[:-1]) + ' and ' + words[-1])
    if count:
        text += ', ' + ('once' if count == 1 else '%d times' % count)
    return text
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: weekly three days',
   ['WEEKLY', 1, ['MO', 'WE', 'FR'], 0, 0],
   'every week on Monday, Wednesday and Friday'),
  ('biweekly single day once', ['WEEKLY', 2, ['TU'], 0, 1], 'every 2 weeks on Tuesday, once'),
  ('last friday monthly', ['MONTHLY', 1, ['FR'], -1, 6], 'every month on the last Friday, 6 times'),
  ('second to last sunday', ['MONTHLY', 3, ['SU'], -2, 0], 'every 3 months on the 2nd to last Sunday'),
  ('second tuesday', ['MONTHLY', 1, ['TU'], 2, 10], 'every month on the 2nd Tuesday, 10 times'),
  ('weekdays exact', ['WEEKLY', 1, ['MO', 'TU', 'WE', 'TH', 'FR'], 0, 0], 'every week on weekdays'),
  ('weekdays reordered',
   ['WEEKLY', 1, ['FR', 'MO', 'TU', 'WE', 'TH'], 0, 3],
   'every week on weekdays, 3 times')],
 [('last friday monthly', ['MONTHLY', 1, ['FR'], -1, 6], 'every month on the last Friday, 6 times'),
  ('second to last sunday', ['MONTHLY', 3, ['SU'], -2, 0], 'every 3 months on the 2nd to last Sunday'),
  ('second tuesday', ['MONTHLY', 1, ['TU'], 2, 10], 'every month on the 2nd Tuesday, 10 times'),
  ('weekdays exact', ['WEEKLY', 1, ['MO', 'TU', 'WE', 'TH', 'FR'], 0, 0], 'every week on weekdays'),
  ('weekdays reordered',
   ['WEEKLY', 1, ['FR', 'MO', 'TU', 'WE', 'TH'], 0, 3],
   'every week on weekdays, 3 times'),
  ('five days with saturday',
   ['WEEKLY', 1, ['MO', 'TU', 'WE', 'TH', 'SA'], 0, 0],
   'every week on Monday, Tuesday, Wednesday, Thursday and Saturday'),
  ('duplicate days', ['WEEKLY', 3, ['SU', 'MO', 'SU'], 0, 2], 'every 3 weeks on Monday and Sunday, 2 times')],
 [('second tuesday', ['MONTHLY', 1, ['TU'], 2, 10], 'every month on the 2nd Tuesday, 10 times'),
  ('weekdays exact', ['WEEKLY', 1, ['MO', 'TU', 'WE', 'TH', 'FR'], 0, 0], 'every week on weekdays'),
  ('weekdays reordered',
   ['WEEKLY', 1, ['FR', 'MO', 'TU', 'WE', 'TH'], 0, 3],
   'every week on weekdays, 3 times'),
  ('five days with saturday',
   ['WEEKLY', 1, ['MO', 'TU', 'WE', 'TH', 'SA'], 0, 0],
   'every week on Monday, Tuesday, Wednesday, Thursday and Saturday'),
  ('duplicate days', ['WEEKLY', 3, ['SU', 'MO', 'SU'], 0, 2], 'every 3 weeks on Monday and Sunday, 2 times'),
  ('daily with count one', ['DAILY', 1, [], 0, 1], 'every day, once'),
  ('yearly interval', ['YEARLY', 4, [], 0, 0], 'every 4 years')],
 [('weekdays reordered',
   ['WEEKLY', 1, ['FR', 'MO', 'TU', 'WE', 'TH'], 0, 3],
   'every week on weekdays, 3 times'),
  ('five days with saturday',
   ['WEEKLY', 1, ['MO', 'TU', 'WE', 'TH', 'SA'], 0, 0],
   'every week on Monday, Tuesday, Wednesday, Thursday and Saturday'),
  ('duplicate days', ['WEEKLY', 3, ['SU', 'MO', 'SU'], 0, 2], 'every 3 weeks on Monday and Sunday, 2 times'),
  ('daily with count one', ['DAILY', 1, [], 0, 1], 'every day, once'),
  ('yearly interval', ['YEARLY', 4, [], 0, 0], 'every 4 years'),
  ('two days unordered', ['WEEKLY', 1, ['TH', 'TU'], 0, 1], 'every week on Tuesday and Thursday, once'),
  ('regression: weekly three days',
   ['WEEKLY', 1, ['MO', 'WE', 'FR'], 0, 0],
   'every week on Monday, Wednesday and Friday')],
 [('duplicate days', ['WEEKLY', 3, ['SU', 'MO', 'SU'], 0, 2], 'every 3 weeks on Monday and Sunday, 2 times'),
  ('daily with count one', ['DAILY', 1, [], 0, 1], 'every day, once'),
  ('yearly interval', ['YEARLY', 4, [], 0, 0], 'every 4 years'),
  ('two days unordered', ['WEEKLY', 1, ['TH', 'TU'], 0, 1], 'every week on Tuesday and Thursday, once'),
  ('regression: weekly three days',
   ['WEEKLY', 1, ['MO', 'WE', 'FR'], 0, 0],
   'every week on Monday, Wednesday and Friday'),
  ('biweekly single day once', ['WEEKLY', 2, ['TU'], 0, 1], 'every 2 weeks on Tuesday, once'),
  ('last friday monthly', ['MONTHLY', 1, ['FR'], -1, 6], 'every month on the last Friday, 6 times')]]
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(freq, interval, byday, ordinal, count):
    unit = {'DAILY': 'day', 'WEEKLY': 'week', 'MONTHLY': 'month', 'YEARLY': 'year'}[freq]
    text = 'every ' + unit if interval == 1 else 'every %d %s' % (interval, unit)
    names = {'MO': 'Monday', 'TU': 'Tuesday', 'WE': 'Wednesday', 'TH': 'Thursday', 'FR': 'Friday', 'SA': 'Saturday', 'SU': 'Sunday'}
    order = ['MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU']
    def nth(n):
        return str(n) + {1: 'st', 2: 'nd', 3: 'rd'}.get(n, 'th')
    if ordinal:
        word = ('last' if ordinal == -1 else nth(-ordinal) + ' to last') if ordinal < 0 else nth(ordinal)
        text += ' on the ' + word + ' ' + names[byday[0]]
    elif byday:
        if set(byday) == {'MO', 'TU', 'WE', 'TH', 'FR'}:
            text += ' on weekdays'
        else:
            words = [names[d] for d in sorted(set(byday), key=order.index)]
            text += ' on ' + (words[0] if len(words) == 1 else ', '.join(words[:-1]) + ' and ' + words[-1])
    if count:
        text += ', ' + ('once' if count == 1 else '%d times' % count)
    return text
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: weekly three days',
   ['WEEKLY', 1, ['MO', 'WE', 'FR'], 0, 0],
   'every week on Monday, Wednesday and Friday'),
  ('biweekly single day once', ['WEEKLY', 2, ['TU'], 0, 1], 'every 2 weeks on Tuesday, once'),
  ('last friday monthly', ['MONTHLY', 1, ['FR'], -1, 6], 'every month on the last Friday, 6 times'),
  ('second to last sunday', ['MONTHLY', 3, ['SU'], -2, 0], 'every 3 months on the 2nd to last Sunday'),
  ('second tuesday', ['MONTHLY', 1, ['TU'], 2, 10], 'every month on the 2nd Tuesday, 10 times'),
  ('weekdays exact', ['WEEKLY', 1, ['MO', 'TU', 'WE', 'TH', 'FR'], 0, 0], 'every week on weekdays'),
  ('weekdays reordered',
   ['WEEKLY', 1, ['FR', 'MO', 'TU', 'WE', 'TH'], 0, 3],
   'every week on weekdays, 3 times')],
 [('last friday monthly', ['MONTHLY', 1, ['FR'], -1, 6], 'every month on the last Friday, 6 times'),
  ('second to last sunday', ['MONTHLY', 3, ['SU'], -2, 0], 'every 3 months on the 2nd to last Sunday'),
  ('second tuesday', ['MONTHLY', 1, ['TU'], 2, 10], 'every month on the 2nd Tuesday, 10 times'),
  ('weekdays exact', ['WEEKLY', 1, ['MO', 'TU', 'WE', 'TH', 'FR'], 0, 0], 'every week on weekdays'),
  ('weekdays reordered',
   ['WEEKLY', 1, ['FR', 'MO', 'TU', 'WE', 'TH'], 0, 3],
   'every week on weekdays, 3 times'),
  ('five days with saturday',
   ['WEEKLY', 1, ['MO', 'TU', 'WE', 'TH', 'SA'], 0, 0],
   'every week on Monday, Tuesday, Wednesday, Thursday and Saturday'),
  ('duplicate days', ['WEEKLY', 3, ['SU', 'MO', 'SU'], 0, 2], 'every 3 weeks on Monday and Sunday, 2 times')],
 [('second tuesday', ['MONTHLY', 1, ['TU'], 2, 10], 'every month on the 2nd Tuesday, 10 times'),
  ('weekdays exact', ['WEEKLY', 1, ['MO', 'TU', 'WE', 'TH', 'FR'], 0, 0], 'every week on weekdays'),
  ('weekdays reordered',
   ['WEEKLY', 1, ['FR', 'MO', 'TU', 'WE', 'TH'], 0, 3],
   'every week on weekdays, 3 times'),
  ('five days with saturday',
   ['WEEKLY', 1, ['MO', 'TU', 'WE', 'TH', 'SA'], 0, 0],
   'every week on Monday, Tuesday, Wednesday, Thursday and Saturday'),
  ('duplicate days', ['WEEKLY', 3, ['SU', 'MO', 'SU'], 0, 2], 'every 3 weeks on Monday and Sunday, 2 times'),
  ('daily with count one', ['DAILY', 1, [], 0, 1], 'every day, once'),
  ('yearly interval', ['YEARLY', 4, [], 0, 0], 'every 4 years')],
 [('weekdays reordered',
   ['WEEKLY', 1, ['FR', 'MO', 'TU', 'WE', 'TH'], 0, 3],
   'every week on weekdays, 3 times'),
  ('five days with saturday',
   ['WEEKLY', 1, ['MO', 'TU', 'WE', 'TH', 'SA'], 0, 0],
   'every week on Monday, Tuesday, Wednesday, Thursday and Saturday'),
  ('duplicate days', ['WEEKLY', 3, ['SU', 'MO', 'SU'], 0, 2], 'every 3 weeks on Monday and Sunday, 2 times'),
  ('daily with count one', ['DAILY', 1, [], 0, 1], 'every day, once'),
  ('yearly interval', ['YEARLY', 4, [], 0, 0], 'every 4 years'),
  ('two days unordered', ['WEEKLY', 1, ['TH', 'TU'], 0, 1], 'every week on Tuesday and Thursday, once'),
  ('regression: weekly three days',
   ['WEEKLY', 1, ['MO', 'WE', 'FR'], 0, 0],
   'every week on Monday, Wednesday and Friday')],
 [('duplicate days', ['WEEKLY', 3, ['SU', 'MO', 'SU'], 0, 2], 'every 3 weeks on Monday and Sunday, 2 times'),
  ('daily with count one', ['DAILY', 1, [], 0, 1], 'every day, once'),
  ('yearly interval', ['YEARLY', 4, [], 0, 0], 'every 4 years'),
  ('two days unordered', ['WEEKLY', 1, ['TH', 'TU'], 0, 1], 'every week on Tuesday and Thursday, once'),
  ('regression: weekly three days',
   ['WEEKLY', 1, ['MO', 'WE', 'FR'], 0, 0],
   'every week on Monday, Wednesday and Friday'),
  ('biweekly single day once', ['WEEKLY', 2, ['TU'], 0, 1], 'every 2 weeks on Tuesday, once'),
  ('last friday monthly', ['MONTHLY', 1, ['FR'], -1, 6], 'every month on the last Friday, 6 times')]]
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 weekly rule is rendered as "every 1 weeks".

House style: "every <unit>" for interval 1, else "every <n> <unit>s"; weekday lists are in Monday-first order without duplicates and joined as "A, B and C"; the exact set MO..FR renders as "on weekdays"; an ordinal renders "on the 2nd Tuesday", -1 as "on the last Friday" and -n (n>1) as "on the 2nd to last Friday"; count renders ", once" for 1 and ", <n> times" otherwise.

split: open-access


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

N = 1
observations = []
def solve(freq, interval, byday, ordinal, count):
    unit = {'DAILY': 'day', 'WEEKLY': 'week', 'MONTHLY': 'month', 'YEARLY': 'year'}[freq]
    text = 'every ' + unit if interval == 1 else 'every %d %ss' % (interval, unit)
    names = {'MO': 'Monday', 'TU': 'Tuesday', 'WE': 'Wednesday', 'TH': 'Thursday', 'FR': 'Friday', 'SA': 'Saturday', 'SU': 'Sunday'}
    order = ['MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU']
    def nth(n):
        return str(n) + {1: 'st', 2: 'nd', 3: 'rd'}.get(n, 'th')
    if ordinal:
        word = (nth(-ordinal) + ' to last') if ordinal < 0 else nth(ordinal)
        text += ' on the ' + word + ' ' + names[byday[0]]
    elif byday:
        if set(byday) == {'MO', 'TU', 'WE', 'TH', 'FR'}:
            text += ' on weekdays'
        else:
            words = [names[d] for d in sorted(set(byday), key=order.index)]
            text += ' on ' + (words[0] if len(words) == 1 else ', '.join(words[:-1]) + ' and ' + words[-1])
    if count:
        text += ', ' + ('once' if count == 1 else '%d times' % count)
    return text
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: weekly three days',
   ['WEEKLY', 1, ['MO', 'WE', 'FR'], 0, 0],
   'every week on Monday, Wednesday and Friday'),
  ('biweekly single day once', ['WEEKLY', 2, ['TU'], 0, 1], 'every 2 weeks on Tuesday, once'),
  ('last friday monthly', ['MONTHLY', 1, ['FR'], -1, 6], 'every month on the last Friday, 6 times'),
  ('second to last sunday', ['MONTHLY', 3, ['SU'], -2, 0], 'every 3 months on the 2nd to last Sunday'),
  ('second tuesday', ['MONTHLY', 1, ['TU'], 2, 10], 'every month on the 2nd Tuesday, 10 times'),
  ('weekdays exact', ['WEEKLY', 1, ['MO', 'TU', 'WE', 'TH', 'FR'], 0, 0], 'every week on weekdays'),
  ('weekdays reordered',
   ['WEEKLY', 1, ['FR', 'MO', 'TU', 'WE', 'TH'], 0, 3],
   'every week on weekdays, 3 times')],
 [('last friday monthly', ['MONTHLY', 1, ['FR'], -1, 6], 'every month on the last Friday, 6 times'),
  ('second to last sunday', ['MONTHLY', 3, ['SU'], -2, 0], 'every 3 months on the 2nd to last Sunday'),
  ('second tuesday', ['MONTHLY', 1, ['TU'], 2, 10], 'every month on the 2nd Tuesday, 10 times'),
  ('weekdays exact', ['WEEKLY', 1, ['MO', 'TU', 'WE', 'TH', 'FR'], 0, 0], 'every week on weekdays'),
  ('weekdays reordered',
   ['WEEKLY', 1, ['FR', 'MO', 'TU', 'WE', 'TH'], 0, 3],
   'every week on weekdays, 3 times'),
  ('five days with saturday',
   ['WEEKLY', 1, ['MO', 'TU', 'WE', 'TH', 'SA'], 0, 0],
   'every week on Monday, Tuesday, Wednesday, Thursday and Saturday'),
  ('duplicate days', ['WEEKLY', 3, ['SU', 'MO', 'SU'], 0, 2], 'every 3 weeks on Monday and Sunday, 2 times')],
 [('second tuesday', ['MONTHLY', 1, ['TU'], 2, 10], 'every month on the 2nd Tuesday, 10 times'),
  ('weekdays exact', ['WEEKLY', 1, ['MO', 'TU', 'WE', 'TH', 'FR'], 0, 0], 'every week on weekdays'),
  ('weekdays reordered',
   ['WEEKLY', 1, ['FR', 'MO', 'TU', 'WE', 'TH'], 0, 3],
   'every week on weekdays, 3 times'),
  ('five days with saturday',
   ['WEEKLY', 1, ['MO', 'TU', 'WE', 'TH', 'SA'], 0, 0],
   'every week on Monday, Tuesday, Wednesday, Thursday and Saturday'),
  ('duplicate days', ['WEEKLY', 3, ['SU', 'MO', 'SU'], 0, 2], 'every 3 weeks on Monday and Sunday, 2 times'),
  ('daily with count one', ['DAILY', 1, [], 0, 1], 'every day, once'),
  ('yearly interval', ['YEARLY', 4, [], 0, 0], 'every 4 years'),
  ('last friday monthly', ['MONTHLY', 1, ['FR'], -1, 6], 'every month on the last Friday, 6 times'),
  ('second to last sunday', ['MONTHLY', 3, ['SU'], -2, 0], 'every 3 months on the 2nd to last Sunday')],
 [('weekdays reordered',
   ['WEEKLY', 1, ['FR', 'MO', 'TU', 'WE', 'TH'], 0, 3],
   'every week on weekdays, 3 times'),
  ('five days with saturday',
   ['WEEKLY', 1, ['MO', 'TU', 'WE', 'TH', 'SA'], 0, 0],
   'every week on Monday, Tuesday, Wednesday, Thursday and Saturday'),
  ('duplicate days', ['WEEKLY', 3, ['SU', 'MO', 'SU'], 0, 2], 'every 3 weeks on Monday and Sunday, 2 times'),
  ('daily with count one', ['DAILY', 1, [], 0, 1], 'every day, once'),
  ('yearly interval', ['YEARLY', 4, [], 0, 0], 'every 4 years'),
  ('two days unordered', ['WEEKLY', 1, ['TH', 'TU'], 0, 1], 'every week on Tuesday and Thursday, once'),
  ('regression: weekly three days',
   ['WEEKLY', 1, ['MO', 'WE', 'FR'], 0, 0],
   'every week on Monday, Wednesday and Friday'),
  ('last friday monthly', ['MONTHLY', 1, ['FR'], -1, 6], 'every month on the last Friday, 6 times'),
  ('second to last sunday', ['MONTHLY', 3, ['SU'], -2, 0], 'every 3 months on the 2nd to last Sunday')],
 [('duplicate days', ['WEEKLY', 3, ['SU', 'MO', 'SU'], 0, 2], 'every 3 weeks on Monday and Sunday, 2 times'),
  ('daily with count one', ['DAILY', 1, [], 0, 1], 'every day, once'),
  ('yearly interval', ['YEARLY', 4, [], 0, 0], 'every 4 years'),
  ('two days unordered', ['WEEKLY', 1, ['TH', 'TU'], 0, 1], 'every week on Tuesday and Thursday, once'),
  ('regression: weekly three days',
   ['WEEKLY', 1, ['MO', 'WE', 'FR'], 0, 0],
   'every week on Monday, Wednesday and Friday'),
  ('biweekly single day once', ['WEEKLY', 2, ['TU'], 0, 1], 'every 2 weeks on Tuesday, once'),
  ('last friday monthly', ['MONTHLY', 1, ['FR'], -1, 6], 'every month on the last Friday, 6 times'),
  ('second to last sunday', ['MONTHLY', 3, ['SU'], -2, 0], 'every 3 months on the 2nd to last Sunday')]]
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(freq, interval, byday, ordinal, count):
    unit = {'DAILY': 'day', 'WEEKLY': 'week', 'MONTHLY': 'month', 'YEARLY': 'year'}[freq]
    text = 'every ' + unit if interval == 1 else 'every %d %ss' % (interval, unit)
    names = {'MO': 'Monday', 'TU': 'Tuesday', 'WE': 'Wednesday', 'TH': 'Thursday', 'FR': 'Friday', 'SA': 'Saturday', 'SU': 'Sunday'}
    order = ['MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU']
    def nth(n):
        return str(n) + {1: 'st', 2: 'nd', 3: 'rd'}.get(n, 'th')
    if ordinal:
        word = ('last') if ordinal < 0 else nth(ordinal)
        text += ' on the ' + word + ' ' + names[byday[0]]
    elif byday:
        if set(byday) == {'MO', 'TU', 'WE', 'TH', 'FR'}:
            text += ' on weekdays'
        else:
            words = [names[d] for d in sorted(set(byday), key=order.index)]
            text += ' on ' + (words[0] if len(words) == 1 else ', '.join(words[:-1]) + ' and ' + words[-1])
    if count:
        text += ', ' + ('once' if count == 1 else '%d times' % count)
    return text
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('regression: weekly three days',
   ['WEEKLY', 1, ['MO', 'WE', 'FR'], 0, 0],
   'every week on Monday, Wednesday and Friday'),
  ('biweekly single day once', ['WEEKLY', 2, ['TU'], 0, 1], 'every 2 weeks on Tuesday, once'),
  ('last friday monthly', ['MONTHLY', 1, ['FR'], -1, 6], 'every month on the last Friday, 6 times'),
  ('second to last sunday', ['MONTHLY', 3, ['SU'], -2, 0], 'every 3 months on the 2nd to last Sunday'),
  ('second tuesday', ['MONTHLY', 1, ['TU'], 2, 10], 'every month on the 2nd Tuesday, 10 times'),
  ('weekdays exact', ['WEEKLY', 1, ['MO', 'TU', 'WE', 'TH', 'FR'], 0, 0], 'every week on weekdays'),
  ('weekdays reordered',
   ['WEEKLY', 1, ['FR', 'MO', 'TU', 'WE', 'TH'], 0, 3],
   'every week on weekdays, 3 times')],
 [('last friday monthly', ['MONTHLY', 1, ['FR'], -1, 6], 'every month on the last Friday, 6 times'),
  ('second to last sunday', ['MONTHLY', 3, ['SU'], -2, 0], 'every 3 months on the 2nd to last Sunday'),
  ('second tuesday', ['MONTHLY', 1, ['TU'], 2, 10], 'every month on the 2nd Tuesday, 10 times'),
  ('weekdays exact', ['WEEKLY', 1, ['MO', 'TU', 'WE', 'TH', 'FR'], 0, 0], 'every week on weekdays'),
  ('weekdays reordered',
   ['WEEKLY', 1, ['FR', 'MO', 'TU', 'WE', 'TH'], 0, 3],
   'every week on weekdays, 3 times'),
  ('five days with saturday',
   ['WEEKLY', 1, ['MO', 'TU', 'WE', 'TH', 'SA'], 0, 0],
   'every week on Monday, Tuesday, Wednesday, Thursday and Saturday'),
  ('duplicate days', ['WEEKLY', 3, ['SU', 'MO', 'SU'], 0, 2], 'every 3 weeks on Monday and Sunday, 2 times')],
 [('second tuesday', ['MONTHLY', 1, ['TU'], 2, 10], 'every month on the 2nd Tuesday, 10 times'),
  ('weekdays exact', ['WEEKLY', 1, ['MO', 'TU', 'WE', 'TH', 'FR'], 0, 0], 'every week on weekdays'),
  ('weekdays reordered',
   ['WEEKLY', 1, ['FR', 'MO', 'TU', 'WE', 'TH'], 0, 3],
   'every week on weekdays, 3 times'),
  ('five days with saturday',
   ['WEEKLY', 1, ['MO', 'TU', 'WE', 'TH', 'SA'], 0, 0],
   'every week on Monday, Tuesday, Wednesday, Thursday and Saturday'),
  ('duplicate days', ['WEEKLY', 3, ['SU', 'MO', 'SU'], 0, 2], 'every 3 weeks on Monday and Sunday, 2 times'),
  ('daily with count one', ['DAILY', 1, [], 0, 1], 'every day, once'),
  ('yearly interval', ['YEARLY', 4, [], 0, 0], 'every 4 years'),
  ('last friday monthly', ['MONTHLY', 1, ['FR'], -1, 6], 'every month on the last Friday, 6 times'),
  ('second to last sunday', ['MONTHLY', 3, ['SU'], -2, 0], 'every 3 months on the 2nd to last Sunday')],
 [('weekdays reordered',
   ['WEEKLY', 1, ['FR', 'MO', 'TU', 'WE', 'TH'], 0, 3],
   'every week on weekdays, 3 times'),
  ('five days with saturday',
   ['WEEKLY', 1, ['MO', 'TU', 'WE', 'TH', 'SA'], 0, 0],
   'every week on Monday, Tuesday, Wednesday, Thursday and Saturday'),
  ('duplicate days', ['WEEKLY', 3, ['SU', 'MO', 'SU'], 0, 2], 'every 3 weeks on Monday and Sunday, 2 times'),
  ('daily with count one', ['DAILY', 1, [], 0, 1], 'every day, once'),
  ('yearly interval', ['YEARLY', 4, [], 0, 0], 'every 4 years'),
  ('two days unordered', ['WEEKLY', 1, ['TH', 'TU'], 0, 1], 'every week on Tuesday and Thursday, once'),
  ('regression: weekly three days',
   ['WEEKLY', 1, ['MO', 'WE', 'FR'], 0, 0],
   'every week on Monday, Wednesday and Friday'),
  ('last friday monthly', ['MONTHLY', 1, ['FR'], -1, 6], 'every month on the last Friday, 6 times'),
  ('second to last sunday', ['MONTHLY', 3, ['SU'], -2, 0], 'every 3 months on the 2nd to last Sunday')],
 [('duplicate days', ['WEEKLY', 3, ['SU', 'MO', 'SU'], 0, 2], 'every 3 weeks on Monday and Sunday, 2 times'),
  ('daily with count one', ['DAILY', 1, [], 0, 1], 'every day, once'),
  ('yearly interval', ['YEARLY', 4, [], 0, 0], 'every 4 years'),
  ('two days unordered', ['WEEKLY', 1, ['TH', 'TU'], 0, 1], 'every week on Tuesday and Thursday, once'),
  ('regression: weekly three days',
   ['WEEKLY', 1, ['MO', 'WE', 'FR'], 0, 0],
   'every week on Monday, Wednesday and Friday'),
  ('biweekly single day once', ['WEEKLY', 2, ['TU'], 0, 1], 'every 2 weeks on Tuesday, once'),
  ('last friday monthly', ['MONTHLY', 1, ['FR'], -1, 6], 'every month on the last Friday, 6 times'),
  ('second to last sunday', ['MONTHLY', 3, ['SU'], -2, 0], 'every 3 months on the 2nd to last Sunday')]]
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:
BYDAY=-1FR is rendered as "the 1st to last Friday".

House style: "every <unit>" for interval 1, else "every <n> <unit>s"; weekday lists are in Monday-first order without duplicates and joined as "A, B and C"; the exact set MO..FR renders as "on weekdays"; an ordinal renders "on the 2nd Tuesday", -1 as "on the last Friday" and -n (n>1) as "on the 2nd to last Friday"; count renders ", once" for 1 and ", <n> times" otherwise.

split: open-access