Turn weekly ad-platform exports into an exact wasted-spend report
Exact prompt
# Weekly ads review: wasted-spend report from Google-style and Meta-style exports The files are synthetic exports for one week: `google_ads.csv`, `meta_ads.csv` and `config.json`. Write `solve.py` (Python 3 standard library only, no network). `python solve.py input.json answer.json` must write `answer.json` (the first argument is unused; read the three files from the current directory). Fresh exports are generated when scoring. ## Parsing rules 1. `google_ads.csv`: skip lines before the header line that starts with `Day,`. Rows whose `Day` is not a date like `Oct 12, 2026` (e.g. `Total: ...` rows) are non-data rows. `Cost` and `Conv. value` may contain thousands commas or be `--` (= 0). Spend currency is the row's `Currency code` (USD or EUR). 2. `meta_ads.csv`: may start with a UTF-8 BOM. The spend column is named `Amount spent (USD)` or `Amount spent (EUR)`; that currency applies to every row. Use `Reporting starts` as the row date. Empty numeric cells = 0. 3. Meta `Results` count as conversions **only** when `Result indicator` is `actions:offsite_conversion.fb_pixel_purchase`; otherwise the row has 0 conversions (its results are clicks, not conversions). `Purchases conversion value` is the conversion value. 4. Convert EUR to USD by multiplying each row's amount by `eur_to_usd`. Keep full precision while summing; round only final reported money values to 2 decimals, half-up. 5. Drop rows dated outside `week_start`..`week_end` (inclusive). Drop exact duplicate lines within a file (keep the first). Count drops in `rows_dropped`: `{"duplicates", "out_of_range", "non_data"}` (a duplicate is counted as a duplicate even if also out of range; check duplicates first, then non-data, then range). 6. A unit is (platform `google`|`meta`, campaign, ad group/ad set). Names are matched after trimming, collapsing internal whitespace and ignoring case; report the first-seen form in file order (trimmed and whitespace-collapsed). ## Metrics and waste rules (per unit, over the week) 7. `spend` (USD), `clicks` (int), `conversions`, `conv_value` (USD; Google values follow the row currency, Meta values the file currency). 8. `cpa` = spend / conversions rounded to 2 dp, `null` when conversions = 0. `roas` = conv_value / spend rounded to 4 dp, `null` when spend = 0. 9. `reason` = `"zero_conversions"` when conversions = 0 and spend >= `zero_conv_min_spend_usd`, then `wasted` = spend. `reason` = `"high_cpa"` when conversions > 0 and cpa (unrounded) > `cpa_multiple` x `target_cpa_usd`, then `wasted` = spend - conversions x `target_cpa_usd`. Otherwise `reason` = null, `wasted` = 0. 10. `units` order: wasted descending, then spend descending, then platform, campaign, ad group ascending (case-insensitive). ## answer.json `{"units": [{"platform", "campaign", "ad_group", "spend", "clicks", "conversions", "conv_value", "cpa", "roas", "reason", "wasted"}], "totals": {"spend", "wasted", "wasted_pct", "by_platform": {"google": {"spend", "wasted"}, "meta": {"spend", "wasted"}}}, "top5": [[platform, campaign, ad_group] for the first 5 units with wasted > 0], "rows_dropped": {...}}`. `wasted_pct` = 100 x wasted / spend, 1 dp. Totals are sums of the rounded unit values. ## Optional visual: chart.svg If you write `chart.svg`: a static, self-contained SVG (root `<svg>`, no scripts, images, links, external URLs or `on*` handlers) with an element `id="wasted-bars"` and one element `id="bar-1"` .. `id="bar-N"` for the top-5 units in order. It is not required; if present it must follow these rules. ## Scoring Hidden checks (partial credit; all must pass; money within 0.005): `parse_dedupe_and_drops`, `unit_keys_and_spend_usd`, `conversions_value_and_result_indicator`, `waste_rules`, `totals_ranking_top5`, `chart_svg_if_present` on the given exports; `fresh_run_1`, `fresh_run_2` (whole answer on new exports). 30-second limit per run.
Every messy-export trap moves real dollars between units, so a quick pandas-style sum gets the shape right and most numbers wrong. 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. parse_dedupe_and_drops 2. unit_keys_and_spend_usd 3. conversions_value_and_result_indicator 4. waste_rules 5. totals_ranking_top5 6. chart_svg_if_present 7. fresh_run_1 8. fresh_run_2
Best model for this task so far: Gemma 4 31B Instruct (Venice) (thinking on) (success, $0.01, 15m).
Latest output per model
All runs (5)
100% pass rate across 5 eligible runs: 5 pass, 0 partial, 0 fail. Partial and failed runs are listed below with everything else.ⓘ
| Model | Cost | Time | Step-insⓘ | Autonomy | Outcome | Trustⓘ | Date | Compare |
|---|---|---|---|---|---|---|---|---|
| GGemma 4 31B Instruct (Venice)thinking on | $0.01 | 15m | 0 | Fully autonomous | pass | Trust 80% | 2026-10-25 | |
| OGPT-6.1 Soldefault · thinking on | $0.05 | 55s | 0 | Fully autonomous | pass | Trust 80% | 2026-10-22 | |
| AClaude Haiku 5.5default · thinking on | $0.02 | 2m | 0 | Fully autonomous | pass | Trust 80% | 2026-10-20 | |
| AClaude Opus 5.5default · thinking on | $0.32 | 58s | 0 | Fully autonomous | pass | Trust 80% | 2026-10-20 | |
| AClaude Sonnet 5.5default · thinking on | $0.08 | 23s | 0 | Fully autonomous | pass | Trust 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.
Get new runs and ranking changes weekly
Which models got better or cheaper on real tasks like this one.