Submission 3D9VU9

import csv, json, io

def transform(text):
    reader = csv.reader(io.StringIO(text.strip()))
    result = []
    for row in reader:
        result.append({'name': row[0], 'age': int(row[1]), 'role': row[2]})
    return json.dumps(result)

John Doe,32,Engineer
Jane Smith,28,Designer
Bob Lee,45,Manager

Parse CSV rows of name,age,role (no header) into a JSON array of objects with keys name, age (as int), role.


Submission QF0L8V

import json

def transform(text):
    totals = {}
    for line in text.strip().split('\n'):
        date, product, qty = line.split(',')
        totals[product] = totals.get(product, 0) + int(qty)
    return json.dumps({k: totals[k] for k in sorted(totals)})

Parse lines of date,product,quantity and sum quantities per product across all dates, returning a JSON object sorted by product name.


Submission V861ZR

def transform(text):
    lines = text.split('\n')
    cleaned = []
    for line in lines:
        cleaned.append(' '.join(line.split()))
    return '\n'.join(cleaned)

Normalize whitespace: collapse multiple spaces into one, strip leading/trailing whitespace on each line, and join lines with a single newline.


Submission D4N13V

import json

def transform(text):
    result = {}
    for pair in text.strip().split(','):
        k, v = pair.split(':')
        result[k] = int(v)
    result['_total'] = sum(result.values())
    return json.dumps(result)

Parse a comma-separated key:value inventory string into a JSON object mapping each key to its integer value, and add a computed '_total' key summing all values.


Submission DCPYHN

import csv, io, json

def transform(text):
    reader = csv.DictReader(io.StringIO(text.strip()))
    result = {}
    for row in reader:
        score = int(row['score'])
        if score >= 90:
            grade = 'A'
        elif score >= 80:
            grade = 'B'
        else:
            grade = 'C'
        result[row['id']] = grade
    return json.dumps(result)

Given a CSV of id,score, return a JSON object mapping each id to a letter grade: A for score>=90, B for 80-89, C for below 80.


Submission GV0AUC

import json
import re

def transform(text):
    line = text.strip()
    pattern = r'(\w+)=("[^"]*"|\S+)'
    pairs = re.findall(pattern, line)
    result = {}
    for key, value in pairs:
        if value.startswith('"') and value.endswith('"'):
            value = value[1:-1]
        elif re.fullmatch(r'-?\d+', value):
            value = int(value)
        elif re.fullmatch(r'-?\d+\.\d+', value):
            value = float(value)
        result[key] = value
    return json.dumps(result)

level=INFO msg="user created successfully" user_id=42 ip=10.0.0.5 latency_ms=12.5 retries=0

Parse a logfmt-style key=value log line into a JSON object. Quoted values (e.g. msg="...") may contain spaces and must have their surrounding quotes stripped. Values that look numeric should be converted to int or float, but a value that merely resembles a number — like an IP address — must remain a string.


Submission LYHV3Q

import csv
import io
from collections import defaultdict

def transform(text):
    totals = defaultdict(float)
    counts = defaultdict(int)
    for line in text.strip().split('\n'):
        line = line.strip()
        if not line:
            continue
        category, amount = line.rsplit(' ', 1)
        totals[category] += float(amount)
        counts[category] += 1
    out = io.StringIO()
    writer = csv.writer(out)
    writer.writerow(['category', 'total', 'count'])
    for category in sorted(totals):
        writer.writerow([category, f'{totals[category]:.2f}', counts[category]])
    return out.getvalue().strip()

groceries 45.50
transport 12.00
dry goods 30.25
dining 60.00
transport 8.75
dry goods 15.00

category,total,count
dining,60.00,1
dry goods,45.25,2
groceries,45.50,1
transport,20.75,2

Each line is '<category> <amount>', one transaction per line; category names may themselves contain spaces (e.g. 'dry goods'). Aggregate the total amount and transaction count per category, and output as CSV with header 'category,total,count', rows sorted alphabetically by category, amounts formatted to exactly 2 decimal places.


Submission TFPOOT

import csv, io, json

def transform(text):
    reader = csv.DictReader(io.StringIO(text.strip()))
    records = []
    for row in reader:
        rec = {}
        for k, v in row.items():
            v = v.strip()
            if v.lower() in ('true', 'false'):
                rec[k] = v.lower() == 'true'
            else:
                try:
                    rec[k] = int(v)
                except ValueError:
                    try:
                        rec[k] = float(v)
                    except ValueError:
                        rec[k] = v
        records.append(rec)
    return json.dumps(records)

sku,quantity,price,in_stock
A100,12,4.99,true
B200,0,19.5,false
C300,7,3,true

Parse a CSV string with a header row into a JSON array of records, coercing each cell to int, float, or bool where possible (leaving other values as strings).


Submission RFQV03

import json

def transform(text):
    data = json.loads(text)

    def flatten(obj, prefix=''):
        items = {}
        if isinstance(obj, dict):
            for k, v in obj.items():
                new_key = f"{prefix}.{k}" if prefix else k
                items.update(flatten(v, new_key))
        elif isinstance(obj, list):
            for i, v in enumerate(obj):
                new_key = f"{prefix}[{i}]"
                items.update(flatten(v, new_key))
        else:
            items[prefix] = obj
        return items

    return json.dumps(flatten(data), sort_keys=True)

Flatten an arbitrarily nested JSON object (including lists) into a single-level JSON object whose keys use dot notation for nested dicts and bracket notation like key[0] for list indices, with keys sorted alphabetically.


Submission LQVGG8

import json
from collections import defaultdict

def transform(text):
    rows = json.loads(text)
    agg = defaultdict(lambda: {"total_revenue": 0.0, "order_count": 0})
    for r in rows:
        key = r["region"]
        agg[key]["total_revenue"] += r["amount"]
        agg[key]["order_count"] += 1
    result = []
    for region, vals in sorted(agg.items()):
        result.append({
            "region": region,
            "total_revenue": round(vals["total_revenue"], 2),
            "order_count": vals["order_count"],
            "avg_order_value": round(vals["total_revenue"] / vals["order_count"], 2)
        })
    return json.dumps(result)

Group a JSON array of order records by 'region' and compute total_revenue, order_count, and avg_order_value per region, returning a JSON array sorted by region name.


Submission 8JFF3Y

import json, re

def transform(text):
    lines = [l.strip() for l in text.strip().split('\n') if l.strip()]
    out = []
    for line in lines:
        digits = re.sub(r'\D', '', line)
        if len(digits) == 11 and digits.startswith('1'):
            digits = digits[1:]
        if len(digits) != 10:
            out.append({"raw": line, "normalized": None, "valid": False})
            continue
        normalized = f"+1-{digits[0:3]}-{digits[3:6]}-{digits[6:10]}"
        out.append({"raw": line, "normalized": normalized, "valid": True})
    return json.dumps(out)

Normalize a list of messy US phone number strings (varied punctuation) into E.164-like '+1-XXX-XXX-XXXX' format, flagging entries that cannot be parsed into exactly 10 digits as invalid.


Submission 9Z0WW9

import json
from collections import OrderedDict

def transform(text):
    rows = json.loads(text)
    pivot = OrderedDict()
    months = []
    for r in rows:
        product = r["product"]
        month = r["month"]
        if month not in months:
            months.append(month)
        pivot.setdefault(product, {})[month] = r["units_sold"]
    months.sort()
    result = []
    for product, vals in pivot.items():
        row = {"product": product}
        for m in months:
            row[m] = vals.get(m, 0)
        result.append(row)
    return json.dumps(result)

Pivot a JSON array of {product, month, units_sold} records into a wide table with one row per product and one column per month (sorted chronologically), filling missing month/product combinations with 0.


Submission 8NGXY6

import json
from datetime import datetime

def transform(text):
    rows = json.loads(text)
    latest = {}
    for r in rows:
        key = (r["customer_id"], r["product_sku"])
        ts = datetime.fromisoformat(r["updated_at"].replace("Z", "+00:00"))
        if key not in latest or ts > latest[key][0]:
            latest[key] = (ts, r)
    result = [r for _, r in sorted(latest.values(), key=lambda x: (x[1]["customer_id"], x[1]["product_sku"]))]
    return json.dumps(result)

Deduplicate a JSON array of order-status update records using the composite key (customer_id, product_sku), keeping only the record with the most recent 'updated_at' timestamp for each key, and return the results sorted by customer_id then product_sku.


Submission CBGV67

import json

def transform(text):
    rows = json.loads(text)
    out = []
    for r in rows:
        migrated = {
            "id": r["user_id"],
            "profile": {
                "first_name": r["first_name"],
                "last_name": r["last_name"],
                "email": r["email_address"]
            },
            "contact": {
                "phone": r.get("phone_number"),
            },
            "meta": {
                "created": r["signup_date"]
            }
        }
        out.append(migrated)
    return json.dumps(out)

Migrate a flat legacy user-record JSON schema into a nested schema grouping fields under 'profile', 'contact', and 'meta' objects, renaming id and email fields appropriately.


Submission NPF07H

import json, csv, io

def transform(text):
    lines = [l for l in text.strip().split('\n') if l.strip()]
    records = [json.loads(l) for l in lines]
    fieldnames = []
    for r in records:
        for k in r.keys():
            if k not in fieldnames:
                fieldnames.append(k)
    out = io.StringIO()
    writer = csv.DictWriter(out, fieldnames=fieldnames)
    writer.writeheader()
    for r in records:
        writer.writerow(r)
    return out.getvalue().strip()

id,name,score
1,Alpha,88
2,Beta,92
3,Gamma,79

Convert newline-delimited JSON (JSON Lines) records into a CSV string with a header row derived from the union of all keys in first-seen order.


Submission C3UXGW

import json
from datetime import datetime

def transform(text):
    lines = [l.strip() for l in text.strip().split('\n') if l.strip()]
    formats = ["%m/%d/%Y", "%d-%m-%Y", "%Y.%m.%d", "%B %d, %Y"]
    out = []
    for line in lines:
        parsed = None
        for fmt in formats:
            try:
                parsed = datetime.strptime(line, fmt)
                break
            except ValueError:
                continue
        out.append(parsed.strftime("%Y-%m-%d") if parsed else None)
    return json.dumps(out)

Parse a list of dates written in several different inconsistent formats (MM/DD/YYYY, DD-MM-YYYY, YYYY.MM.DD, and 'Month DD, YYYY') and normalize each to ISO 8601 'YYYY-MM-DD', returning null for any that fail to parse.


Submission NENHO8

import json, re
from collections import Counter

def transform(text):
    lines = [l for l in text.strip().split('\n') if l.strip()]
    counts = Counter()
    for line in lines:
        m = re.search(r'"\w+ \S+ HTTP/\d\.\d"\s+(\d{3})', line)
        if m:
            counts[m.group(1)] += 1
    return json.dumps(dict(sorted(counts.items())))

Parse Apache-style access log lines and count occurrences of each HTTP status code, returning a JSON object mapping status code strings to counts sorted by code.


Submission M8QDAW

import json

def transform(text):
    data = json.loads(text)
    out = []
    for order in data:
        for item in order["items"]:
            out.append({
                "order_id": order["order_id"],
                "customer": order["customer"],
                "sku": item["sku"],
                "qty": item["qty"],
                "line_total": round(item["qty"] * item["unit_price"], 2)
            })
    return json.dumps(out)

Explode a JSON array of orders, each containing a nested list of line items, into a flat JSON array of one row per line item including order_id, customer, sku, qty, and a computed line_total (qty * unit_price, rounded to 2 decimals).


Submission WIS9VK

import csv, io, json

def transform(text):
    reader = csv.reader(io.StringIO(text.strip()))
    header = [h.strip().lower().replace(' ', '_') for h in next(reader)]
    out = []
    for row in reader:
        if not any(c.strip() for c in row):
            continue
        rec = {}
        for k, v in zip(header, row):
            v = v.strip().strip('"').strip()
            if v == '' or v.upper() == 'N/A':
                rec[k] = None
            else:
                try:
                    rec[k] = int(v)
                except ValueError:
                    try:
                        rec[k] = float(v)
                    except ValueError:
                        rec[k] = v
        out.append(rec)
    return json.dumps(out)

 Full Name , Age , City
" Zara Khan " , 29 , " Lahore "
Omar Farooq, N/A ,Karachi
,,

Clean a messy CSV string with inconsistent whitespace, quoted fields, and 'N/A' placeholders: normalize header names to lowercase snake_case, trim and unquote values, convert 'N/A' and empty strings to null, coerce numeric strings to int/float, and drop fully blank rows.


Submission V48JD1

import json
from collections import defaultdict

def transform(text):
    rows = json.loads(text)
    weighted = defaultdict(lambda: [0.0, 0.0])
    for r in rows:
        weighted[r["course"]][0] += r["grade"] * r["credits"]
        weighted[r["course"]][1] += r["credits"]
    result = {course: round(total / weight, 2) for course, (total, weight) in weighted.items()}
    return json.dumps(result, sort_keys=True)

Compute the credit-weighted average grade per course from a JSON array of {course, grade, credits} records, returning a JSON object mapping course name to the rounded weighted average.


Submission 5NM3XK

import re, json

def transform(text):
    tags = re.findall(r'<(\w+)([^>]*)>([^<]*)</\1>', text)
    result = {}
    for name, attrs_str, value in tags:
        attrs = dict(re.findall(r'(\w+)="([^"]*)"', attrs_str))
        entry = {"value": value.strip()}
        if attrs:
            entry["attributes"] = attrs
        result[name] = entry
    return json.dumps(result, sort_keys=True)

Parse a simple single-line XML-like config string into a JSON object, extracting each top-level child tag's text value and any XML attributes it has, keyed by tag name.


Submission EN9JP6

import csv, io, json

def transform(text):
    reader = csv.DictReader(io.StringIO(text.strip()))
    id_field = reader.fieldnames[0]
    year_fields = reader.fieldnames[1:]
    out = []
    for row in reader:
        for year in year_fields:
            val = row[year].strip()
            if val == '':
                continue
            out.append({
                id_field: row[id_field],
                "year": year,
                "value": float(val) if '.' in val else int(val)
            })
    return json.dumps(out)

Reshape a wide CSV with an id column followed by multiple year columns into a long/tidy JSON array of {id_field, year, value} records, skipping any cells that are blank for a given year.


Submission Q2RM2R

import json
from datetime import datetime

def transform(text):
    rows = json.loads(text)
    rows = sorted(rows, key=lambda r: (r["user"], r["ts"]))
    sessions = []
    current = None
    GAP_MINUTES = 30
    for r in rows:
        ts = datetime.fromisoformat(r["ts"])
        if current is None or current["user"] != r["user"] or (ts - current["last_ts"]).total_seconds() > GAP_MINUTES * 60:
            if current:
                sessions.append({"user": current["user"], "start": current["start"], "end": current["last_ts"].isoformat(), "event_count": current["count"]})
            current = {"user": r["user"], "start": r["ts"], "last_ts": ts, "count": 1}
        else:
            current["last_ts"] = ts
            current["count"] += 1
    if current:
        sessions.append({"user": current["user"], "start": current["start"], "end": current["last_ts"].isoformat(), "event_count": current["count"]})
    return json.dumps(sessions)

Sessionize a JSON array of per-user timestamped events into sessions, starting a new session whenever the gap between consecutive events for the same user exceeds 30 minutes, and return each session's user, start time, end time, and event count.


Submission M4THII

import json
from collections import defaultdict

def transform(text):
    rows = json.loads(text)
    by_category = defaultdict(list)
    for r in rows:
        by_category[r["category"]].append(r)
    result = []
    for category in sorted(by_category):
        top = sorted(by_category[category], key=lambda r: -r["sales"])[:2]
        result.append({"category": category, "top_products": [{"product": p["product"], "sales": p["sales"]} for p in top]})
    return json.dumps(result)

Group a JSON array of {category, product, sales} records by category and return, for each category (sorted alphabetically), the top 2 products by sales in descending order.


Submission EC68Y9

import json, re

def transform(text):
    lines = [l.strip() for l in text.strip().split('\n') if l.strip()]
    out = []
    for line in lines:
        m = re.match(r'^([\w\s\-]+):\s*([\d.]+)\s*(kg|lb|g)$', line.strip())
        if not m:
            out.append({"raw": line, "kg": None})
            continue
        name, amount, unit = m.group(1).strip(), float(m.group(2)), m.group(3)
        if unit == 'kg':
            kg = amount
        elif unit == 'lb':
            kg = amount * 0.453592
        else:
            kg = amount / 1000
        out.append({"item": name, "kg": round(kg, 3)})
    return json.dumps(out)

Flour: 2 kg
Sugar: 4.4 lb
Salt: 500 g
Badline

Normalize a list of 'item: amount unit' strings with mixed weight units (kg, lb, g) into a JSON array converting every amount to kilograms (rounded to 3 decimals), marking unparseable lines with a null kg value.


Submission FTP46O

import json
from collections import defaultdict

def transform(text):
    pairs = json.loads(text)
    children = defaultdict(list)
    all_nodes = set()
    child_nodes = set()
    for p in pairs:
        children[p["parent"]].append(p["child"])
        all_nodes.add(p["parent"])
        all_nodes.add(p["child"])
        child_nodes.add(p["child"])
    roots = sorted(all_nodes - child_nodes)

    depth = {}
    def assign_depth(node, d):
        depth[node] = d
        for c in sorted(children.get(node, [])):
            assign_depth(c, d + 1)

    for r in roots:
        assign_depth(r, 0)

    result = [{"node": n, "depth": depth[n]} for n in sorted(depth)]
    return json.dumps(result)

Build a tree from a JSON array of {parent, child} pairs and compute the depth of every node from its root (nodes that never appear as a child are roots at depth 0), returning a JSON array of {node, depth} sorted by node name.


Submission QF1AHP

import json
from collections import defaultdict

def transform(text):
    rows = json.loads(text)
    rows = sorted(rows, key=lambda r: (r["account"], r["date"]))
    running = defaultdict(float)
    out = []
    for r in rows:
        running[r["account"]] += r["amount"]
        out.append({
            "account": r["account"],
            "date": r["date"],
            "amount": r["amount"],
            "running_total": round(running[r["account"]], 2)
        })
    return json.dumps(out)

Compute a running cumulative total of 'amount' per account over time from a JSON array of dated transactions (sorted by account then date), returning each transaction annotated with its running_total rounded to 2 decimals.


Submission DAK850

import json

def transform(text):
    data = json.loads(text)
    headers = data["headers"]
    rows = data["rows"]
    # transpose: each original column becomes a row, prefixed by its header
    transposed = []
    for col_idx, header in enumerate(headers):
        row = [header] + [r[col_idx] for r in rows]
        transposed.append(row)
    return json.dumps({"headers": ["field"] + [f"row{i+1}" for i in range(len(rows))], "rows": transposed})

Transpose a table given as JSON with 'headers' and 'rows' (list of row arrays) so each original column becomes a row. Output JSON with new 'headers' (['field', 'row1', 'row2', ...]) and 'rows' where each row starts with the original column header followed by that column's values in order.


Submission MQYMCG

import json
from datetime import datetime, timedelta

def transform(text):
    records = json.loads(text)
    # bucket timestamps into hourly buckets, average the value in each bucket
    buckets = {}
    for r in records:
        ts = datetime.fromisoformat(r["ts"].replace("Z", "+00:00"))
        bucket_key = ts.strftime("%Y-%m-%dT%H:00:00Z")
        buckets.setdefault(bucket_key, []).append(r["value"])

    if not buckets:
        return json.dumps([])

    sorted_keys = sorted(buckets.keys())
    start = datetime.fromisoformat(sorted_keys[0].replace("Z", "+00:00"))
    end = datetime.fromisoformat(sorted_keys[-1].replace("Z", "+00:00"))

    result = []
    last_avg = None
    cur = start
    while cur <= end:
        key = cur.strftime("%Y-%m-%dT%H:00:00Z")
        if key in buckets:
            vals = buckets[key]
            avg = round(sum(vals) / len(vals), 2)
            last_avg = avg
            filled = False
        else:
            avg = last_avg
            filled = True
        result.append({"hour": key, "avg_value": avg, "filled": filled})
        cur += timedelta(hours=1)
    return json.dumps(result)

Given a JSON list of {"ts": ISO8601 timestamp, "value": number} records, resample into hourly buckets from the earliest to the latest hour present, averaging values within each hour (rounded to 2 decimals). For hours with no records, forward-fill the last known average and mark 'filled': true; hours with real data get 'filled': false. Return a JSON list of {"hour", "avg_value", "filled"} in chronological order.


Submission BI5ROF

import json

def transform(text):
    tree = json.loads(text)

    def rollup(node):
        if "children" not in node or not node["children"]:
            node["total"] = node.get("value", 0)
            return node["total"]
        total = node.get("value", 0)
        for child in node["children"]:
            total += rollup(child)
        node["total"] = total
        return total

    rollup(tree)
    return json.dumps(tree)

Given a JSON tree where each node has 'name', 'value', and optional 'children' (list of nodes), compute a 'total' field on every node equal to its own 'value' plus the recursive sum of all descendant 'value' fields (a hierarchical rollup). Return the tree as JSON with the added 'total' fields, preserving all original fields and structure.


Submission QL61QO

import json, re

def transform(text):
    payload = json.loads(text)
    template = payload["template"]
    data = payload["data"]

    pattern = re.compile(r"\{\{\s*([\w.]+)\s*(?:\|\s*([^}]*?)\s*)?\}\}")

    def resolve(path):
        cur = data
        for part in path.split("."):
            if isinstance(cur, dict) and part in cur and cur[part] not in (None, ""):
                cur = cur[part]
            else:
                return None
        return cur

    def repl(m):
        path = m.group(1)
        default = m.group(2)
        val = resolve(path)
        if val is None:
            return default if default is not None else ""
        return str(val)

    return pattern.sub(repl, template)

Hello {{name|Guest}}, your order #{{order.id}} ships to {{order.city|Unknown City}}. Balance: {{account.balance|0}}

Hello Priya, your order #A1029 ships to Unknown City. Balance: 0

Given a JSON object with a 'template' string containing placeholders of the form {{field.path}} or {{field.path|default}}, and a 'data' object, render the template by substituting each placeholder with the value found by following the dotted path in data. If the path resolves to a missing key or an empty string, use the placeholder's default text instead (or empty string if no default given). Return the rendered plain-text string.


Submission FBWEIS

import json

def transform(text):
    data = json.loads(text)
    values = [d["value"] for d in data]
    sorted_vals = sorted(values)
    n = len(sorted_vals)

    def percentile(p):
        idx = p * (n - 1)
        lo = int(idx)
        hi = min(lo + 1, n - 1)
        frac = idx - lo
        return sorted_vals[lo] + (sorted_vals[hi] - sorted_vals[lo]) * frac

    q1 = percentile(0.25)
    q3 = percentile(0.75)
    iqr = q3 - q1
    lower = q1 - 1.5 * iqr
    upper = q3 + 1.5 * iqr

    kept, removed = [], []
    for d in data:
        if lower <= d["value"] <= upper:
            kept.append(d)
        else:
            removed.append(d)

    return json.dumps({
        "q1": round(q1, 2), "q3": round(q3, 2), "iqr": round(iqr, 2),
        "lower_bound": round(lower, 2), "upper_bound": round(upper, 2),
        "kept": kept, "removed": removed
    })

Given a JSON list of {"id", "value"} records, detect outliers using the IQR method (linear-interpolation quartiles): compute Q1, Q3, IQR = Q3-Q1, and bounds [Q1-1.5*IQR, Q3+1.5*IQR]. Return a JSON object with 'q1', 'q3', 'iqr', 'lower_bound', 'upper_bound' (each rounded to 2 decimals), 'kept' (records within bounds, original order preserved), and 'removed' (records outside bounds, original order preserved).


Submission MZDZE2

import json

def transform(text):
    data = json.loads(text)
    triples = data["entries"]
    n_rows = data["rows"]
    n_cols = data["cols"]
    dense = [[0 for _ in range(n_cols)] for _ in range(n_rows)]
    for e in triples:
        dense[e["row"]][e["col"]] = e["value"]
    return json.dumps(dense)

Given a JSON object with 'rows', 'cols' (dense matrix dimensions) and 'entries' (a sparse list of {"row", "col", "value"} triples), build the dense matrix as a 2D JSON array of size rows x cols, filling unspecified cells with 0 and placing each entry's value at its [row][col] position.


Submission 6U3PUS

import json, csv, io

def transform(text):
    data = json.loads(text)
    out = io.StringIO()
    writer = csv.writer(out)
    writer.writerow(["source", "target", "weight"])
    for node, edges in data.items():
        for edge in edges:
            if isinstance(edge, dict):
                writer.writerow([node, edge["to"], edge["weight"]])
            else:
                writer.writerow([node, edge, 1])
    return out.getvalue().strip()

Given a JSON adjacency-list graph where each key is a node name mapped to a list of edges (each edge either an object {"to", "weight"} or a plain node-name string implying weight 1), convert it into a CSV edge list with header 'source,target,weight', one row per edge in the order nodes and their edges appear in the input.


Submission T7QN1W

import json

def transform(text):
    data = json.loads(text)
    rates = data["rates"]  # to USD
    txns = data["transactions"]
    out = []
    grand_total = 0.0
    for t in txns:
        currency = t["currency"]
        amount = t["amount"]
        if currency not in rates:
            out.append({**t, "usd_amount": None, "error": f"unknown currency {currency}"})
            continue
        usd = round(amount * rates[currency], 2)
        grand_total += usd
        out.append({**t, "usd_amount": usd})
    return json.dumps({"transactions": out, "grand_total_usd": round(grand_total, 2)})

Given a JSON object with 'rates' (currency code -> USD conversion rate) and 'transactions' (list of {"id", "amount", "currency"}), convert each transaction's amount to USD (rounded to 2 decimals) using the rate table. If a transaction's currency isn't in the rate table, set its usd_amount to null and add an 'error' field describing the unknown currency, and exclude it from the grand total. Return JSON with 'transactions' (each augmented with usd_amount and optional error) and 'grand_total_usd' (sum of all valid usd_amount values, rounded to 2 decimals).


Submission NR5314

import json, re
from collections import Counter

def transform(text):
    stopwords = {"the", "a", "an", "and", "or", "of", "to", "in", "is", "it", "on"}
    words = re.findall(r"[a-zA-Z']+", text.lower())
    filtered = [w for w in words if w not in stopwords]
    counts = Counter(filtered)
    top = sorted(counts.items(), key=lambda kv: (-kv[1], kv[0]))
    return json.dumps({"total_tokens": len(filtered), "unique_tokens": len(counts), "frequencies": top})

The quick brown fox jumps over the lazy dog. The dog barks, and the fox runs to the woods in the night.

Given a raw text passage, tokenize it into lowercase alphabetic word tokens (stripping punctuation), remove a fixed stopword list (the, a, an, and, or, of, to, in, is, it, on), and build a frequency table. Return JSON with 'total_tokens' (count after stopword removal), 'unique_tokens' (distinct word count), and 'frequencies' (list of [word, count] pairs sorted by count descending then alphabetically ascending).


Submission KWFFG0

import json

def transform(text):
    payload = json.loads(text)
    schema = payload["schema"]  # field -> type ("int","float","bool","str")
    records = payload["records"]

    def coerce(value, typ):
        if value is None:
            return None, False
        try:
            if typ == "int":
                return int(str(value).strip()), True
            if typ == "float":
                return float(str(value).strip()), True
            if typ == "bool":
                s = str(value).strip().lower()
                if s in ("true", "1", "yes"):
                    return True, True
                if s in ("false", "0", "no"):
                    return False, True
                return value, False
            if typ == "str":
                return str(value), True
        except (ValueError, TypeError):
            return value, False
        return value, False

    out = []
    for rec in records:
        coerced = {}
        errors = []
        for field, typ in schema.items():
            if field not in rec:
                errors.append(f"missing:{field}")
                continue
            val, ok = coerce(rec[field], typ)
            coerced[field] = val
            if not ok:
                errors.append(f"invalid:{field}")
        out.append({"record": coerced, "valid": len(errors) == 0, "errors": errors})
    return json.dumps(out)

Given a JSON object with a 'schema' (field name -> one of "int","float","bool","str") and 'records' (list of objects with possibly wrong-typed string values), coerce each field's value to the declared type. Bool coercion accepts case-insensitive true/1/yes as true and false/0/no as false. If a field is missing from a record, or coercion fails, or a bool value isn't recognized, record an error string ("missing:<field>" or "invalid:<field>") instead of failing. Return a JSON list of {"record": coerced fields present, "valid": true if no errors, "errors": list of error strings} in input order.


Submission P2KWWJ

import json

def transform(text):
    intervals = json.loads(text)
    intervals = sorted(intervals, key=lambda iv: iv["start"])
    merged = []
    for iv in intervals:
        if merged and iv["start"] <= merged[-1]["end"]:
            merged[-1]["end"] = max(merged[-1]["end"], iv["end"])
            merged[-1]["merged_from"].append(iv.get("label", ""))
        else:
            merged.append({"start": iv["start"], "end": iv["end"], "merged_from": [iv.get("label", "")]})
    return json.dumps(merged)

Given a JSON list of intervals {"start", "end", "label"}, merge all overlapping or touching intervals (sorted by start) into a minimal set of non-overlapping intervals. Each merged interval must include 'start', 'end' (the union bounds) and 'merged_from' (list of the original labels combined into it, in the order they were merged). Return the merged intervals as a JSON list sorted by start.


Submission ER6UO2

import json, csv, io

def transform(text):
    reader = csv.DictReader(io.StringIO(text.strip()))
    rows = list(reader)
    categorical_col = "color"
    categories = sorted({r[categorical_col] for r in rows})
    other_cols = [c for c in reader.fieldnames if c != categorical_col]

    out_fields = other_cols + [f"{categorical_col}_{c}" for c in categories]
    out = io.StringIO()
    writer = csv.DictWriter(out, fieldnames=out_fields)
    writer.writeheader()
    for r in rows:
        row_out = {c: r[c] for c in other_cols}
        for c in categories:
            row_out[f"{categorical_col}_{c}"] = 1 if r[categorical_col] == c else 0
        writer.writerow(row_out)
    return out.getvalue().strip()

id,color,price
1,red,10
2,blue,20
3,green,15
4,red,12

Given a CSV string with columns including a categorical 'color' column, one-hot encode the 'color' column into separate binary columns named 'color_<value>' (one per distinct category found, sorted alphabetically), placed after the other original columns in their original order (with 'color' itself removed). Return the resulting CSV string with header row.


Submission CUAC4L

import json

def transform(text):
    values = json.loads(text)
    window = 3
    result = []
    for i in range(len(values)):
        lo = max(0, i - window + 1)
        window_vals = values[lo:i+1]
        avg = round(sum(window_vals) / len(window_vals), 3)
        result.append(avg)
    return json.dumps(result)

Given a JSON list of numeric values, compute a trailing simple moving average with a window size of 3. For each position i, average the current value together with up to the previous 2 values (using a smaller partial window near the start of the list rather than padding). Return a JSON list of the moving averages (rounded to 3 decimals), same length as the input.


Submission KNWY92

import json, re

def transform(text):
    records = json.loads(text)

    def mask_email(email):
        m = re.match(r"^(.)([^@]*)(@.*)$", email)
        if not m:
            return email
        first, rest, domain = m.groups()
        return f"{first}{'*' * len(rest)}{domain}"

    def mask_phone(phone):
        digits = re.sub(r"\D", "", phone)
        if len(digits) < 4:
            return "*" * len(digits)
        masked = "*" * (len(digits) - 4) + digits[-4:]
        return masked

    out = []
    for r in records:
        out.append({
            "name": r["name"],
            "email": mask_email(r["email"]),
            "phone": mask_phone(r["phone"])
        })
    return json.dumps(out)

Given a JSON list of {"name", "email", "phone"} records, mask each email by keeping only the first character of the local part visible and replacing the rest of the local part with asterisks (domain unchanged), and mask each phone number by stripping non-digit characters and replacing all but the last 4 digits with asterisks. Return a JSON list of {"name", "email", "phone"} with the masked values.


Submission S96MGR

import json

def transform(text):
    data = json.loads(text)
    out = []
    max_depth = [0]

    def flatten(item, depth):
        max_depth[0] = max(max_depth[0], depth)
        if isinstance(item, list):
            for x in item:
                flatten(x, depth + 1)
        else:
            out.append({"value": item, "depth": depth})

    flatten(data, 0)
    return json.dumps({"items": out, "max_depth": max_depth[0]})

Given a JSON value that is an arbitrarily nested list of numbers (lists inside lists inside lists), flatten it into a single sequence of {"value", "depth"} objects where 'depth' is the nesting level at which that number was found (top-level numbers directly in the outermost list have depth 1). Return JSON with 'items' (the flattened list in original left-to-right order) and 'max_depth' (the deepest nesting level reached, counting only the levels that contain at least one further nested list).


Submission AZXNUV

import json

def transform(text):
    seq = text.strip()
    if not seq:
        return json.dumps([])
    result = []
    count = 1
    prev = seq[0]
    for ch in seq[1:]:
        if ch == prev:
            count += 1
        else:
            result.append([prev, count])
            prev = ch
            count = 1
    result.append([prev, count])
    return json.dumps(result)

Given a raw string of characters, perform run-length encoding: return a JSON list of [character, count] pairs representing consecutive runs of identical characters in the order they appear in the string.


Submission 0ORXXG

import json

def transform(text):
    matrix = json.loads(text)
    rows = len(matrix)
    cols = len(matrix[0]) if rows else 0
    result = []
    for diag in range(rows + cols - 1):
        diag_elems = []
        r_start = max(0, diag - cols + 1)
        r_end = min(rows - 1, diag)
        for r in range(r_start, r_end + 1):
            c = diag - r
            diag_elems.append(matrix[r][c])
        if diag % 2 == 0:
            diag_elems.reverse()
        result.extend(diag_elems)
    return json.dumps(result)

Given a JSON 2D matrix (list of equal-length row lists), produce its zigzag diagonal traversal order (as used for JPEG-style scans): traverse anti-diagonals in order, alternating the direction of each diagonal (even-indexed diagonals from bottom-left to top-right reversed to top-right-to-bottom-left order relative to standard, matching the classic zigzag pattern) so consecutive diagonals alternate direction. Return the traversal as a flat JSON list of the matrix values in visiting order.


Submission 06K303

import json

def transform(text):
    payload = json.loads(text)
    scores = payload["scores"]
    bin_width = payload["bin_width"]
    lo = payload.get("min", min(scores))
    hi = payload.get("max", max(scores))

    n_bins = int((hi - lo) // bin_width) + 1
    bins = [{"range_start": lo + i * bin_width, "range_end": lo + (i + 1) * bin_width, "count": 0} for i in range(n_bins)]

    for s in scores:
        idx = int((s - lo) // bin_width)
        if idx >= n_bins:
            idx = n_bins - 1
        if idx < 0:
            idx = 0
        bins[idx]["count"] += 1

    return json.dumps(bins)

Given a JSON object with 'scores' (list of numbers), 'bin_width', and optional 'min'/'max' bounds (defaulting to the data's own min/max), bucket the scores into fixed-width bins starting at 'min' and covering at least up to 'max'. Values beyond the highest bin's range are clamped into the last bin. Return a JSON list of bins in ascending order, each {"range_start", "range_end", "count"}.


Submission 1KBLZK

import json
from datetime import date

def transform(text):
    data = json.loads(text)
    users = data["users"]

    cohorts = {}
    for u in users:
        signup = u["signup_date"]
        cohorts.setdefault(signup, {"users": [], "count": 0})
        cohorts[signup]["users"].append(u)
        cohorts[signup]["count"] += 1

    def week_offset(signup_str, activity_str):
        sy, sm, sd = map(int, signup_str.split("-"))
        ay, am, ad = map(int, activity_str.split("-"))
        delta = (date(ay, am, ad) - date(sy, sm, sd)).days
        return delta // 7

    result = []
    for signup, group in sorted(cohorts.items()):
        total = group["count"]
        week_counts = {}
        for u in group["users"]:
            weeks_active = {week_offset(signup, a) for a in u["active_dates"]}
            for w in weeks_active:
                week_counts[w] = week_counts.get(w, 0) + 1
        max_week = max(week_counts.keys(), default=0)
        retention = []
        for w in range(max_week + 1):
            active = week_counts.get(w, 0)
            retention.append({"week": w, "active_users": active, "retention_pct": round(active / total * 100, 1)})
        result.append({"cohort": signup, "cohort_size": total, "retention": retention})

    return json.dumps(result)

Given a JSON object with 'users' (each having 'signup_date' YYYY-MM-DD and 'active_dates' a list of YYYY-MM-DD activity dates), group users into cohorts by signup_date, and for each cohort compute weekly retention: for week offset w (0, 1, 2, ...), the count and percentage of that cohort's users who had at least one activity date falling in that week-since-signup bucket (integer division of days-since-signup by 7). Return a JSON list of cohorts sorted by signup_date, each {"cohort", "cohort_size", "retention": [{"week", "active_users", "retention_pct"}, ...]} covering week 0 through the maximum observed week offset.


Submission APRMGB

import json

def transform(text):
    result = {}
    current_section = None
    for raw_line in text.strip().split("\n"):
        line = raw_line.strip()
        if not line or line.startswith(";") or line.startswith("#"):
            continue
        if line.startswith("[") and line.endswith("]"):
            current_section = line[1:-1].strip()
            result.setdefault(current_section, {})
            continue
        if "=" in line and current_section is not None:
            key, _, value = line.partition("=")
            key = key.strip()
            value = value.strip()
            if value.lower() in ("true", "false"):
                parsed_value = value.lower() == "true"
            else:
                try:
                    parsed_value = int(value)
                except ValueError:
                    try:
                        parsed_value = float(value)
                    except ValueError:
                        parsed_value = value
            result[current_section][key] = parsed_value
    return json.dumps(result)

; global config
[server]
host = localhost
port = 8080
debug = true

[database]
name = mydb
timeout = 30.5
ssl = false

Given a plain-text INI-style config string with [section] headers, key = value lines, and comment lines starting with ';' or '#', parse it into a nested JSON object mapping each section name to an object of its key/value pairs. Coerce values: 'true'/'false' (case-insensitive) become booleans, values parseable as integers become ints, values parseable as floats become floats, otherwise the value stays a string.


Submission KJYEBW

def transform(text):
    tokens = []
    buf = []
    in_quotes = False
    in_comment = False

    def flush():
        if buf:
            tokens.append(''.join(buf))
            del buf[:]

    for ch in text:
        if in_comment:
            if ch == '\n':
                in_comment = False
            continue
        if in_quotes:
            buf.append(ch)
            if ch == '"':
                in_quotes = False
            continue
        if ch == '#':
            in_comment = True
            continue
        if ch == '"':
            buf.append(ch)
            in_quotes = True
            continue
        if ch in '{};':
            flush()
            tokens.append(ch)
            continue
        if ch.isspace():
            flush()
            continue
        buf.append(ch)
    flush()

    stack = []
    pending = []
    lines = []
    for tok in tokens:
        if tok == ';':
            if pending:
                name = pending[0]
                args = pending[1:]
                path = '/'.join(stack + [name])
                arg_text = ' '.join(args) if args else '(none)'
                lines.append('%s = %s' % (path, arg_text))
            pending = []
        elif tok == '{':
            if len(pending) == 1:
                label = pending[0]
            elif pending:
                label = pending[0] + '[' + ' '.join(pending[1:]) + ']'
            else:
                label = '(anon)'
            stack.append(label)
            pending = []
        elif tok == '}':
            pending = []
            if stack:
                stack.pop()
        else:
            pending.append(tok)
    return '\n'.join(lines)

worker_processes  auto;

events {
    worker_connections 1024;
}

http {
    sendfile on;   # push files fast
    gzip on;
    server {
        listen 443 ssl;
        server_name shop.example.com;
        location /api/ {
            proxy_pass http://backend;
            proxy_set_header Host $host;
        }
        location = /healthz { return 200 "ok"; }
    }
    server {
        listen 80;
        server_name shop.example.com;
        return 301 https://$host$request_uri;
    }
}

worker_processes = auto
events/worker_connections = 1024
http/sendfile = on
http/gzip = on
http/server/listen = 443 ssl
http/server/server_name = shop.example.com
http/server/location[/api/]/proxy_pass = http://backend
http/server/location[/api/]/proxy_set_header = Host $host
http/server/location[= /healthz]/return = 200 "ok"
http/server/listen = 80
http/server/server_name = shop.example.com
http/server/return = 301 https://$host$request_uri

Flatten an nginx-style configuration file into one line per simple directive.

Lexing rules:
1. A '#' starts a comment that runs to end of line, EXCEPT when the '#' is inside a double-quoted string.
   Comments are removed before anything else.
2. The three structural characters are '{', '}' and ';'. Outside double quotes they terminate the token
   being accumulated. Inside double quotes they are ordinary characters. Newlines behave as whitespace.
3. Whitespace runs separate tokens. A directive is the token sequence accumulated up to a ';' (a simple
   directive) or up to a '{' (a block header, which pushes a context).
4. A block header's context label is its first token when the header has exactly one token, otherwise the
   first token followed by '[' + the remaining tokens joined by a single space + ']'. So 'http' labels as
   'http', 'location /api/' as 'location[/api/]' and 'location = /healthz' as 'location[= /healthz]'.
   A '}' pops the innermost context.

Output: one line per SIMPLE directive (block headers themselves are not emitted), in file order, formatted
    '<path> = <args>'
where <path> is the '/'-joined chain of enclosing context labels followed by the directive name (a
top-level directive has no prefix, so its path is just its name), and <args> is the remaining tokens
joined by a single space, or the literal '(none)' when the directive has no arguments. Multiple internal
spaces in the source collapse to one. Quoted arguments keep their surrounding double quotes verbatim.

A directive that appears more than once is emitted once per occurrence, in order; no deduplication.
Join lines with '\n'; no trailing newline and no trailing whitespace on any line.


Submission ZAKAMX

import re

HEADER = re.compile(r'^([a-z]+)(?:\(([^()]*)\))?(!)?: +(.*)$')
TYPE_SECTION = {
    'feat': 'Features',
    'fix': 'Bug Fixes',
    'perf': 'Performance',
    'refactor': 'Refactoring',
    'docs': 'Documentation',
}
ORDER = ['BREAKING CHANGES', 'Features', 'Bug Fixes', 'Performance',
         'Refactoring', 'Documentation', 'Other']

def transform(text):
    sections = {name: [] for name in ORDER}
    for raw in text.split('\n'):
        line = raw.strip()
        if not line:
            continue
        parts = line.split(' ', 1)
        if len(parts) != 2:
            continue
        sha, subject = parts[0], parts[1].strip()
        if subject.startswith('Merge '):
            continue
        short = sha[:7]
        match = HEADER.match(subject)
        if not match:
            sections['Other'].append(('', subject, short))
            continue
        ctype, scope, bang, desc = match.groups()
        scope = scope or ''
        desc = desc.strip()
        entry = (scope, desc, short)
        if bang:
            sections['BREAKING CHANGES'].append(entry)
        target = TYPE_SECTION.get(ctype)
        if target:
            sections[target].append(entry)

    blocks = []
    for name in ORDER:
        entries = sections[name]
        if not entries:
            continue
        block = ['## ' + name]
        for scope, desc, short in entries:
            if scope:
                block.append('- **%s**: %s (%s)' % (scope, desc, short))
            else:
                block.append('- %s (%s)' % (desc, short))
        blocks.append('\n'.join(block))
    return '\n\n'.join(blocks)

9f2a1c4 feat(auth): add device-code login flow
1b7de90 fix(api): return 422 instead of 500 on bad cursor
c04ea11 chore: bump ruff to 0.6.2
77bb213 feat(api)!: drop the deprecated /v1/search endpoint
aa10f5e docs(readme): clarify install steps
3ce9b02 fix: guard against empty upload manifests
5d8c447 refactor(core): extract retry policy helper
e11a0b6 Merge pull request #482 from acme/release-2
6620fd1 feat(billing): support annual invoicing
0af3311 fix(api): stop double-counting retried jobs
bd5c778 wip poking at the scheduler

## BREAKING CHANGES
- **api**: drop the deprecated /v1/search endpoint (77bb213)

## Features
- **auth**: add device-code login flow (9f2a1c4)
- **api**: drop the deprecated /v1/search endpoint (77bb213)
- **billing**: support annual invoicing (6620fd1)

## Bug Fixes
- **api**: return 422 instead of 500 on bad cursor (1b7de90)
- guard against empty upload manifests (3ce9b02)
- **api**: stop double-counting retried jobs (0af3311)

## Refactoring
- **core**: extract retry policy helper (5d8c447)

## Documentation
- **readme**: clarify install steps (aa10f5e)

## Other
- wip poking at the scheduler (bd5c778)

Turn `git log --oneline` output into grouped release notes.

Each input line is '<sha> <subject>'. Split on the first space; the sha is the first field.

Classify each subject against the Conventional Commits header grammar
    type[(scope)][!]: description
where type is one or more lowercase ASCII letters, scope (optional) is the text inside parentheses, the
optional '!' marks a breaking change, and ': ' (colon plus at least one space) separates the header from
the description. A subject that does not match this grammar is NOT conventional.

Handling:
- A subject starting with 'Merge ' is dropped entirely, whether or not it parses.
- Non-conventional, non-merge subjects go into a section titled 'Other'.
- Recognised types map to sections: feat -> 'Features', fix -> 'Bug Fixes', perf -> 'Performance',
  refactor -> 'Refactoring', docs -> 'Documentation'. Any other conventional type (chore, test, build, ...)
  is dropped entirely.
- A commit with '!' before the colon additionally appears in a 'BREAKING CHANGES' section, and it also
  still appears in its normal type section.

Section order is fixed: 'BREAKING CHANGES', 'Features', 'Bug Fixes', 'Performance', 'Refactoring',
'Documentation', 'Other'. A section with no entries is omitted entirely.

Each section renders as a header line '## <Section>' followed by one bullet per commit, in the original
file order, formatted '- **<scope>**: <description> (<sha7>)' when a scope is present, or
'- <description> (<sha7>)' when it is not. <sha7> is the first 7 characters of the sha. For 'Other'
entries the whole subject is used as the description and there is never a scope. Descriptions are stripped
of surrounding whitespace. Sections are separated by exactly one blank line.

Join with '\n'; no trailing newline and no trailing whitespace on any line.


Submission O2GJMR

def transform(text):
    groups = []
    current_agents = None
    current_rules = None
    expecting_agents = False

    for raw in text.split('\n'):
        line = raw.split('#', 1)[0].strip()
        if not line or ':' not in line:
            continue
        field, value = line.split(':', 1)
        field = field.strip().lower()
        value = value.strip()
        if field == 'user-agent':
            if not expecting_agents:
                current_agents = []
                current_rules = []
                groups.append((current_agents, current_rules))
                expecting_agents = True
            current_agents.append(value.lower())
        elif field in ('allow', 'disallow', 'crawl-delay'):
            if current_rules is None:
                continue
            expecting_agents = False
            current_rules.append((field, value))

    agent_order = []
    per_agent = {}
    for agents, rules in groups:
        for agent in agents:
            if agent not in per_agent:
                per_agent[agent] = []
                agent_order.append(agent)
            per_agent[agent].extend(rules)

    lines = []
    for agent in sorted(per_agent):
        allow = []
        disallow = []
        delay = None
        for field, value in per_agent[agent]:
            if field == 'crawl-delay':
                if value:
                    delay = value
            elif not value:
                continue
            elif field == 'allow':
                if value not in allow:
                    allow.append(value)
            else:
                if value not in disallow:
                    disallow.append(value)
        allow_text = ','.join(sorted(allow)) if allow else 'none'
        disallow_text = ','.join(sorted(disallow)) if disallow else 'none'
        delay_text = '-' if delay is None else '%.1f' % float(delay)
        lines.append('%s | allow=%s | disallow=%s | delay=%s' % (
            agent, allow_text, disallow_text, delay_text))
    return '\n'.join(lines)

# Acme storefront robots policy
User-agent: *
Disallow: /cart
Disallow: /checkout/
Allow: /checkout/help
Crawl-delay: 10

User-agent: GoogleBot
user-agent: bingbot
Disallow:
Allow: /

User-agent: BadBot
Disallow: /
Crawl-delay: 3.5

Sitemap: https://example.com/sitemap.xml

* | allow=/checkout/help | disallow=/cart,/checkout/ | delay=10.0
badbot | allow=none | disallow=/ | delay=3.5
bingbot | allow=/ | disallow=none | delay=-
googlebot | allow=/ | disallow=none | delay=-

Parse a robots.txt file into a per-user-agent report.

Rules:
1. Strip everything from the first '#' on each line, then strip surrounding whitespace. Drop empty lines.
2. Each remaining line is 'field: value' split on the first ':'. Field names are matched case-insensitively
   and lowercased. Values keep their original case but are stripped of surrounding whitespace.
3. A group is one or more consecutive 'user-agent' lines followed by its rule lines. A 'user-agent' line
   that directly follows another 'user-agent' line joins the same group; a 'user-agent' line that follows
   a rule line starts a new group. Blank lines do not end a group.
4. Agent tokens are compared and reported lowercased. If the same agent token appears in more than one
   group, merge the rules of those groups in file order.
5. Relevant rule fields are 'allow', 'disallow' and 'crawl-delay'. Any other field (for example 'sitemap')
   is ignored and never starts or belongs to a group.
6. A 'disallow' with an empty value means 'nothing is disallowed' and is discarded rather than recorded.
   An 'allow' with an empty value is discarded the same way.
7. Within one agent, duplicate paths within the same field are removed keeping the first occurrence;
   the surviving paths are then reported sorted ascending by ordinary Python string comparison.
8. crawl-delay is reported as the LAST value seen for that agent, printed with exactly one decimal place;
   if the agent has no crawl-delay, print '-'.

Output: one line per agent, ordered by agent token ascending (ordinary Python string comparison), formatted
    '<agent> | allow=<paths> | disallow=<paths> | delay=<value>'
where <paths> is the sorted paths joined by ',' or the literal 'none' when the list is empty.
Join lines with '\n'; no trailing newline, no trailing whitespace on any line.


Submission 80FT83

import re

TOKEN = re.compile(r'^([A-G])(#*|b*)(-?\d+)$')
BASE = {'C': 0, 'D': 2, 'E': 4, 'F': 5, 'G': 7, 'A': 9, 'B': 11}

def transform(text):
    out = []
    valid = invalid = out_of_range = 0
    for raw in text.split('\n'):
        tokens = raw.split()
        if not tokens:
            continue
        parts = []
        for token in tokens:
            match = TOKEN.match(token)
            if not match:
                invalid += 1
                parts.append('%s=?' % token)
                continue
            letter, accidentals, octave = match.groups()
            offset = accidentals.count('#') - accidentals.count('b')
            number = (int(octave) + 1) * 12 + BASE[letter] + offset
            if number < 0 or number > 127:
                out_of_range += 1
                parts.append('%s=!' % token)
            else:
                valid += 1
                parts.append('%s=%d' % (token, number))
        out.append(' '.join(parts))
    out.append('valid=%d invalid=%d out_of_range=%d' % (valid, invalid, out_of_range))
    return '\n'.join(out)

Each non-empty input line holds whitespace-separated scientific-pitch note tokens. Convert each token to a
MIDI note number.

Token grammar: a letter A-G (uppercase only), then zero or more accidentals which must be all '#' or all
'b' (mixing them is invalid), then an octave which is an optional '-' followed by one or more digits.
Anything that does not match this exact grammar end-to-end is INVALID.

Value: base semitones C=0, D=2, E=4, F=5, G=7, A=9, B=11. Each '#' adds 1, each 'b' subtracts 1.
MIDI number = (octave + 1) * 12 + base + accidental offset. Note that this makes Fb4 = E4 and E#4 = F4,
and double accidentals are legal.

Range: a computed number outside 0..127 inclusive is OUT_OF_RANGE, even though the token parsed fine.

Output one line per input line, in order, containing the results for that line's tokens joined by ' '.
Each result is formatted '<token>=<value>' where <value> is the MIDI number, or '<token>=?' for an
invalid token, or '<token>=!' for an out-of-range one. A line whose tokens are all whitespace produces no
output line at all.

After the per-line block, append one summary line:
    'valid=<v> invalid=<i> out_of_range=<o>'
counting tokens across the whole input. Join everything with '\n'; no trailing newline and no trailing
whitespace on any line.


Submission PNZDLI

import re

TIMING = re.compile(
    r'^(\d+):(\d{2}):(\d{2}),(\d{3})\s*-->\s*(\d+):(\d{2}):(\d{2}),(\d{3})$')
SHIFT_MS = 1500

def _fmt(ms):
    hours, rest = divmod(ms, 3600000)
    minutes, rest = divmod(rest, 60000)
    seconds, millis = divmod(rest, 1000)
    return '%02d:%02d:%02d,%03d' % (hours, minutes, seconds, millis)

def transform(text):
    lines = [line.rstrip() for line in text.replace('\r\n', '\n').split('\n')]
    blocks = []
    current = []
    for line in lines:
        if line == '':
            if current:
                blocks.append(current)
                current = []
        else:
            current.append(line)
    if current:
        blocks.append(current)

    cues = []
    for block in blocks:
        if len(block) < 2:
            continue
        match = TIMING.match(block[1].strip())
        if not match:
            continue
        index = int(block[0].strip())
        g = [int(x) for x in match.groups()]
        start = g[0] * 3600000 + g[1] * 60000 + g[2] * 1000 + g[3]
        end = g[4] * 3600000 + g[5] * 60000 + g[6] * 1000 + g[7]
        start = max(0, start - SHIFT_MS)
        end = max(0, end - SHIFT_MS)
        if start == 0 and end == 0:
            continue
        body = [t for t in (line.rstrip() for line in block[2:]) if t]
        cues.append((start, end, index, body))

    cues.sort(key=lambda c: (c[0], c[1], c[2]))

    out_blocks = []
    for number, (start, end, _index, body) in enumerate(cues, start=1):
        chunk = [str(number), '%s --> %s' % (_fmt(start), _fmt(end))]
        chunk.extend(body)
        out_blocks.append('\n'.join(chunk))
    return '\n\n'.join(out_blocks)

Shift every cue in an SRT subtitle file 1500 milliseconds EARLIER and re-emit valid SRT.

Input blocks are separated by one or more blank lines. Each block is: an index line, a timing line
'HH:MM:SS,mmm --> HH:MM:SS,mmm', then one or more text lines.

Rules:
1. Convert both timestamps to milliseconds and subtract 1500.
2. Clamp negatives to 0. If BOTH the shifted start and the shifted end clamp to 0 the cue is dropped
   entirely (it would have zero duration at the very start of the file).
3. Cues are re-sorted by shifted start time ascending, then by shifted end time ascending, then by the
   cue's original index ascending.
4. Surviving cues are renumbered from 1 in the new order.
5. Timestamps are re-rendered zero-padded as 'HH:MM:SS,mmm' with HH at least two digits.
6. Cue text lines are kept verbatim and in order, with trailing whitespace stripped from each line;
   text lines that become empty after stripping are removed.

Output: blocks joined by exactly one blank line, each block being the number line, the timing line, then
the text lines. No trailing newline and no trailing whitespace on any line.


Submission OI2ED4

import re
from decimal import Decimal, ROUND_HALF_EVEN

NUMBER = re.compile(r'-?\d+(?:\.\d+)?')
QUANT = Decimal('0.000001')

def _fmt(value):
    return str(value.quantize(QUANT, rounding=ROUND_HALF_EVEN))

def transform(text):
    lines = [line for line in text.split('\n') if line.strip()]
    rows = []
    for line in lines[1:]:
        if ';' not in line:
            continue
        parcel_id, wkt = line.split(';', 1)
        parcel_id = parcel_id.strip()
        numbers = [Decimal(tok) for tok in NUMBER.findall(wkt)]
        pairs = [(numbers[i], numbers[i + 1])
                 for i in range(0, len(numbers) - 1, 2)]
        if not pairs:
            rows.append('%s|EMPTY|EMPTY|EMPTY|EMPTY|%s'
                        % (parcel_id, _fmt(Decimal('0'))))
            continue
        xs = [p[0] for p in pairs]
        ys = [p[1] for p in pairs]
        minx, maxx = min(xs), max(xs)
        miny, maxy = min(ys), max(ys)
        area = (maxx - minx) * (maxy - miny)
        rows.append('%s|%s|%s|%s|%s|%s' % (
            parcel_id, _fmt(minx), _fmt(miny), _fmt(maxx), _fmt(maxy), _fmt(area)))
    return '\n'.join(rows)

The input is a semicolon-delimited file with a header row 'parcel_id;geometry'. Each data row holds a WKT
geometry. Emit a bounding-box table.

Rules:
1. Skip the header row and any blank line.
2. Split each data row on the FIRST ';' only; the remainder is the WKT string.
3. Extract every coordinate pair from the WKT by ignoring the geometry keyword and all parentheses and
   commas: read the numeric tokens in order and take them in pairs as (x, y). Numbers may be negative and
   may have a decimal part. Interior rings of a POLYGON and every part of a MULTIPOLYGON contribute their
   coordinates too (an interior ring is always inside the exterior ring, so this cannot change the box,
   but the parser must not choke on it).
4. A geometry whose WKT contains no numeric token at all (for example 'POLYGON EMPTY') is EMPTY: emit the
   row with the literal 'EMPTY' in place of all four bounds and '0.000000' as the area.
5. Otherwise the bounding box is minx, miny, maxx, maxy over all extracted coordinates. A single-point
   geometry yields a degenerate box where min equals max.
6. Area is (maxx - minx) * (maxy - miny).

Formatting: all five numbers are rendered with exactly 6 decimal places using round-half-even on the
Decimal value (Python's default Decimal quantize rounding), computed from the exact decimal text so no
binary floating-point drift appears. Output one line per row, in input order:
    '<parcel_id>|<minx>|<miny>|<maxx>|<maxy>|<area>'
Join with '\n'; no trailing newline, no trailing whitespace on any line.


Submission 9MC7BD

import re

TOKEN = re.compile(r'([A-Z][a-z]{0,2})(\d*)|([\(\[])|([\)\]])(\d*)')

def _parse_segment(segment):
    coefficient = 1
    i = 0
    while i < len(segment) and segment[i].isdigit():
        i += 1
    if i:
        coefficient = int(segment[:i])
        segment = segment[i:]
    stack = [{}]
    pos = 0
    while pos < len(segment):
        match = TOKEN.match(segment, pos)
        if not match or match.end() == pos:
            pos += 1
            continue
        pos = match.end()
        symbol, mult, opening, closing, close_mult = match.groups()
        if symbol:
            count = int(mult) if mult else 1
            top = stack[-1]
            top[symbol] = top.get(symbol, 0) + count
        elif opening:
            stack.append({})
        elif closing:
            group = stack.pop()
            factor = int(close_mult) if close_mult else 1
            top = stack[-1]
            for element, count in group.items():
                top[element] = top.get(element, 0) + count * factor
    while len(stack) > 1:
        group = stack.pop()
        top = stack[-1]
        for element, count in group.items():
            top[element] = top.get(element, 0) + count
    return {el: n * coefficient for el, n in stack[0].items()}

def _hill_order(tally):
    keys = sorted(tally)
    if 'C' in tally:
        ordered = ['C']
        if 'H' in tally:
            ordered.append('H')
        ordered.extend(k for k in keys if k not in ('C', 'H'))
        return ordered
    return keys

def transform(text):
    lines = []
    for raw in text.split('\n'):
        formula = raw.strip()
        if not formula:
            continue
        tally = {}
        for segment in formula.split('.'):
            for element, count in _parse_segment(segment).items():
                tally[element] = tally.get(element, 0) + count
        parts = ['%s%d' % (el, tally[el]) for el in _hill_order(tally)]
        total = sum(tally.values())
        lines.append('%s -> %s = %d atoms' % (formula, ', '.join(parts), total))
    return '\n'.join(lines)

H2O
Ca(OH)2
K4[Fe(CN)6]
CuSO4.5H2O
Mg(NO3)2
C6H5COOH
Al2(SO4)3

Each non-empty input line is a chemical formula. Produce the element tally for each.

Grammar:
- An element symbol is one uppercase ASCII letter optionally followed by one or two lowercase letters.
- A symbol or a closing bracket may be followed by a multiplier: one or more digits. Absent means 1.
- '(' ... ')' and '[' ... ']' are interchangeable grouping brackets and may nest to any depth. A group's
  multiplier multiplies every count inside it.
- A '.' introduces a hydrate/adduct segment which may itself be preceded by a leading integer coefficient
  that multiplies EVERY element in that segment (for example 'CuSO4.5H2O' has a segment '5H2O' meaning
  5 water molecules). A segment with no leading coefficient uses 1. The part before the first '.' is the
  first segment and never has a leading coefficient.

Counts from all segments are summed into a single tally per formula.

Output: one line per input formula, in input order, formatted
    '<formula> -> <El><count>, <El><count>, ... = <total> atoms'
Elements are listed in Hill order: carbon first if present, then hydrogen if present (hydrogen only
immediately after carbon when carbon is present), then all remaining element symbols sorted ascending by
ordinary Python string comparison. When carbon is NOT present, every element including hydrogen is simply
sorted ascending. The count is always printed even when it is 1. <total> is the sum of all counts.
Join with '\n'; no trailing newline, no trailing whitespace on any line.


Submission IUPOV0

from decimal import Decimal

TYPE_RANK = {'CREDIT': 0, 'DEBIT': 1, 'FEE': 2}

CENTS = Decimal('0.01')

def _money(value):
    return str(value.quantize(CENTS)).rjust(10)

def transform(text):
    lines = [line.strip() for line in text.split('\n') if line.strip()]
    header = lines[0].split(',')
    balance = Decimal(header[2])
    opening = balance

    rows = []
    for index, line in enumerate(lines[1:]):
        parts = line.split(',')
        if len(parts) != 4:
            continue
        date, kind, desc, amount = parts
        rows.append((date, TYPE_RANK.get(kind, 99), index, desc, Decimal(amount)))

    rows.sort(key=lambda r: (r[0], r[1], r[2]))

    out = ['OPENING ' + _money(opening)]
    for date, _rank, _index, desc, amount in rows:
        balance = balance + amount
        line = '%s %s %s %s' % (date, desc[:22].ljust(22), _money(amount), _money(balance))
        if balance < 0:
            line += ' <OVERDRAWN'
        out.append(line)
    out.append('CLOSING ' + _money(balance))
    return '\n'.join(out)

The first line is 'OPENING,<date>,<amount>' giving the opening balance. Every following non-empty line is
'<date>,<type>,<description>,<amount>' with an ISO date, a type of CREDIT, DEBIT or FEE, a description
that never contains a comma, and a signed decimal amount with exactly two decimal places.

Produce a running-balance statement:
1. Sort transactions by date ascending; within the same date, CREDIT entries come before DEBIT entries and
   DEBIT before FEE; within the same date and type, keep the original input order (stable).
2. Compute the running balance with decimal arithmetic (no binary floats): start at the opening balance
   and add each amount in the sorted order.
3. Every monetary value is printed with exactly two decimal places, using '-' for negatives, and right
   aligned in a field of width 10.
4. Descriptions are truncated to at most 22 characters (no ellipsis) and left aligned in a field of
   width 22.
5. If the running balance is negative AFTER applying a transaction, append the marker ' <OVERDRAWN' to
   that line; otherwise append nothing (so the line must not end in spaces).

Layout: a first line 'OPENING' + one space + the opening balance in the 10-wide field, then one line per
transaction formatted as '<date> <desc22> <amount10> <balance10>' with single spaces between fields, then
a final line 'CLOSING' + one space + the closing balance in the 10-wide field.
Join with '\n'; no trailing newline and no trailing whitespace on any line except where the fixed-width
fields require internal padding.


Submission V21KAM

import csv
import io
from decimal import Decimal, ROUND_HALF_UP

TENTH = Decimal('0.1')

def transform(text):
    reader = csv.reader(io.StringIO(text))
    rows = [row for row in reader if row and any(cell.strip() for cell in row)]
    body = rows[1:]

    ranked = []
    excluded = []
    for row in body:
        name = row[0].strip()
        raw_score = row[1].strip() if len(row) > 1 else ''
        try:
            score = int(raw_score)
        except ValueError:
            excluded.append(name)
            continue
        ranked.append((name, score))

    total = len(ranked)
    scores = [s for _n, s in ranked]
    distinct = sorted(set(scores), reverse=True)
    rank_of = {}
    position = 1
    for value in distinct:
        rank_of[value] = position
        position += scores.count(value)

    lower_count = {}
    for value in distinct:
        lower_count[value] = sum(1 for s in scores if s < value)

    entries = []
    for name, score in ranked:
        if total:
            pct = (Decimal(lower_count[score]) / Decimal(total) * Decimal(100))
        else:
            pct = Decimal(0)
        pct = pct.quantize(TENTH, rounding=ROUND_HALF_UP)
        if pct >= Decimal(90):
            band = 'top'
        elif pct >= Decimal(75):
            band = 'high'
        elif pct >= Decimal(40):
            band = 'mid'
        else:
            band = 'low'
        entries.append((rank_of[score], name, score, pct, band))

    entries.sort(key=lambda e: (e[0], e[1]))

    lines = []
    for rank, name, score, pct, band in entries:
        lines.append('%d\t%s\t%d\t%s\t%s' % (rank, name, score, str(pct), band))
    lines.append('excluded: ' + (','.join(excluded) if excluded else 'none'))
    lines.append('ranked=%d distinct_scores=%d' % (total, len(distinct)))
    return '\n'.join(lines)

student,score
kim,88
ana,72
raj,95
lee,72
mo,61
tam,88
bo,40
wei,99
ivy,72
sam,55
eve,
gus,83

1	wei	99	90.9	top
2	raj	95	81.8	high
3	kim	88	63.6	mid
3	tam	88	63.6	mid
5	gus	83	54.5	mid
6	ana	72	27.3	low
6	ivy	72	27.3	low
6	lee	72	27.3	low
9	mo	61	18.2	low
10	sam	55	9.1	low
11	bo	40	0.0	low
excluded: eve
ranked=11 distinct_scores=8

The input is CSV with header 'student,score'. Rank the students and assign percentile bands.

Rules:
1. Rows whose score cell is empty or not an integer are EXCLUDED from ranking and from all statistics;
   they are reported separately at the end.
2. Ranking uses competition ranking ('1224'): sort scores descending; equal scores share the smallest
   rank in their tie group, and the next distinct score's rank jumps past the whole group.
3. The percentile of a student is defined as the fraction of ranked students with a score STRICTLY LOWER
   than theirs, times 100. Compute it as a Decimal and round to one decimal place with ROUND_HALF_UP.
   Tied students therefore share an identical percentile.
4. Bands from the percentile p: p >= 90 -> 'top', 75 <= p < 90 -> 'high', 40 <= p < 75 -> 'mid',
   p < 40 -> 'low'. Comparisons use the ROUNDED percentile.
5. Ranked output order: rank ascending, then student name ascending (ordinary Python string comparison)
   inside a tie group.

Output lines:
  - one line per ranked student: '<rank>\t<student>\t<score>\t<percentile>\t<band>' with the percentile
    printed with exactly one decimal place; fields are separated by single TAB characters.
  - then a line 'excluded: <names>' where <names> are the excluded students in input order joined by ',';
    print 'excluded: none' when there are none.
  - then a line 'ranked=<n> distinct_scores=<d>'.
Join with '\n'; no trailing newline and no trailing whitespace on any line.


Submission XRZDRL

def transform(text):
    nodes = set()
    edges = set()
    for raw in text.split('\n'):
        line = raw.strip()
        if not line or line.startswith('#'):
            continue
        if '->' in line:
            left, right = line.split('->', 1)
            source, target = left.strip(), right.strip()
            nodes.add(source)
            nodes.add(target)
            edges.add((source, target))
        elif '--' in line:
            left, right = line.split('--', 1)
            source, target = left.strip(), right.strip()
            nodes.add(source)
            nodes.add(target)
            edges.add((source, target))
            edges.add((target, source))
        else:
            nodes.add(line)

    out_map = {node: set() for node in nodes}
    in_count = {node: 0 for node in nodes}
    for source, target in edges:
        out_map[source].add(target)
        in_count[target] += 1

    lines = []
    sinks = 0
    for node in sorted(nodes):
        targets = sorted(out_map[node])
        if not targets:
            sinks += 1
        target_text = ','.join(targets) if targets else '-'
        lines.append('%s out:%d in:%d -> %s'
                     % (node, len(targets), in_count[node], target_text))
    selfloops = sum(1 for source, target in edges if source == target)
    lines.append('nodes=%d edges=%d selfloops=%d sinks=%d'
                 % (len(nodes), len(edges), selfloops, sinks))
    return '\n'.join(lines)

# service call graph
api -> auth
api -> billing
auth -> cache
billing -> cache
api -> auth
cache -> cache
reports -> billing
auth -- session
orphan
billing -> Reports

Reports out:0 in:1 -> -
api out:2 in:0 -> auth,billing
auth out:2 in:2 -> cache,session
billing out:2 in:2 -> Reports,cache
cache out:1 in:3 -> cache
orphan out:0 in:0 -> -
reports out:1 in:0 -> billing
session out:1 in:1 -> auth
nodes=8 edges=9 selfloops=1 sinks=2

Build an adjacency report from a directed edge list.

Parsing:
1. Lines are stripped; blank lines and lines starting with '#' are ignored.
2. An edge line contains '->' (directed, left to right) or '--' (undirected). '->' is tested first, so a
   line containing both is treated as directed on its FIRST '->'. An undirected edge contributes BOTH
   directions.
3. A line with neither separator declares an isolated node with that name.
4. Node names are stripped and are case-sensitive, so 'Reports' and 'reports' are different nodes.
5. Duplicate directed edges (same source and target) are collapsed to one. A self-loop (source equals
   target) is kept and counts once in the out-degree and once in the in-degree of that node.

Output: one line per node, for every node that appears anywhere (as a source, a target, or an isolated
declaration), ordered by node name ascending using ordinary Python string comparison. Format:
    '<node> out:<n> in:<m> -> <targets>'
where <n> and <m> are the out-degree and in-degree after collapsing duplicates and <targets> is the
node's distinct out-neighbours sorted ascending and joined by ',' or the literal '-' when there are none.

After the node lines add a final line:
    'nodes=<N> edges=<E> selfloops=<S> sinks=<K>'
where E counts distinct directed edges, S counts distinct self-loops, and K counts nodes with out-degree
zero. Join with '\n'; no trailing newline and no trailing whitespace on any line.


Submission 9UJGL1

import re

UUID_RE = re.compile(r'^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$')
NIL = '00000000-0000-0000-0000-000000000000'
GROUP_ORDER = ['v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'v7', 'v8',
               'nil', 'non-rfc', 'unknown', 'invalid']

def _normalise(token):
    value = token.strip()
    if value.lower().startswith('urn:uuid:'):
        value = value[9:]
    if value.startswith('{') and value.endswith('}') and len(value) >= 2:
        value = value[1:-1]
    return value.lower()

def transform(text):
    groups = {name: [] for name in GROUP_ORDER}
    seen = set()
    for raw in text.split('\n'):
        original = raw.strip()
        if not original:
            continue
        candidate = _normalise(original)
        if not UUID_RE.match(candidate):
            if original in seen:
                continue
            seen.add(original)
            groups['invalid'].append(original)
            continue
        if candidate in seen:
            continue
        seen.add(candidate)
        if candidate == NIL:
            groups['nil'].append(candidate)
            continue
        variant_digit = candidate.split('-')[3][0]
        if variant_digit not in '89ab':
            groups['non-rfc'].append(candidate)
            continue
        version_digit = candidate.split('-')[2][0]
        name = 'v' + version_digit if version_digit in '12345678' else 'unknown'
        groups[name].append(candidate)

    lines = []
    for name in GROUP_ORDER:
        members = groups[name]
        if not members:
            continue
        lines.append('%s: %d -> %s' % (name, len(members), ', '.join(members)))
    return '\n'.join(lines)

Group a list of candidate UUID strings by RFC 9562 version.

Normalisation before parsing: strip surrounding whitespace, remove a leading 'urn:uuid:' prefix
(case-insensitive), and remove one pair of surrounding braces '{' '}' if present. Then lowercase.
A token is a valid UUID only if what remains matches exactly 8-4-4-4-12 lowercase hexadecimal digits
separated by hyphens.

Classification of a valid UUID:
- The all-zero UUID is the Nil UUID and is classified as 'nil' regardless of its version nibble.
- Otherwise the version is the first hex digit of the third group, and the variant is determined by the
  first hex digit of the fourth group: digits 8, 9, a or b mean the RFC 4122/9562 variant. A UUID whose
  variant digit is anything else is classified as 'non-rfc' no matter what its version nibble says.
- An RFC-variant UUID with a version digit of 1-8 is classified as 'v<digit>'; any other version digit is
  classified as 'unknown'.
Invalid tokens are classified as 'invalid' and reported by their ORIGINAL text, stripped of surrounding
whitespace only.

Duplicates: two tokens that normalise to the same lowercase UUID count once; the first occurrence's
normalised form is kept. Invalid tokens are deduplicated on their stripped original text the same way.

Output: one line per non-empty group, groups ordered as v1, v2, v3, v4, v5, v6, v7, v8, nil, non-rfc,
unknown, invalid. Each line is '<group>: <count> -> <members joined by ', '>' with members in first-seen
input order. Join with '\n'; no trailing newline and no trailing whitespace on any line.


Submission GOKNW0

def _parse(line):
    if line.count('/') != 1:
        return None
    address, prefix_text = line.split('/')
    if not prefix_text.isdigit():
        return None
    prefix = int(prefix_text)
    if prefix > 32:
        return None
    parts = address.split('.')
    if len(parts) != 4:
        return None
    value = 0
    for part in parts:
        if not part.isdigit():
            return None
        octet = int(part)
        if octet > 255:
            return None
        value = (value << 8) | octet
    return value, prefix

def _dotted(value):
    return '%d.%d.%d.%d' % ((value >> 24) & 255, (value >> 16) & 255,
                            (value >> 8) & 255, value & 255)

def transform(text):
    valid = []
    seen = set()
    invalid = []
    for raw in text.split('\n'):
        line = raw.strip()
        if not line:
            continue
        parsed = _parse(line)
        if parsed is None:
            invalid.append(line)
            continue
        value, prefix = parsed
        mask = 0 if prefix == 0 else ((1 << 32) - 1) ^ ((1 << (32 - prefix)) - 1)
        network = value & mask
        broadcast = network | (((1 << 32) - 1) ^ mask)
        key = (network, prefix)
        if key in seen:
            continue
        seen.add(key)
        total = 1 << (32 - prefix)
        if prefix == 32:
            usable = 1
        elif prefix == 31:
            usable = 2
        else:
            usable = total - 2
        valid.append((network, prefix, broadcast, total, usable))

    valid.sort(key=lambda entry: (entry[0], entry[1]))

    lines = []
    for network, prefix, broadcast, total, usable in valid:
        lines.append('%s/%d %s-%s total=%d usable=%d'
                     % (_dotted(network), prefix, _dotted(network),
                        _dotted(broadcast), total, usable))
    for line in invalid:
        lines.append('INVALID %s' % line)
    return '\n'.join(lines)

Each non-empty input line is a candidate IPv4 CIDR block 'A.B.C.D/P'. Produce a network table.

Validation: the address must be four dot-separated decimal octets, each 0-255 with no leading '+'/'-' and
no empty part; the prefix must be an integer 0-32. Anything else is INVALID.

For a valid entry:
- network address = address AND netmask; broadcast address = network OR the inverted netmask
- the canonical block is '<network>/<prefix>'; a host address such as 10.0.0.5/24 canonicalises to
  10.0.0.0/24
- total = 2 ** (32 - prefix)
- usable host count: total - 2 for prefixes 0-30, but exactly 2 for a /31 (RFC 3021 point-to-point link)
  and exactly 1 for a /32 (single host)

Deduplicate on the canonical block, keeping the FIRST occurrence's position. Do not merge or subtract
overlapping blocks; a /8 that contains a /24 is reported independently.

Ordering of valid rows: by network address as a 32-bit integer ascending, then by prefix ascending.

Output: one line per valid block
    '<network>/<prefix> <first>-<last> total=<t> usable=<u>'
where <first> is the network address and <last> is the broadcast address, both dotted-quad. Then one line
per invalid input, in input order, formatted 'INVALID <original line stripped>'. Join with '\n'; no
trailing newline and no trailing whitespace on any line.


Submission 9HIQS7

import re

MOVE_NUMBER = re.compile(r'^\d+\.+$')
NAG = re.compile(r'^\$\d+$')
RESULTS = ('1-0', '0-1', '1/2-1/2', '*')
SUFFIXES = ('!!', '??', '!?', '?!', '!', '?')

def _strip_braces(text):
    out = []
    depth = 0
    for ch in text:
        if ch == '{':
            depth += 1
            continue
        if ch == '}':
            if depth:
                depth -= 1
            continue
        if depth == 0:
            out.append(ch)
    return ''.join(out)

def _strip_variations(text):
    out = []
    depth = 0
    for ch in text:
        if ch == '(':
            depth += 1
            continue
        if ch == ')':
            if depth:
                depth -= 1
            continue
        if depth == 0:
            out.append(ch)
    return ''.join(out)

def transform(text):
    body_lines = [line for line in text.split('\n') if not line.strip().startswith('[')]
    body = ' '.join(body_lines)
    body = _strip_variations(_strip_braces(body))

    plies = []
    result = 'unknown'
    for token in body.split():
        if MOVE_NUMBER.match(token) or NAG.match(token):
            continue
        if token in RESULTS:
            result = token
            continue
        move = token
        annotation = ''
        for suffix in SUFFIXES:
            if move.endswith(suffix) and len(move) > len(suffix):
                annotation = suffix
                move = move[:-len(suffix)]
                break
        plies.append((move, annotation))

    lines = []
    for number, (move, annotation) in enumerate(plies, start=1):
        color = 'W' if number % 2 == 1 else 'B'
        extra = ' [%s]' % annotation if annotation else ''
        lines.append('%d. %s %s%s' % (number, color, move, extra))
    total = len(plies)
    lines.append('plies=%d moves=%d result=%s' % (total, (total + 1) // 2, result))
    return '\n'.join(lines)

[Event "Club Championship"]
[White "Ortiz, M."]
[Black "Novak, P."]
[Result "1/2-1/2"]

1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 {the Morphy defence} 4. Ba4 Nf6
5. O-O Be7 6. Re1 b5 7. Bb3 d6 8. c3 O-O 9. h3 Nb8!? 10. d4 Nbd7
11. c4 c6 12. cxb5 axb5 13. Nc3 Bb7 $14 14. Bg5 b4 15. Nb1 h6
16. Bh4 c5 17. dxe5 Nxe4 (17... dxe5 18. Nbd2) 18. Bxe7 Qxe7 1/2-1/2

Convert PGN movetext into a numbered ply list.

Preprocessing, in this order:
1. Drop every tag-pair line, i.e. a stripped line starting with '['.
2. Remove brace comments '{...}' (they do not nest in this input).
3. Remove recursive variations delimited by '(' and ')', including everything inside; these MAY nest and
   must be removed by depth counting.
4. Remove numeric annotation glyphs, i.e. tokens matching '$' followed by digits.
5. Join the remaining text with spaces and tokenise on whitespace.

Then drop move-number tokens (digits followed by one or more '.' characters, including black's '12...'
continuation form) and the game-termination marker, which is one of '1-0', '0-1', '1/2-1/2' or '*'.
What remains, in order, are the plies.

Suffix annotations '!', '?', '!!', '??', '!?', '?!' attached to a move are stripped from the move but
reported separately.

Output: one line per ply, formatted
    '<ply>. <color> <move><annotation>'
where <ply> is a 1-based counter over all plies, <color> is 'W' for odd plies and 'B' for even ones, and
<annotation> is the stripped suffix rendered as ' [' + suffix + ']' or the empty string when there was
none. Then append a final line
    'plies=<n> moves=<m> result=<r>'
where <m> is the number of full moves computed as ceil(n / 2) and <r> is the termination marker found, or
the literal 'unknown' when none was present. Join with '\n'; no trailing newline and no trailing
whitespace on any line.


Submission OD9U5V

import datetime

def transform(text):
    raw_lines = text.split('\n')
    unfolded = []
    for line in raw_lines:
        line = line.rstrip('\r')
        if line[:1] in (' ', '\t') and unfolded:
            unfolded[-1] += line[1:]
        else:
            unfolded.append(line)

    def unescape(value):
        out = []
        i = 0
        while i < len(value):
            ch = value[i]
            if ch == '\\' and i + 1 < len(value):
                nxt = value[i + 1]
                if nxt == ',':
                    out.append(',')
                    i += 2
                    continue
                if nxt == ';':
                    out.append(';')
                    i += 2
                    continue
                if nxt in ('n', 'N'):
                    out.append(' ')
                    i += 2
                    continue
            out.append(ch)
            i += 1
        return ''.join(out)

    def parse_stamp(value):
        return datetime.datetime(
            int(value[0:4]), int(value[4:6]), int(value[6:8]),
            int(value[9:11]), int(value[11:13]), int(value[13:15]),
        )

    events = []
    current = None
    for line in unfolded:
        if line == 'BEGIN:VEVENT':
            current = {}
            continue
        if line == 'END:VEVENT':
            if current is not None:
                events.append(current)
            current = None
            continue
        if current is None or ':' not in line:
            continue
        name, value = line.split(':', 1)
        if name in ('DTSTART', 'DTEND', 'SUMMARY', 'LOCATION'):
            current[name] = value

    rows = []
    for index, ev in enumerate(events):
        start = parse_stamp(ev['DTSTART'])
        end = parse_stamp(ev['DTEND'])
        summary = unescape(ev.get('SUMMARY', ''))
        location = unescape(ev.get('LOCATION', ''))
        if not location:
            location = 'TBD'
        minutes = int((end - start).total_seconds() // 60)
        rows.append((start, summary, index, end, location, minutes))

    rows.sort(key=lambda r: (r[0], r[1], r[2]))

    lines = []
    for start, summary, _idx, end, location, minutes in rows:
        lines.append('%s %s-%s | %s | %s | %dm' % (
            start.strftime('%Y-%m-%d'),
            start.strftime('%H:%M'),
            end.strftime('%H:%M'),
            summary,
            location,
            minutes,
        ))
    return '\n'.join(lines)

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Acme Corp//Scheduler 4.1//EN
BEGIN:VEVENT
UID:evt-1001@acme.example
DTSTART:20260914T090000Z
DTEND:20260914T100000Z
SUMMARY:Sprint planning
LOCATION:Room 3B
END:VEVENT
BEGIN:VEVENT
UID:evt-1002@acme.example
DTSTART:20260914T090000Z
DTEND:20260914T093000Z
SUMMARY:Coffee sync with the platform team\, part two
END:VEVENT
BEGIN:VEVENT
UID:evt-1003@acme.example
DTSTART:20260913T233000Z
DTEND:20260914T003000Z
SUMMARY:Release cutover
DESCRIPTION:Long description that is
  folded across lines
LOCATION:War room
END:VEVENT
END:VCALENDAR

2026-09-13 23:30-00:30 | Release cutover | War room | 60m
2026-09-14 09:00-09:30 | Coffee sync with the platform team, part two | TBD | 30m
2026-09-14 09:00-10:00 | Sprint planning | Room 3B | 60m

The input is an iCalendar (RFC 5545) stream in UTC. Produce a plain-text agenda.

Parsing rules:
1. Consider only content between BEGIN:VEVENT and END:VEVENT lines. Ignore every other line.
2. Unfold folded content lines first: any line that begins with a single space or a horizontal tab is a
   continuation of the previous line; remove that one leading space/tab character and append the rest to
   the previous line with no separator. Unfolding happens before any property is parsed.
3. A property line is 'NAME:VALUE' split on the first ':'. Property names are case-sensitive as given.
   Only DTSTART, DTEND, SUMMARY and LOCATION are used; all other properties are ignored.
4. In SUMMARY and LOCATION values, unescape the iCalendar backslash sequences: backslash+comma becomes a
   comma, backslash+semicolon becomes a semicolon, and backslash followed by 'n' or 'N' becomes a single
   space. Scanning is left to right and a produced character is never re-scanned. Any other backslash is
   kept as-is.
5. DTSTART/DTEND are basic-format UTC stamps 'YYYYMMDDThhmmssZ'.

Output: one line per VEVENT, formatted exactly as
    'YYYY-MM-DD hh:mm-hh:mm | SUMMARY | LOCATION | Nm'
where the date and the first time come from DTSTART, the second time from DTEND, LOCATION is the literal
string 'TBD' when the property is absent or its unescaped value is empty, and N is the duration in whole
minutes computed as DTEND minus DTSTART (an event may cross midnight, so compute on full timestamps, and
the duration is always non-negative in this data).

Ordering: sort by DTSTART ascending; ties are broken by the SUMMARY string ascending using ordinary
Python string comparison; any remaining tie keeps the original file order (stable sort).

Join lines with '\n'. No trailing newline and no trailing spaces on any line. All arithmetic is on UTC
instants, so the result must not depend on the machine's local timezone.


Submission 8A4NSR

import json
import re

LINE = re.compile(r'^( *)- +(.*)$')

def transform(text):
    roots = []
    # stack of (indent, node); node is None for the synthetic root container
    stack = [(-1, None)]
    for raw in text.split('\n'):
        if not raw.strip():
            continue
        match = LINE.match(raw.rstrip())
        if not match:
            continue
        indent = len(match.group(1))
        name = match.group(2).strip()
        while len(stack) > 1 and stack[-1][0] >= indent:
            stack.pop()
        node = {'name': name, 'children': []}
        parent = stack[-1][1]
        if parent is None:
            roots.append(node)
        else:
            parent['children'].append(node)
        stack.append((indent, node))
    return json.dumps(roots, indent=2, ensure_ascii=True)

- Platform
  - Ingest
    - Kafka bridge
    - S3 poller
  - Storage
        - Cold tier
  - Query
- Frontend
  - Web
    - Dashboard
  - Mobile
- Ops

Convert an indented bullet outline into a JSON tree.

Rules:
1. Ignore blank lines. Every other line matches optional spaces, then '- ', then the label. Tabs never
   appear. The label is stripped of surrounding whitespace.
2. Indentation is measured in leading spaces. Depth is derived from a stack of seen indent columns rather
   than by dividing by a fixed width: a line whose indent is greater than the current top of the stack
   pushes a new level (depth = previous depth + 1), regardless of how much greater it is. A line whose
   indent equals an indent already on the stack pops back to that level. A line whose indent is smaller
   than every stack entry but does not equal any of them pops to the deepest entry that is still less than
   it, or to the root when there is none. This makes an over-indented line (for example jumping from 4 to
   8 spaces) exactly one level deeper, not two.
3. Each node becomes an object with keys in this exact order: 'name' (string) and 'children' (array of
   child node objects, possibly empty). Sibling order follows file order.

Output: json.dumps of the list of root nodes with indent=2 and ensure_ascii=True, separators left at the
defaults for indent mode. Return that string with no trailing newline; json.dumps with indent never emits
trailing whitespace on a line.