Skip to content

iCalendar recurrence expansion with time-zone transitions, exceptions and overrides

Exact prompt

# Calendar (iCalendar subset) recurrence expansion `input.json` names `calendar.ics` and gives `timezones` (each with `initial_offset_min` and `transitions` [[UTC instant, new offset minutes], ...]; offset = local minus UTC) and a UTC window `window_start`..`window_end`. Write `solve.py` (Python 3 standard library only); `python solve.py input.json answer.json`. Fresh calendars are generated. Everything you need is below. ## Parsing 1. Lines end in CRLF (accept LF too). A line starting with a space or tab continues the previous line (drop the line break and that one character). Blank lines are ignored. 2. Content line: `NAME *(;PARAM=value) : value`. Names and parameter names are case-insensitive. Parameter values may be double-quoted (quotes removed; `;` and `:` inside quotes are literal). The value starts after the first `:` that is not inside quotes. 3. Only `VEVENT` components count (`events_parsed` = number of VEVENT blocks, overrides included). Nested components (e.g. `VALARM`) inside a VEVENT are skipped entirely, properties included. For repeated properties, the first wins, except that `EXDATE` and `RDATE` accumulate (comma lists allowed). 4. Text unescaping (SUMMARY): `\\` -> `\`, `\;` -> `;`, `\,` -> `,`, `\n` or `\N` -> newline. 5. Date-times: `YYYYMMDDTHHMMSSZ` is UTC; `YYYYMMDDTHHMMSS` with `TZID=` is local time in that zone (no TZID: treat as UTC); `VALUE=DATE` or an 8-digit value is an all-day date. 6. Local -> UTC: find each interval of the zone's offset table whose offset o makes local - o fall inside that interval. If several do (repeated hour), take the earliest UTC instant. If none do (skipped hour), use local - (offset in force before that transition). 7. Length: `DTEND` - `DTSTART` (both converted to UTC; dates for all-day), or `DURATION` (`P[nW][nD][T[nH][nM][nS]]`), else 0 for timed events and 1 day for all-day ones. ## Recurrence (RRULE: FREQ, INTERVAL, COUNT, UNTIL, BYDAY, BYMONTHDAY, BYMONTH) 8. Expand in **local wall time** (the DTSTART's zone) and keep DTSTART's time of day; convert each occurrence to UTC with rule 6. 9. DAILY: every INTERVAL days; BYMONTH, BYMONTHDAY and BYDAY filter. WEEKLY: weeks start Monday; every INTERVAL weeks from DTSTART's week; BYDAY lists the days (default: DTSTART's weekday); BYMONTH/BYMONTHDAY filter. MONTHLY: every INTERVAL months; days = BYMONTHDAY (negative counts from month end; days that don't exist are skipped) and/or BYDAY (`MO` = every Monday, `2TU` = second Tuesday, `-1FR` = last Friday). If both are given, take the intersection; if neither, use DTSTART's day of month (skip months without it). YEARLY: every INTERVAL years; months = BYMONTH (default DTSTART's month), with days chosen as in MONTHLY. 10. Candidates before DTSTART are dropped; DTSTART itself is an occurrence only if it matches the rule. Occurrences are generated in time order. COUNT counts generated occurrences **before** EXDATE removal. UNTIL is inclusive and compared in UTC (a date-only UNTIL on a timed event means 23:59:59 UTC that day; on all-day events compare dates). 11. Add RDATEs, then remove EXDATEs (matched as UTC instants or dates). 12. Overrides: a VEVENT with `RECURRENCE-ID` and the same UID replaces the occurrence whose UTC start equals it: it uses its own DTSTART, length and SUMMARY, and has `override: true`. `STATUS:CANCELLED` removes that occurrence. 13. An event without RRULE has one occurrence (plus RDATEs). ## Output Occurrences overlapping the window: timed events with start < window_end and end > window_start (zero-length: start in [window_start, window_end)); all-day events compare dates the same way. Each is `{"uid", "summary", "start", "end", "all_day", "override"}` with `YYYY-MM-DDTHH:MM:SSZ` (UTC) or `YYYY-MM-DD` (all-day). Sort by start (all-day dates count as 00:00:00Z), then uid. `answer.json`: `{"occurrences": [...], "count": n, "events_parsed": n}` ## Scoring Hidden checks (partial credit; all must pass; exact): `unfold_unescape_parse`, `weekly_tz_exdate_override`, `monthly_byday_bymonthday`, `all_day_and_yearly`, `daily_until_rdate_cancel`, `dst_gap_overlap_zero_length`, `full_sorted_list` on the given calendar; `fresh_run_1`, `fresh_run_2`. Per-family checks compare the occurrences whose summary starts with that family's text, in order. 30-second limit per run.

Wall-clock expansion across DST with skipped and repeated hours, COUNT before EXDATE, negative BYMONTHDAY and -1FR, inclusive UNTIL, and overrides keyed on UTC RECURRENCE-ID. Original benchmark task written for usecaserank.com (not based on a specific public post). Headless, offline run on a reproducible fixture. Each run's notes say how its cost was measured (estimates are marked).

Success criteria: 1. unfold_unescape_parse 2. weekly_tz_exdate_override 3. monthly_byday_bymonthday 4. all_day_and_yearly 5. daily_until_rdate_cancel 6. dst_gap_overlap_zero_length 7. full_sorted_list 8. fresh_run_1 9. fresh_run_2

Best model for this task so far: GPT-6.1 Sol (effort default (no reasoning-effort override) · thinking on) (success, $0.11, 2m).

Run this on another model

All runs (4)

75% pass rate across 4 eligible runs: 3 pass, 1 partial, 0 fail. Partial and failed runs are listed below with everything else.ⓘ

Runs for this use case
ModelCostTimeStep-insⓘAutonomyOutcomeTrustⓘDateCompare
OGPT-6.1 Soldefault · thinking on$0.112m0Fully autonomouspassTrust 80%2026-10-22
AClaude Haiku 5.5default · thinking on$0.054m0Fully autonomouspartialTrust 80%2026-10-20
AClaude Opus 5.5default · thinking on$0.422m0Fully autonomouspassTrust 80%2026-10-20
AClaude Sonnet 5.5default · thinking on$0.1648s0Fully autonomouspassTrust 80%2026-10-20

Embed this result

A live badge for this use case. It links back here and updates as new runs are published.

UseCaseRank badge for iCalendar recurrence expansion with time-zone transitions, exceptions and overrides

Get new runs and ranking changes weekly

Which models got better or cheaper on real tasks like this one.