Submission CZERNO

def transform(text):
    invalid = []
    rows = []
    for raw in text.split("\n"):
        line = raw.strip()
        if not line or line.startswith("#"):
            continue
        fields = line.split()
        if len(fields) < 4:
            invalid.append("INVALID " + line)
            continue
        source, mount, fstype, optfield = fields[0], fields[1], fields[2], fields[3]
        dump = fields[4] if len(fields) > 4 else "0"
        passno = fields[5] if len(fields) > 5 else "0"
        if source.startswith("UUID="):
            kind = "uuid"
        elif source.startswith("LABEL="):
            kind = "label"
        elif source.startswith("/"):
            kind = "device"
        else:
            kind = "pseudo"
        seen = []
        for opt in optfield.split(","):
            if not opt or opt == "defaults":
                continue
            if opt not in seen:
                seen.append(opt)
        options = ",".join(sorted(seen)) if seen else "defaults"
        rows.append((mount, fstype, kind, options, dump, passno))

    rows.sort(key=lambda r: (r[0], r[1]))
    out = list(invalid)
    for mount, fstype, kind, options, dump, passno in rows:
        out.append("%s|%s|%s|%s|%s%s" % (mount, fstype, kind, options, dump, passno))
    pseudo = sum(1 for r in rows if r[2] == "pseudo")
    out.append("mounts=%d invalid=%d pseudo=%d" % (len(rows), len(invalid), pseudo))
    return "\n".join(out)

# /etc/fstab: static file system information
UUID=7c2f-9a11   /          ext4   defaults,noatime,errors=remount-ro  0 1
/dev/sdb1        /data      xfs    rw,relatime,nofail                  0 2
tmpfs            /tmp       tmpfs  defaults                            0 0
LABEL=archive    /mnt/arch  ext4   noauto,user,ro,ro,noatime           0   0
proc /proc proc defaults 0 0
/dev/sdc1  /mnt/spare  auto  defaults
/dev/sdd1  swap

cgroup2  /sys/fs/cgroup  cgroup2  nsdelegate,memory_recursiveprot  0 0

INVALID /dev/sdd1  swap
/|ext4|uuid|errors=remount-ro,noatime|01
/data|xfs|device|nofail,relatime,rw|02
/mnt/arch|ext4|label|noatime,noauto,ro,user|00
/mnt/spare|auto|device|defaults|00
/proc|proc|pseudo|defaults|00
/sys/fs/cgroup|cgroup2|pseudo|memory_recursiveprot,nsdelegate|00
/tmp|tmpfs|pseudo|defaults|00
mounts=7 invalid=1 pseudo=3

Normalize a Unix fstab file into a mount table.
1. Strip each line; drop lines that are empty or start with '#'.
2. Split the remaining lines on runs of whitespace. A valid entry has at least 4 fields: source, mount point, filesystem type, options. Fields 5 (dump) and 6 (pass) default to '0' when absent. An entry with fewer than 4 fields is invalid: emit 'INVALID <the stripped line>' and skip it.
3. Classify the source: it starts with 'UUID=' -> 'uuid', starts with 'LABEL=' -> 'label', starts with '/' -> 'device', anything else -> 'pseudo'.
4. Split the options field on ','; drop empty entries; drop the literal option 'defaults'; deduplicate keeping one copy; sort the survivors ascending. If nothing remains use the single word 'defaults'.
5. Emit one line per valid entry: '<mount point>|<fstype>|<kind>|<options joined by ,>|<dump><pass>' where dump and pass are printed as one digit each with no separator between them.
6. Valid entries are sorted by mount point using ordinary string comparison, ties broken by filesystem type ascending. Invalid lines are all emitted first, in input order, before the sorted table.
7. Finally emit 'mounts=<valid count> invalid=<invalid count> pseudo=<count of kind pseudo>'.
8. Join the lines with '\n' and return them with no trailing newline.


Submission HC8HH0

from decimal import Decimal, ROUND_HALF_UP

def transform(text):
    lines = text.split("\n")
    while lines and lines[-1] == "":
        lines.pop()
    usable = len(lines) - (len(lines) % 4)

    out = []
    reads = 0
    bases = 0
    q30 = 0
    for start in range(0, usable, 4):
        header, seq, sep, qual = lines[start:start + 4]
        rid = header[1:].split(" ")[0] if header.startswith("@") else header.split(" ")[0]
        if not header.startswith("@") or not sep.startswith("+") or len(seq) != len(qual):
            out.append("%s MALFORMED" % rid)
            continue
        upper = seq.upper()
        length = len(upper)
        gc_count = upper.count("G") + upper.count("C")
        gc = (Decimal(gc_count) * 100 / Decimal(length)).quantize(
            Decimal("0.1"), rounding=ROUND_HALF_UP)
        scores = [ord(ch) - 33 for ch in qual]
        mean = (Decimal(sum(scores)) / Decimal(length)).quantize(
            Decimal("0.01"), rounding=ROUND_HALF_UP)
        out.append("%s len=%d gc=%s meanq=%s n=%d" % (
            rid, length, gc, mean, upper.count("N")))
        reads += 1
        bases += length
        q30 += sum(1 for s in scores if s >= 30)
    out.append("reads=%d bases=%d q30=%d" % (reads, bases, q30))
    return "\n".join(out)

@read_0001 lane=3 tile=1101
ACGTACGTNNGGCC
+
IIIIIIII##IIII
@read_0002
GGGCCCATTA
+read_0002
!!!!IIIIII
@read_0003 short
ACGT
+
III
@read_0004
atgcatgcatgc
+
5555IIII::::

Compute per-read statistics for a FASTQ file.
1. Split the input into lines and drop trailing empty lines. The remaining lines are grouped into records of exactly four lines: header, sequence, separator, quality. If the number of lines is not a multiple of four, ignore the leftover lines at the end.
2. The read id is the header line with its leading '@' removed, truncated at the first space.
3. A record is malformed when the header does not start with '@', the separator does not start with '+', or the sequence and quality strings differ in length. For a malformed record emit '<id> MALFORMED' and continue with the next record.
4. Sequence letters are upper-cased before counting. GC content is (count of G + count of C) divided by the read length, as a percentage rounded half-up to one decimal place, always printed with one decimal.
5. Quality scores use Phred+33: the score of a character is its code point minus 33. The mean score is rounded half-up to two decimal places and always printed with two decimals.
6. Emit one line per record: '<id> len=<length> gc=<pct> meanq=<mean> n=<count of N bases>'.
7. Then emit a final line 'reads=<good record count> bases=<total length of good records> q30=<number of quality characters across good records whose score is 30 or more>'.
8. Join the lines with '\n' and return them with no trailing newline.


Submission JO5X4H

from decimal import Decimal, ROUND_HALF_UP

def transform(text):
    out = []
    n = 0
    for raw in text.split("\n"):
        line = raw.strip()
        if not line:
            continue
        n += 1
        if not line.startswith("$") or line.count("*") != 1:
            out.append("%d: BADSUM" % n)
            continue
        body, _, tail = line[1:].partition("*")
        if len(tail) < 2:
            out.append("%d: BADSUM" % n)
            continue
        checksum = 0
        for ch in body:
            checksum ^= ord(ch)
        if "%02X" % checksum != tail[:2].upper():
            out.append("%d: BADSUM" % n)
            continue
        fields = body.split(",")
        if not fields[0].endswith("GGA"):
            out.append("%d: SKIP %s" % (n, fields[0]))
            continue
        if len(fields) < 10:
            out.append("%d: BADSUM" % n)
            continue
        if fields[6] == "0":
            out.append("%d: NOFIX" % n)
            continue

        def to_degrees(value, hemi, deg_digits):
            deg = Decimal(value[:deg_digits])
            minutes = Decimal(value[deg_digits:])
            result = deg + minutes / Decimal(60)
            if hemi in ("S", "W"):
                result = -result
            return str(result.quantize(Decimal("0.000001"), rounding=ROUND_HALF_UP))

        utc = fields[1].split(".")[0]
        stamp = "%s:%s:%s" % (utc[0:2], utc[2:4], utc[4:6])
        lat = to_degrees(fields[2], fields[3], 2)
        lon = to_degrees(fields[4], fields[5], 3)
        out.append("%d: %s %s %s sats=%d alt=%sm" % (
            n, stamp, lat, lon, int(fields[7]), fields[9]))
    return "\n".join(out)

Decode NMEA 0183 GGA fix sentences. Process every non-blank line in input order, numbering them from 1 counting only non-blank lines.
1. A sentence must start with '$' and contain exactly one '*'. The two characters after '*' are the checksum in hexadecimal. Compute the checksum as the XOR of every character strictly between '$' and '*'. Compare case-insensitively. On any structural problem or checksum mismatch emit '<n>: BADSUM' and continue.
2. Split the part between '$' and '*' on ','. The first field is the talker+type; if it does not end with 'GGA' emit '<n>: SKIP <field0>'.
3. Field layout: 1=UTC hhmmss(.sss), 2=latitude ddmm.mmmm, 3=N/S, 4=longitude dddmm.mmmm, 5=E/W, 6=fix quality, 7=satellites used, 9=altitude in metres.
4. If field 6 is '0' emit '<n>: NOFIX' and continue.
5. Convert latitude and longitude to signed decimal degrees: degrees + minutes/60, negative for 'S' and 'W'. Round half-up to 6 decimal places and always show 6 decimals.
6. Format UTC as 'hh:mm:ss', discarding any fractional seconds.
7. Emit '<n>: <hh:mm:ss> <lat> <lon> sats=<int satellites> alt=<altitude>m' where the satellite count is printed without leading zeros and the altitude is printed exactly as it appears in the sentence.
8. Join the lines with '\n' and return them with no trailing newline.


Submission 7PZSIU

def transform(text):
    origin = "."
    default_ttl = "3600"
    last_owner = None
    records = []

    for raw in text.split("\n"):
        line = raw.split(";")[0].rstrip()
        if not line.strip():
            continue
        if line.lstrip().startswith("$"):
            parts = line.split()
            if parts[0].upper() == "$ORIGIN":
                origin = parts[1]
            elif parts[0].upper() == "$TTL":
                default_ttl = parts[1]
            continue

        indented = line[0].isspace()
        tokens = line.split()
        if indented:
            owner_token = last_owner
        else:
            owner_token = tokens[0]
            tokens = tokens[1:]
        last_owner = owner_token

        ttl = default_ttl
        if tokens and tokens[0].isdigit():
            ttl = tokens[0]
            tokens = tokens[1:]
        if tokens and tokens[0].upper() == "IN":
            tokens = tokens[1:]
        rtype = tokens[0].upper()
        rdata = " ".join(tokens[1:])

        def expand(name):
            if name == "@":
                return origin
            if name.endswith("."):
                return name
            return name + "." + origin

        owner = expand(owner_token)
        if rtype in ("NS", "CNAME", "PTR"):
            rdata = expand(rdata)
        elif rtype == "MX":
            pref, target = rdata.split(None, 1)
            rdata = pref + " " + expand(target)
        records.append((owner, ttl, rtype, rdata))

    records.sort(key=lambda r: (r[0], r[2], r[3]))
    out = ["%s %s %s %s" % r for r in records]
    types = sorted({r[2] for r in records})
    out.append("records=%d types=%s" % (len(records), ",".join(types)))
    return "\n".join(out)

$ORIGIN example.net.
$TTL 3600
@        IN  NS    ns1            ; primary
         IN  NS    ns2.example.net.
@        IN  MX    10 mail
@        IN  MX    20 backup.mx.example.org.
ns1      IN  A     192.0.2.53
ns2  600 IN  A     192.0.2.54
www      IN  CNAME @
mail     IN  A     192.0.2.25
; a stray comment line
shop  300 IN  CNAME www
@        IN  TXT   "v=spf1 mx -all"
$ORIGIN dev.example.net.
api      IN  A     198.51.100.7
@        IN  NS    ns1.example.net.

api.dev.example.net. 3600 A 198.51.100.7
dev.example.net. 3600 NS ns1.example.net.
example.net. 3600 MX 10 mail.example.net.
example.net. 3600 MX 20 backup.mx.example.org.
example.net. 3600 NS ns1.example.net.
example.net. 3600 NS ns2.example.net.
example.net. 3600 TXT "v=spf1 mx -all"
mail.example.net. 3600 A 192.0.2.25
ns1.example.net. 3600 A 192.0.2.53
ns2.example.net. 600 A 192.0.2.54
shop.example.net. 300 CNAME www.example.net.
www.example.net. 3600 CNAME example.net.
records=12 types=A,CNAME,MX,NS,TXT

Expand a BIND-style DNS zone fragment into fully qualified records.
1. Remove a ';' comment from each line: everything from the first ';' to the end of the line is dropped. Then drop lines that are empty after stripping trailing whitespace.
2. '$ORIGIN name' and '$TTL seconds' are directives that set the current origin and the current default TTL. They produce no output. The origin always ends with a dot.
3. Every other line is a resource record. If the line starts with whitespace the owner name is inherited from the previous record; otherwise the first token is the owner name. After the owner, an optional all-digit TTL may appear, then the literal class 'IN', then the record type, then the rdata (all remaining tokens joined with a single space).
4. Owner name expansion: '@' becomes the current origin; a name ending in '.' is already absolute; any other name gets '.' plus the current origin appended.
5. For record types A and TXT the rdata is left alone. For NS, CNAME and PTR the whole rdata is a domain name and is expanded with the same rule as owner names. For MX the rdata is a preference number and a domain name; only the name is expanded.
6. Emit one line per record: '<owner> <ttl> <type> <rdata>' where ttl is the record's own TTL if present, otherwise the current default TTL.
7. Sort the emitted records by owner ascending, then type ascending, then rdata ascending, all as plain string comparisons.
8. Finally emit 'records=<count> types=<distinct types sorted ascending, joined by ,>'.
9. Join the lines with '\n' and return them with no trailing newline.


Submission OAH3JZ

def transform(text):
    raw_lines = text.split("\n")
    unfolded = []
    for line in raw_lines:
        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 in ("n", "N"):
                    out.append(" / ")
                elif nxt == ",":
                    out.append(",")
                elif nxt == ";":
                    out.append(";")
                else:
                    out.append(nxt)
                i += 2
                continue
            out.append(ch)
            i += 1
        return "".join(out)

    contacts = []
    card = None
    for line in unfolded:
        stripped = line.strip()
        if not stripped:
            continue
        if stripped.upper() == "BEGIN:VCARD":
            card = {"fn": None, "n": None, "org": None, "emails": [], "tels": []}
            continue
        if stripped.upper() == "END:VCARD":
            if card is not None:
                contacts.append(card)
            card = None
            continue
        if card is None or ":" not in stripped:
            continue
        head, _, value = stripped.partition(":")
        prop = head.split(";")[0].upper()
        value = unescape(value)
        if prop == "FN" and card["fn"] is None:
            card["fn"] = value
        elif prop == "N" and card["n"] is None:
            card["n"] = value
        elif prop == "ORG" and card["org"] is None:
            card["org"] = " / ".join(part.strip() for part in value.split(";") if part.strip())
        elif prop == "EMAIL":
            card["emails"].append(value)
        elif prop == "TEL":
            cleaned = value
            for junk in (" ", "-", ".", "(", ")"):
                cleaned = cleaned.replace(junk, "")
            card["tels"].append(cleaned)

    out = []
    with_email = 0
    for card in contacts:
        name = card["fn"]
        if not name:
            if card["n"]:
                parts = card["n"].split(";")
                given = parts[1] if len(parts) > 1 else ""
                family = parts[0] if parts else ""
                name = (given + " " + family).strip()
            if not name:
                name = "Unnamed"
        org = card["org"] or "-"
        emails = ",".join(card["emails"]) if card["emails"] else "-"
        tels = ",".join(card["tels"]) if card["tels"] else "-"
        if card["emails"]:
            with_email += 1
        out.append("%s|%s|%s|%s" % (name, org, emails, tels))
    out.append("contacts=%d withemail=%d" % (len(contacts), with_email))
    return "\n".join(out)

BEGIN:VCARD
VERSION:3.0
N:Okonkwo;Adaeze;Q;Dr.;
FN:Dr. Adaeze Okonkwo
ORG:Longname Research Institute for Applied
  Cartography;Mapping Division
TEL;TYPE=WORK,VOICE:+44 20 7946-0958
TEL;TYPE=CELL:+44 (7700) 900.123
EMAIL;TYPE=INTERNET;TYPE=PREF:adaeze@example.org
NOTE:Field survey lead\nAvailable Tuesdays
END:VCARD
BEGIN:VCARD
VERSION:3.0
N:Zhang;Bo;;;
ORG:Solo Practice
EMAIL:bo@example.net
EMAIL:bo.zhang@work.example.net
END:VCARD
BEGIN:VCARD
VERSION:3.0
FN:Kiosk Support Desk
TEL:0800 555 0199
END:VCARD

Dr. Adaeze Okonkwo|Longname Research Institute for Applied Cartography / Mapping Division|adaeze@example.org|+442079460958,+447700900123
Bo Zhang|Solo Practice|bo@example.net,bo.zhang@work.example.net|-
Kiosk Support Desk|-|-|08005550199
contacts=3 withemail=2

Flatten a stream of vCard 3.0 records into one line per contact.
1. First unfold the input: a line beginning with a space or a horizontal tab is a continuation of the previous line; remove exactly one leading whitespace character and append the rest to the previous line. Do this before any other parsing.
2. A contact runs from a 'BEGIN:VCARD' line to the next 'END:VCARD' line. Ignore anything outside such a block.
3. Split every property line at the first ':'. The part before it is the name plus optional ';'-separated parameters; the part after it is the value. Property names are compared case-insensitively.
4. In values, the escape sequences '\\n' and '\\N' mean a line break and are replaced by ' / '; '\\,' means a comma and '\\;' means a semicolon.
5. Collect FN (first occurrence wins), ORG (its ';'-separated components joined with ' / '), every EMAIL in file order and every TEL in file order. A TEL value is normalized by deleting spaces, hyphens, dots and parentheses.
6. A contact with no FN uses the value of N, taking its second ';' component then its first, joined with a space and stripped; if there is no N either, use 'Unnamed'.
7. Emit one line per contact: '<FN>|<ORG or ->|<emails joined by ,, or - when none>|<tels joined by ,, or - when none>'.
8. Finally emit 'contacts=<count> withemail=<count having at least one EMAIL>'.
9. Join the lines with '\n' and return them with no trailing newline.


Submission RL0PCN

def transform(text):
    name = "Untitled"
    entries = []
    pending = None
    for raw in text.split("\n"):
        line = raw.strip()
        if not line:
            continue
        if line.startswith("#"):
            if line.startswith("#PLAYLIST:"):
                name = line[len("#PLAYLIST:"):].strip()
            elif line.startswith("#EXTINF:"):
                info = line[len("#EXTINF:"):]
                secs, _, title = info.partition(",")
                pending = (int(secs.strip()), title)
            continue
        if pending is not None:
            entries.append((pending[0], pending[1], line))
            pending = None

    out = []
    known_total = 0
    known = 0
    for index, (secs, title, uri) in enumerate(entries, start=1):
        if " - " in title:
            artist, song = title.split(" - ", 1)
            artist, song = artist.strip(), song.strip()
        else:
            artist, song = "<unknown>", title.strip()
        if uri.startswith("http://") or uri.startswith("https://"):
            medium = "stream"
        else:
            tail = uri.split("/")[-1]
            medium = tail.rsplit(".", 1)[1].lower() if "." in tail else "none"
        if secs == -1:
            length = "--:--"
        else:
            length = "%d:%02d" % (secs // 60, secs % 60)
            known_total += secs
            known += 1
        out.append("%d. %s | %s | %s | %s" % (index, artist, song, length, medium))
    hours, rest = divmod(known_total, 3600)
    out.append("playlist=%s entries=%d known=%d total=%d:%02d:%02d" % (
        name, len(entries), known, hours, rest // 60, rest % 60))
    return "\n".join(out)

#EXTM3U
#PLAYLIST:Night Drive
#EXTINF:213,Kessler Trio - Amber Underpass
tracks/amber_underpass.mp3
#EXTINF:-1,Harbour Radio Live
https://stream.example.org/harbour
# a stray comment that should be ignored
#EXTINF:95,Interlude
tracks/interlude.flac
#EXTINF:3067,Kessler Trio - The Long Way Back
/media/library/long way back

#EXTINF:47,Nuria Vidal  -  Coda
tracks/coda.OGG

1. Kessler Trio | Amber Underpass | 3:33 | mp3
2. <unknown> | Harbour Radio Live | --:-- | stream
3. <unknown> | Interlude | 1:35 | flac
4. Kessler Trio | The Long Way Back | 51:07 | none
5. Nuria Vidal | Coda | 0:47 | ogg
playlist=Night Drive entries=5 known=4 total=0:57:02

Turn an extended M3U playlist into a numbered track listing.
1. Ignore the '#EXTM3U' header and any blank line. A '#PLAYLIST:<name>' line sets the playlist name; if it never appears use 'Untitled'.
2. A '#EXTINF:<seconds>,<title>' line describes the next entry; seconds is an integer that may be -1 for unknown. The entry's URI is the first following line that is not blank and does not start with '#'. Any other '#' line is ignored.
3. The title is split on the first occurrence of ' - ' into artist and song title. If there is no ' - ', the artist is '<unknown>' and the whole string is the song title. Both halves are stripped.
4. The medium column is 'stream' when the URI starts with 'http://' or 'https://'; otherwise it is the lower-cased extension after the last '.' of the URI's final path segment, or 'none' when that segment has no dot.
5. Emit one line per entry, numbered from 1 in playlist order: '<n>. <artist> | <song title> | <length> | <medium>'. Length is 'M:SS' with the minutes unpadded, or '--:--' when the duration is -1.
6. Finally emit 'playlist=<name> entries=<count> known=<count with a known duration> total=<H:MM:SS>' where total sums only the known durations and prints hours unpadded with two-digit minutes and seconds.
7. Join the lines with '\n' and return them with no trailing newline.


Submission 76QRUB

import re
from decimal import Decimal, ROUND_HALF_UP

WIND = re.compile(r"^(\d{3}|VRB)(\d{2,3})(?:G(\d{2,3}))?KT$")
TEMP = re.compile(r"^(M?\d{1,2})/(M?\d{1,2})$")

def transform(text):
    out = []
    good = 0
    bad = 0
    for raw in text.split("\n"):
        line = raw.strip()
        if not line:
            continue
        tokens = line.split()
        if len(tokens) < 2 or len(tokens[1]) != 7 or not tokens[1].endswith("Z") \
                or not tokens[1][:6].isdigit():
            out.append("%s INVALID" % tokens[0])
            bad += 1
            continue
        station = tokens[0]
        stamp = tokens[1]
        wind = vis = temp = dew = qnh = "?"
        for token in tokens[2:]:
            if wind == "?" and token.endswith("KT"):
                m = WIND.match(token)
                if m:
                    direction, speed, gust = m.groups()
                    if direction == "000" and speed == "00":
                        wind = "calm"
                    else:
                        wind = "%s@%skt" % (direction, speed)
                        if gust:
                            wind += "g%s" % gust
                    continue
            if vis == "?":
                if token == "CAVOK":
                    vis = "CAVOK"
                    continue
                if token == "9999":
                    vis = "10+km"
                    continue
                if len(token) == 4 and token.isdigit():
                    metres = (Decimal(token) / Decimal(1000)).quantize(
                        Decimal("0.1"), rounding=ROUND_HALF_UP)
                    vis = "%skm" % metres
                    continue
                if token.endswith("SM"):
                    body = token[:-2]
                    if "/" in body:
                        num, den = body.split("/")
                        miles = Decimal(num) / Decimal(den)
                    else:
                        miles = Decimal(body)
                    km = (miles * Decimal("1.609344")).quantize(
                        Decimal("0.1"), rounding=ROUND_HALF_UP)
                    vis = "%skm" % km
                    continue
            if temp == "?":
                m = TEMP.match(token)
                if m:
                    def celsius(value):
                        sign = "-" if value.startswith("M") else ""
                        return sign + str(int(value.lstrip("M")))
                    temp = celsius(m.group(1))
                    dew = celsius(m.group(2))
                    continue
            if qnh == "?" and len(token) == 5:
                if token[0] == "Q" and token[1:].isdigit():
                    qnh = "%dhPa" % int(token[1:])
                    continue
                if token[0] == "A" and token[1:].isdigit():
                    inhg = Decimal(token[1:]) / Decimal(100)
                    hpa = (inhg * Decimal("33.8639")).quantize(
                        Decimal("0.1"), rounding=ROUND_HALF_UP)
                    qnh = "%shPa" % hpa
                    continue
        out.append("%s %s/%s:%sZ wind=%s vis=%s t=%sC dp=%sC qnh=%s" % (
            station, stamp[0:2], stamp[2:4], stamp[4:6], wind, vis, temp, dew, qnh))
        good += 1
    out.append("reports=%d invalid=%d" % (good, bad))
    return "\n".join(out)

EGLL 12/13:50Z wind=240@15ktg27 vis=10+km t=12C dp=9C qnh=1008hPa
KJFK 12/13:51Z wind=calm vis=0.8km t=-2C dp=-3C qnh=1013.2hPa
LFPG 12/14:00Z wind=VRB@03kt vis=CAVOK t=25C dp=12C qnh=1015hPa
YSSY 12/14:30Z wind=090@18kt vis=8.0km t=19C dp=14C qnh=1012hPa
NZAA 12/15:00Z wind=360@04kt vis=3.0km t=7C dp=7C qnh=998hPa
BROKEN INVALID
CYYZ 12/15:30Z wind=310@12kt vis=3.2km t=-8C dp=-11C qnh=1007.5hPa
reports=6 invalid=1

Decode METAR aviation weather reports. Process every non-blank line, stripped, in order.
1. Split on whitespace. The first token is the station identifier; the second must be a 7-character day-time group 'DDHHMMZ'. If it is missing or malformed, emit '<station> INVALID' and continue.
2. Scan the remaining tokens:
   - Wind: a token ending in 'KT'. '00000KT' is 'calm'. 'VRBffKT' is 'VRB@<ff>kt'. Otherwise 'dddff(Gxx)KT' is '<ddd>@<ff>kt' with 'g<xx>' appended when a gust group is present. Leading zeros are kept exactly as written.
   - Visibility: the token 'CAVOK' gives 'CAVOK'; '9999' gives '10+km'; any other 4-digit token gives metres divided by 1000 with one decimal and 'km'; a token ending in 'SM' gives statute miles converted with 1 mile = 1.609344 km, rounded half-up to one decimal, plus 'km'. A mile value may be a fraction like '1/2'.
   - Temperature: a token matching '<t>/<d>' where each half is one or two digits optionally prefixed by 'M' for minus. 'M' becomes a leading '-'; leading zeros are dropped.
   - Pressure: 'Qnnnn' gives '<nnnn>hPa' with leading zeros dropped; 'Annnn' is inches of mercury in hundredths, converted with 1 inHg = 33.8639 hPa and rounded half-up to one decimal, then 'hPa'.
3. Any field that never appears is reported as '?'.
4. Emit one line per report: '<station> <DD>/<HH>:<MM>Z wind=<wind> vis=<visibility> t=<temp>C dp=<dewpoint>C qnh=<pressure>'.
5. Finally emit 'reports=<count of decoded reports> invalid=<count of invalid lines>'.
6. Join the lines with '\n' and return them with no trailing newline.


Submission 6GGMAL

import hashlib

def transform(text):
    gaps = []
    data = bytearray()
    marker = None
    for raw in text.split("\n"):
        line = raw.strip()
        if not line:
            continue
        head = line.split("|", 1)[0].strip()
        tokens = head.split()
        if len(tokens) == 1 and all(c in "0123456789abcdefABCDEF" for c in tokens[0]):
            marker = int(tokens[0], 16)
            continue
        offset_token = tokens[0]
        offset = int(offset_token, 16)
        if offset != len(data):
            gaps.append("GAP at " + offset_token)
        for token in tokens[1:]:
            data.append(int(token, 16))

    if marker is None:
        marker_state = "absent"
    elif marker == len(data):
        marker_state = "ok"
    else:
        marker_state = "mismatch"

    printable = sum(1 for b in data if 0x20 <= b <= 0x7E)
    rendered = "".join(chr(b) if 0x20 <= b <= 0x7E else "." for b in data)
    out = list(gaps)
    out.append("length=%d" % len(data))
    out.append("marker=%s" % marker_state)
    out.append("sha256=%s" % hashlib.sha256(bytes(data)).hexdigest())
    out.append("printable=%d" % printable)
    out.append("text=%s" % rendered)
    return "\n".join(out)

Reconstruct the bytes described by a 'hexdump -C' listing.
1. Ignore blank lines. A line consisting only of hexadecimal digits is the trailing length marker; remember the last one seen.
2. Every other line starts with an 8-digit hexadecimal offset, then whitespace, then up to 16 two-digit hexadecimal byte values, then an optional '|...|' ASCII gutter. Take everything before the first '|' (or the whole line when there is no '|'), drop the first whitespace-separated token as the offset, and treat the remaining tokens as byte values.
3. Concatenate the bytes of every data line in the order the lines appear. Ignore the offsets when concatenating, but verify them: if a data line's offset differs from the number of bytes gathered so far, emit 'GAP at <the 8-digit offset as written>' as its own output line and keep going.
4. After all lines, emit these lines in order:
   'length=<number of bytes>'
   'marker=<ok|mismatch|absent>' comparing the trailing length marker to the reconstructed length,
   'sha256=<hex digest of the reconstructed bytes>',
   'printable=<count of bytes in the inclusive range 0x20..0x7e>',
   'text=<the reconstructed bytes decoded as latin-1 with every byte outside 0x20..0x7e replaced by a dot>'.
5. GAP lines come first, in input order, before the five summary lines.
6. Join the lines with '\n' and return them with no trailing newline.


Submission 6VWBYK

import json

def transform(text):
    physical = text.split("\n")
    logical = []
    buffer = ""
    continuing = False
    for line in physical:
        current = line.lstrip() if continuing else line
        trailing = len(current) - len(current.rstrip("\\"))
        if trailing % 2 == 1:
            buffer += current[:-1]
            continuing = True
            continue
        buffer += current
        logical.append(buffer)
        buffer = ""
        continuing = False
    if continuing or buffer:
        logical.append(buffer)

    def unescape(chunk):
        out = []
        i = 0
        while i < len(chunk):
            ch = chunk[i]
            if ch != "\\":
                out.append(ch)
                i += 1
                continue
            if i + 1 >= len(chunk):
                i += 1
                continue
            nxt = chunk[i + 1]
            if nxt == "t":
                out.append("\t")
            elif nxt == "n":
                out.append("\n")
            elif nxt == "r":
                out.append("\r")
            elif nxt == "f":
                out.append("\f")
            elif nxt == "u":
                out.append(chr(int(chunk[i + 2:i + 6], 16)))
                i += 6
                continue
            else:
                out.append(nxt)
            i += 2
        return "".join(out)

    result = {}
    for line in logical:
        line = line.lstrip()
        if not line or line[0] in ("#", "!"):
            continue
        i = 0
        key_chars = []
        sep_index = None
        while i < len(line):
            ch = line[i]
            if ch == "\\" and i + 1 < len(line):
                key_chars.append(ch)
                key_chars.append(line[i + 1])
                i += 2
                continue
            if ch in ("=", ":") or ch.isspace():
                sep_index = i
                break
            key_chars.append(ch)
            i += 1
        raw_key = "".join(key_chars)
        if sep_index is None:
            result[unescape(raw_key)] = ""
            continue
        rest = line[sep_index:]
        stripped = rest.lstrip()
        if rest[0].isspace() and stripped[:1] in ("=", ":"):
            rest = stripped[1:]
        elif rest[0] in ("=", ":"):
            rest = rest[1:]
        else:
            rest = stripped
        value = rest.lstrip()
        result[unescape(raw_key)] = unescape(value)

    return json.dumps(result, indent=2, sort_keys=True, ensure_ascii=False)

# database settings
! legacy comment style
db.host = localhost
db.port:5432
db.name  postgres
db.host = 127.0.0.1
long.description = first fragment \
    second fragment \
    third fragment
path.windows = C\:\\logs\\app
empty.value =
key\ with\ space = present
greeting = café – ready
tabbed.value = left\tright

first fragment second fragment third fragment

Parse a Java .properties file into JSON.
1. A logical line ends where a physical line does NOT end with an odd number of backslashes. When a line ends with a single backslash, that backslash and the newline are removed and the leading whitespace of the next physical line is stripped before joining.
2. Leading whitespace of a logical line is removed. A logical line that is empty, or whose first character is '#' or '!', is a comment and is skipped.
3. The key ends at the first unescaped '=', ':' or run of whitespace. Whitespace around that separator is discarded; if the separator was whitespace only, the next '=' or ':' immediately following is also consumed. The rest of the logical line is the value; it keeps internal spacing but has no leading whitespace.
4. In both key and value, backslash escapes are resolved: '\\t' tab, '\\n' newline, '\\r' carriage return, '\\f' form feed, '\\uXXXX' the code point given by four hexadecimal digits, and a backslash before any other character yields that character.
5. A key that appears twice keeps the value of its last occurrence.
6. Return the resulting mapping as JSON produced with json.dumps using indent=2, sort_keys=True and ensure_ascii=False.


Submission HNEE8V

def transform(text):
    physical = text.split("\n")
    logical = []
    buffer = None
    for line in physical:
        piece = line
        if buffer is not None:
            piece = piece.lstrip()
            piece = buffer + " " + piece
            buffer = None
        if piece.endswith("\\"):
            buffer = piece[:-1].rstrip()
            continue
        logical.append(piece)
    if buffer is not None:
        logical.append(buffer)

    targets = {}
    order = []
    phony = set()
    current = []
    for line in logical:
        if line.startswith("\t"):
            for name in current:
                targets[name]["recipes"] += 1
            continue
        stripped = line.strip()
        if not stripped or stripped.startswith("#"):
            continue
        colon = stripped.find(":")
        equals = stripped.find("=")
        if equals != -1 and (colon == -1 or equals < colon):
            current = []
            continue
        if colon == -1:
            current = []
            continue
        head = stripped[:colon]
        rest = stripped[colon + 1:]
        recipe_inline = 0
        if ";" in rest:
            rest, _, _tail = rest.partition(";")
            recipe_inline = 1
        prereqs = rest.split()
        names = head.split()
        if names == [".PHONY"]:
            phony.update(prereqs)
            current = []
            continue
        current = []
        for name in names:
            if name not in targets:
                targets[name] = {"prereqs": [], "recipes": 0}
                order.append(name)
            for p in prereqs:
                if p not in targets[name]["prereqs"]:
                    targets[name]["prereqs"].append(p)
            targets[name]["recipes"] += recipe_inline
            current.append(name)

    out = []
    for name in sorted(targets):
        info = targets[name]
        prereqs = ",".join(info["prereqs"]) if info["prereqs"] else "-"
        out.append("%s: %s recipes=%d phony=%s" % (
            name, prereqs, info["recipes"], "yes" if name in phony else "no"))
    missing = sorted({p for info in targets.values() for p in info["prereqs"]
                      if p not in targets})
    out.append("missing=%s" % (",".join(missing) if missing else "-"))
    return "\n".join(out)

CC = gcc
CFLAGS = -O2 -Wall
OBJ = main.o util.o

# default goal
all: build test

build: $(OBJ) banner.h
	$(CC) $(CFLAGS) -o app $(OBJ)
	@echo built

main.o: main.c util.h \
        banner.h
	$(CC) -c main.c

util.o: util.c util.h
	$(CC) -c util.c

test: build ; ./app --selftest

.PHONY: all test clean
clean:
	rm -f *.o app
build: extra.h
	@echo second rule

all: build,test recipes=0 phony=yes
build: $(OBJ),banner.h,extra.h recipes=3 phony=no
clean: - recipes=1 phony=yes
main.o: main.c,util.h,banner.h recipes=1 phony=no
test: build recipes=1 phony=yes
util.o: util.c,util.h recipes=1 phony=no
missing=$(OBJ),banner.h,extra.h,main.c,util.c,util.h

Build a target report from a Makefile.
1. A physical line ending with a backslash continues onto the next line: remove the backslash and the newline and join with a single space, stripping the leading whitespace of the continuation.
2. A logical line starting with a TAB character is a recipe line belonging to the most recently seen rule; count it and otherwise ignore it.
3. After removing recipe lines, drop lines that are blank or whose first non-space character is '#'.
4. A line whose stripped form contains '=' before any ':' is a variable assignment and is ignored.
5. Every other line containing ':' is a rule. The targets are the whitespace-separated words before the first ':'. Everything after that ':' up to an optional ';' is the prerequisite list, split on whitespace; text after ';' is a recipe and is counted as one recipe line.
6. A target listed in a '.PHONY' rule's prerequisites is phony. The '.PHONY' rule itself is not reported as a target.
7. Report one line per target, sorted by target name ascending: '<target>: <prerequisites joined by ,, or - when none> recipes=<count> phony=<yes|no>'. When the same target appears in more than one rule, merge them: concatenate prerequisites in order of appearance without repeating one already present, and add up the recipe counts.
8. Then emit 'missing=<sorted, comma-separated list of prerequisites that are never defined as a target, or - when none>'. Compare prerequisites literally, including any '$(...)' text.
9. Join the lines with '\n' and return them with no trailing newline.


Submission ZR4ZR3

import re

PATTERN = re.compile(r"^P(?:(\d+)W|(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?)?)$")

def transform(text):
    out = []
    ok = 0
    total_sum = 0
    for raw in text.split("\n"):
        line = raw.strip()
        if not line:
            continue
        negative = line.startswith("-")
        body = line[1:] if negative else line
        if not body.startswith("P"):
            out.append("%s -> INVALID" % line)
            continue
        rest = body[1:]
        date_part, sep, time_part = rest.partition("T")
        if "Y" in date_part or "M" in date_part or "." in body or "," in body:
            out.append("%s -> UNSUPPORTED" % line)
            continue
        if rest == "" or (sep and time_part == ""):
            out.append("%s -> INVALID" % line)
            continue
        match = PATTERN.match(body)
        if not match:
            out.append("%s -> INVALID" % line)
            continue
        weeks, days, hours, minutes, seconds = match.groups()
        total = 0
        if weeks is not None:
            total = int(weeks) * 7 * 86400
        else:
            total += int(days or 0) * 86400
            total += int(hours or 0) * 3600
            total += int(minutes or 0) * 60
            total += int(seconds or 0)
        if negative:
            total = -total

        magnitude = abs(total)
        d, rem = divmod(magnitude, 86400)
        h, rem = divmod(rem, 3600)
        m, s = divmod(rem, 60)
        if magnitude == 0:
            canonical = "PT0S"
        else:
            canonical = "P"
            if d:
                canonical += "%dD" % d
            if h or m or s:
                canonical += "T"
                if h:
                    canonical += "%dH" % h
                if m:
                    canonical += "%dM" % m
                if s:
                    canonical += "%dS" % s
        if total < 0:
            canonical = "-" + canonical
        out.append("%s -> %d -> %s" % (line, total, canonical))
        ok += 1
        total_sum += total
    out.append("ok=%d sum=%d" % (ok, total_sum))
    return "\n".join(out)

PT1H30M
P3DT4H15M30S
PT0S
P1W
PT90M
-PT45S
P2DT
PT1.5H
P1Y2M
P10D
P2WT3H
PT36H
banana

Normalize a list of ISO 8601 durations. Process every non-blank line in order after stripping it.
1. A duration may start with '-' meaning a negative value. After that it must start with 'P'.
2. Supported forms are 'PnW' (weeks, 7 days each) and 'P[nD][T[nH][nM][nS]]'. All component values are non-negative integers.
3. Any duration containing a year ('Y') or month designator ('M' before the 'T'), or a fractional value, is unsupported: emit '<input> -> UNSUPPORTED'.
4. A duration that is not 'P' followed by at least one component, that has a 'T' with no component after it, that mixes 'W' with any other component, or that has any leftover characters, is invalid: emit '<input> -> INVALID'.
5. Otherwise compute the total in seconds: days*86400 + hours*3600 + minutes*60 + seconds, negated when the input started with '-'.
6. Canonical form: sign, then 'P', then the day count with 'D' if non-zero, then 'T' with the non-zero hour, minute and second components in that order, each followed by its designator. Recompute the components from the absolute total: days, then hours, then minutes, then seconds. A total of zero is written 'PT0S'.
7. Emit '<input> -> <total seconds> -> <canonical>'.
8. Finally emit 'ok=<count of converted lines> sum=<sum of their totals in seconds>'.
9. Join the lines with '\n' and return them with no trailing newline.


Submission C5IWWH

import re

def transform(text):
    entries = []
    i = 0
    while True:
        at = text.find("@", i)
        if at == -1:
            break
        brace = text.find("{", at)
        if brace == -1:
            break
        etype = text[at + 1:brace].strip().lower()
        depth = 0
        end = brace
        for pos in range(brace, len(text)):
            if text[pos] == "{":
                depth += 1
            elif text[pos] == "}":
                depth -= 1
                if depth == 0:
                    end = pos
                    break
        inner = text[brace + 1:end]
        i = end + 1
        key, _, rest = inner.partition(",")
        fields = {}
        depth = 0
        chunk = []
        chunks = []
        for ch in rest:
            if ch == "{":
                depth += 1
            elif ch == "}":
                depth -= 1
            if ch == "," and depth == 0:
                chunks.append("".join(chunk))
                chunk = []
                continue
            chunk.append(ch)
        chunks.append("".join(chunk))
        for piece in chunks:
            if "=" not in piece:
                continue
            name, _, value = piece.partition("=")
            name = name.strip().lower()
            value = value.strip()
            if value.startswith("{") and value.endswith("}"):
                value = value[1:-1]
            value = re.sub(r"\s+", " ", value).strip().replace("{", "").replace("}", "")
            fields[name] = value
        entries.append((key.strip(), etype, fields))

    def authors_of(fields):
        raw = fields.get("author")
        if not raw:
            return "Anonymous"
        formatted = []
        for person in raw.split(" and "):
            words = person.split()
            if not words:
                continue
            surname = words[-1]
            initials = " ".join(w[0] + "." for w in words[:-1])
            formatted.append("%s, %s" % (surname, initials) if initials else surname)
        return " & ".join(formatted) if formatted else "Anonymous"

    out = []
    for key, etype, fields in sorted(entries, key=lambda e: e[0]):
        year = fields.get("year", "n.d.")
        title = fields.get("title", "Untitled")
        who = authors_of(fields)
        pages = fields.get("pages", "").replace("--", "-")
        if etype == "article":
            tail = fields.get("journal", "")
            volume = fields.get("volume", "")
            number = fields.get("number", "")
            piece = tail
            if volume:
                piece += ", " + volume
                if number:
                    piece += "(%s)" % number
            if pages:
                piece += ", " + pages
            citation = "%s (%s). %s. %s." % (who, year, title, piece)
        elif etype == "book":
            citation = "%s (%s). %s. %s." % (who, year, title, fields.get("publisher", ""))
        else:
            citation = "%s (%s). %s." % (who, year, title)
        out.append("%s: %s" % (key, citation))
    types = sorted({e[1] for e in entries})
    out.append("entries=%d types=%s" % (len(entries), ",".join(types)))
    return "\n".join(out)

@article{knuth1984lp,
  author  = {Donald E. Knuth},
  title   = {Literate Programming},
  journal = {The Computer Journal},
  year    = 1984,
  volume  = {27},
  number  = {2},
  pages   = {97--111}
}

@book{lamport1994latex, author={Leslie Lamport}, title={{LaTeX}: A Document
  Preparation System}, publisher={Addison-Wesley}, year={1994}, edition={2nd}}

@misc{anon2020notes,
  title = {Field Notes on Peat Bog Drainage},
  year  = {2020}
}

@article{ostrom1990cpr,
  author = {Elinor Ostrom and Roy Gardner and James M. Walker},
  title  = {Governing the Commons},
  journal = {Cambridge Studies},
  year = {1990},
  volume = {8}
}

anon2020notes: Anonymous (2020). Field Notes on Peat Bog Drainage.
knuth1984lp: Knuth, D. E. (1984). Literate Programming. The Computer Journal, 27(2), 97-111.
lamport1994latex: Lamport, L. (1994). LaTeX: A Document Preparation System. Addison-Wesley.
ostrom1990cpr: Ostrom, E. & Gardner, R. & Walker, J. M. (1990). Governing the Commons. Cambridge Studies, 8.
entries=4 types=article,book,misc

Format BibTeX entries as plain-text citations.
1. An entry starts at '@<type>{<key>,' and ends at the matching closing brace, counting brace nesting. The type is lower-cased; the key is the text up to the first comma.
2. Inside an entry, fields are 'name = value' separated by commas that are not inside braces. The name is lower-cased and stripped. A value wrapped in braces has exactly one outer brace layer removed; otherwise it is used as written. Then collapse every run of whitespace into a single space, strip it, and delete all remaining brace characters.
3. Authors are the 'author' field split on ' and '. Format each author as '<Surname>, <initials>' where the surname is the last whitespace-separated word and each earlier word contributes its first character followed by a period, joined by single spaces. Join multiple authors with ' & '. A missing author field gives 'Anonymous'.
4. In the 'pages' field replace '--' with '-'.
5. Build the citation by entry type:
   - article: '<authors> (<year>). <title>. <journal>, <volume>(<number>), <pages>.'
   - book: '<authors> (<year>). <title>. <publisher>.'
   - anything else: '<authors> (<year>). <title>.'
   For an article, omit '(<number>)' when there is no number field, omit ', <pages>' when there are no pages, and omit '<volume>' when there is no volume. A missing year is written 'n.d.'; a missing title is written 'Untitled'.
6. Emit one line per entry: '<key>: <citation>', sorted by key ascending.
7. Then emit 'entries=<count> types=<distinct entry types sorted ascending and comma-joined>'.
8. Join the lines with '\n' and return them with no trailing newline.


Submission VXV422

def transform(text):
    def unescape(value):
        replacements = [("\\F\\", "|"), ("\\S\\", "^"), ("\\T\\", "&"),
                        ("\\R\\", "~"), ("\\E\\", "\\")]
        for token, replacement in replacements:
            value = value.replace(token, replacement)
        return value

    segments = []
    for raw in text.split("\n"):
        line = raw.strip()
        if line:
            segments.append(line.split("|"))

    def field(segment, index):
        if segment[0] == "MSH":
            index = index - 1
        if index < len(segment):
            return "^".join(unescape(part) for part in segment[index].split("^"))
        return ""

    def component(segment, index, position):
        if segment[0] == "MSH":
            raw_index = index - 1
        else:
            raw_index = index
        if raw_index >= len(segment):
            return ""
        parts = segment[raw_index].split("^")
        if position <= len(parts):
            return unescape(parts[position - 1])
        return ""

    flags = {"L": "LOW", "H": "HIGH", "LL": "CRITICAL-LOW",
             "HH": "CRITICAL-HIGH", "A": "ABNORMAL"}

    out = []
    obx = [s for s in segments if s[0] == "OBX"]
    notes = [s for s in segments if s[0] == "NTE"]
    for segment in segments:
        if segment[0] != "PID":
            continue
        identifier = component(segment, 3, 1)
        family = component(segment, 5, 1)
        given = component(segment, 5, 2)
        middle = component(segment, 5, 3)
        dob = field(segment, 7)
        sex = field(segment, 8)
        name = "%s, %s" % (family, given)
        if middle:
            name += " " + middle
        dob_text = "%s-%s-%s" % (dob[0:4], dob[4:6], dob[6:8]) if len(dob) == 8 else dob
        out.append("patient=%s (%s) dob=%s sex=%s" % (name, identifier, dob_text, sex))
        break

    abnormal = 0
    for segment in obx:
        name = component(segment, 3, 2) or component(segment, 3, 1)
        value = field(segment, 5)
        units = field(segment, 6)
        flag = field(segment, 8)
        line = "%s: %s" % (name, value)
        if units:
            line += " " + units
        if flag in flags:
            line += " [%s]" % flags[flag]
            abnormal += 1
        out.append(line)
    out.append("results=%d abnormal=%d notes=%d" % (len(obx), abnormal, len(notes)))
    return "\n".join(out)

MSH|^~\&|LIS|RiverLab|EHR|Clinic|20240117093000||ORU^R01|MSG00023|P|2.5
PID|1||A12345^^^MRN||Ramirez^Elena^Quiteria||19870204|F
OBR|1||LAB998|CBC^Complete Blood Count
OBX|1|NM|WBC^White Blood Cells||6.2|10*3/uL|4.0-11.0|N|||F
OBX|2|NM|HGB^Hemoglobin||10.1|g/dL|12.0-16.0|L|||F
OBX|3|NM|PLT^Platelets||702|10*3/uL|150-400|HH|||F
OBX|4|ST|COMMENT^Technologist note||Sample hemolyzed \T\ slightly clotted|||||F
NTE|1||Repeat draw if clinically indicated
NTE|2||Analyzer calibrated 20240117

patient=Ramirez, Elena Quiteria (A12345) dob=1987-02-04 sex=F
White Blood Cells: 6.2 10*3/uL
Hemoglobin: 10.1 g/dL [LOW]
Platelets: 702 10*3/uL [CRITICAL-HIGH]
Technologist note: Sample hemolyzed & slightly clotted
results=4 abnormal=2 notes=2

Extract a lab report from an HL7 v2 message.
1. Segments are the non-blank lines, stripped. Fields within a segment are separated by '|', components within a field by '^'.
2. Split into fields and components first, and only then decode these escape sequences inside each component: '\\F\\' -> '|', '\\S\\' -> '^', '\\T\\' -> '&', '\\R\\' -> '~', '\\E\\' -> a single backslash.
3. Field numbering: for the MSH segment the separator itself is field 1, so MSH-3 is the third '|'-separated token counting the segment name as index 0 plus one. For all other segments field n is the n-th '|'-separated token after the segment name.
4. From PID take field 3 component 1 as the patient identifier, field 5 component 1 as the family name, component 2 as the given name, component 3 as the middle name, field 7 as the birth date 'YYYYMMDD' and field 8 as the sex.
5. From each OBX take field 2 as the value type, field 3 component 2 as the test name (falling back to component 1 when there is no component 2), field 5 as the value, field 6 as the units and field 8 as the abnormal flag.
6. Emit, in order:
   - 'patient=<family>, <given> <middle> (<identifier>) dob=<YYYY-MM-DD> sex=<sex>' with the middle name and its preceding space omitted when empty.
   - one line per OBX in message order: '<test name>: <value>' followed by ' <units>' when units are present, and ' [<flag word>]' when the abnormal flag is one of L, H, LL, HH or A, mapped to LOW, HIGH, CRITICAL-LOW, CRITICAL-HIGH and ABNORMAL. A flag of 'N' or an empty flag adds nothing.
   - 'results=<number of OBX segments> abnormal=<number with a mapped flag> notes=<number of NTE segments>'.
7. Join the lines with '\n' and return them with no trailing newline.


Submission UDBMK5

import re

ENCODED_WORD = re.compile(r"^=\?utf-8\?Q\?(.*)\?=$", re.IGNORECASE)

def transform(text):
    lines = text.split("\n")
    if lines and lines[-1] == "":
        lines.pop()

    stats = {"escapes": 0}

    def decode(payload, underscore_is_space=False):
        data = bytearray()
        i = 0
        while i < len(payload):
            ch = payload[i]
            if ch == "=" and i + 2 < len(payload) + 1 and \
                    all(c in "0123456789abcdefABCDEF" for c in payload[i + 1:i + 3]) and \
                    len(payload[i + 1:i + 3]) == 2:
                data.append(int(payload[i + 1:i + 3], 16))
                stats["escapes"] += 1
                i += 3
                continue
            if underscore_is_space and ch == "_":
                data.append(0x20)
                i += 1
                continue
            data.extend(ch.encode("latin-1"))
            i += 1
        return data.decode("utf-8")

    out = []
    soft = 0
    buffer = None
    for line in lines:
        word = ENCODED_WORD.match(line.strip())
        if word and buffer is None:
            out.append(decode(word.group(1), True).rstrip())
            continue
        current = line if buffer is None else buffer + line
        if current.endswith("="):
            buffer = current[:-1]
            soft += 1
            continue
        buffer = None
        out.append(decode(current).rstrip())
    if buffer is not None:
        out.append(decode(buffer).rstrip())

    nonascii = sum(1 for line in out for ch in line if ord(ch) > 127)
    out.append("lines=%d soft=%d escapes=%d nonascii=%d" % (
        len(out), soft, stats["escapes"], nonascii))
    return "\n".join(out)

=?utf-8?Q?Caf=C3=A9_planning_meeting?=
Hello team,
This paragraph was wrapped by the mail=
er and must be rejoined without a space.
Budget: 1=2C500=E2=82=AC plus 5=25 handling.
Tabs=09and=20spaces survive the round trip.
Na=C3=AFve r=C3=A9sum=C3=A9 attached.
-- =
Signature block

Café planning meeting
Hello team,
This paragraph was wrapped by the mailer and must be rejoined without a space.
Budget: 1,500€ plus 5% handling.
Tabs	and spaces survive the round trip.
Naïve résumé attached.
-- Signature block
lines=7 soft=2 escapes=15 nonascii=5

Decode a quoted-printable message body.
1. Work line by line over the input, dropping a single trailing empty line if the text ends with a newline.
2. A line ending with '=' has a soft line break: remove that '=' and join the line with the next one before decoding. Count how many soft breaks were removed.
3. In the joined text, '=XX' where XX are two hexadecimal digits stands for the byte with that value; every other character contributes its own Latin-1 byte. Decode the resulting byte string as UTF-8.
4. A line whose stripped form matches '=?utf-8?Q?<payload>?=' (the charset and the 'Q' compared case-insensitively) is an RFC 2047 encoded word: decode the payload the same way but additionally treat '_' as a space. Such a line is decoded on its own and is not joined to its neighbours by soft-break handling.
5. Emit every decoded line, with trailing whitespace stripped from each one.
6. Then emit 'lines=<number of emitted lines> soft=<number of soft breaks removed> escapes=<number of =XX sequences decoded, including those inside encoded words> nonascii=<number of decoded characters with a code point above 127>'.
7. Join the lines with '\n' and return them with no trailing newline.


Submission 41V1UG

import re
from fractions import Fraction

MIXED = re.compile(r"^(\d+)\s+(\d+)/(\d+)\s+(.*)$")
FRACTION = re.compile(r"^(\d+)/(\d+)\s+(.*)$")
DECIMAL = re.compile(r"^(\d+\.\d+|\d+)\s+(.*)$")

def transform(text):
    lines = [ln for ln in text.split("\n") if ln.strip()]
    factor = Fraction(1)
    body = []
    for index, line in enumerate(lines):
        stripped = line.strip()
        if index == 0 and stripped.lower().startswith("scale:"):
            raw = stripped.split(":", 1)[1].strip()
            factor = Fraction(raw) if "/" in raw else Fraction(raw)
            continue
        body.append(stripped)

    def render(value):
        if value.denominator == 1:
            return str(value.numerator)
        whole = value.numerator // value.denominator
        remainder = value - whole
        if whole == 0:
            return "%d/%d" % (remainder.numerator, remainder.denominator)
        return "%d %d/%d" % (whole, remainder.numerator, remainder.denominator)

    out = []
    scaled = 0
    passthrough = 0
    for line in body:
        m = MIXED.match(line)
        if m:
            qty = Fraction(int(m.group(1))) + Fraction(int(m.group(2)), int(m.group(3)))
            rest = m.group(4)
        else:
            m = FRACTION.match(line)
            if m:
                qty = Fraction(int(m.group(1)), int(m.group(2)))
                rest = m.group(3)
            else:
                m = DECIMAL.match(line)
                if m:
                    qty = Fraction(m.group(1))
                    rest = m.group(2)
                else:
                    qty = None
        if qty is None:
            out.append(line)
            passthrough += 1
            continue
        out.append("%s %s" % (render(qty * factor), rest))
        scaled += 1
    out.append("scaled=%d passthrough=%d" % (scaled, passthrough))
    return "\n".join(out)

scale: 3/2
2 1/4 cups flour
1/2 tsp fine salt
3 large eggs
0.75 cup whole milk
1 pinch grated nutmeg
2/3 cup caster sugar
a splash of vanilla
12 blanched almonds
1 1/3 tbsp cold butter

3 3/8 cups flour
3/4 tsp fine salt
4 1/2 large eggs
1 1/8 cup whole milk
1 1/2 pinch grated nutmeg
1 cup caster sugar
a splash of vanilla
18 blanched almonds
2 tbsp cold butter
scaled=8 passthrough=1

Scale a recipe's ingredient quantities.
1. The first non-blank line must be 'scale: <factor>' where the factor is an integer, a decimal number or a fraction like '3/2'. Parse it as an exact rational number.
2. Every following non-blank line is an ingredient line. Strip it, then try to read a leading quantity, which is one of: a mixed number '<int> <int>/<int>', a fraction '<int>/<int>', a decimal number, or a plain integer. The quantity must be followed by whitespace and at least one more character.
3. If a line has no leading quantity, emit it unchanged.
4. Otherwise multiply the quantity by the factor using exact rational arithmetic and re-render it: if the result is a whole number print just that integer; if it is smaller than 1 print the fraction in lowest terms; otherwise print '<whole> <numerator>/<denominator>' in lowest terms. Emit the rendered quantity, a single space, and the rest of the line exactly as it was after the quantity's trailing whitespace.
5. After all ingredient lines, emit 'scaled=<count of lines whose quantity was scaled> passthrough=<count of unchanged lines>'.
6. Join the lines with '\n' and return them with no trailing newline.


Submission 23POT7

from decimal import Decimal, ROUND_HALF_UP

DIGITS = {"black": 0, "brown": 1, "red": 2, "orange": 3, "yellow": 4,
          "green": 5, "blue": 6, "violet": 7, "gray": 8, "white": 9}
MULTIPLIERS = dict((name, Decimal(10) ** value) for name, value in DIGITS.items())
MULTIPLIERS["gold"] = Decimal("0.1")
MULTIPLIERS["silver"] = Decimal("0.01")
TOLERANCES = {"brown": Decimal("1"), "red": Decimal("2"), "green": Decimal("0.5"),
              "blue": Decimal("0.25"), "violet": Decimal("0.1"),
              "gold": Decimal("5"), "silver": Decimal("10")}
UNITS = [("Gohm", Decimal(10) ** 9), ("Mohm", Decimal(10) ** 6),
         ("kohm", Decimal(10) ** 3), ("ohm", Decimal(1))]

def transform(text):
    def trim(value):
        quantized = value.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
        rendered = format(quantized, "f")
        if "." in rendered:
            rendered = rendered.rstrip("0").rstrip(".")
        return rendered or "0"

    out = []
    good = 0
    bad = 0
    for raw in text.split("\n"):
        line = raw.strip()
        if not line:
            continue
        bands = [b.lower().replace("grey", "gray") for b in line.split()]
        if len(bands) == 3:
            digit_bands, multiplier_band, tolerance_band = bands[:2], bands[2], None
        elif len(bands) == 4:
            digit_bands, multiplier_band, tolerance_band = bands[:2], bands[2], bands[3]
        elif len(bands) == 5:
            digit_bands, multiplier_band, tolerance_band = bands[:3], bands[3], bands[4]
        else:
            out.append("%s -> INVALID" % line)
            bad += 1
            continue
        if any(b not in DIGITS for b in digit_bands) or multiplier_band not in MULTIPLIERS \
                or (tolerance_band is not None and tolerance_band not in TOLERANCES):
            out.append("%s -> INVALID" % line)
            bad += 1
            continue
        number = 0
        for band in digit_bands:
            number = number * 10 + DIGITS[band]
        value = Decimal(number) * MULTIPLIERS[multiplier_band]
        tolerance = TOLERANCES[tolerance_band] if tolerance_band else Decimal("20")
        unit_name, unit_size = UNITS[-1]
        for name, size in UNITS:
            if value >= size:
                unit_name, unit_size = name, size
                break
        out.append("%s -> %s %s +/-%s%%" % (
            line, trim(value / unit_size), unit_name, trim(tolerance)))
        good += 1
    out.append("resistors=%d invalid=%d" % (good, bad))
    return "\n".join(out)

brown black red gold
yellow violet orange
green blue black brown
red red red red
orange white brown silver
blue gray gold gold
black brown red
brown grey red gold
brown black black red brown
purple haze orange
red red

brown black red gold -> 1 kohm +/-5%
yellow violet orange -> 47 kohm +/-20%
green blue black brown -> 56 ohm +/-1%
red red red red -> 2.2 kohm +/-2%
orange white brown silver -> 390 ohm +/-10%
blue gray gold gold -> 6.8 ohm +/-5%
black brown red -> 100 ohm +/-20%
brown grey red gold -> 1.8 kohm +/-5%
brown black black red brown -> 10 kohm +/-1%
purple haze orange -> INVALID
red red -> INVALID
resistors=9 invalid=2

Decode resistor colour bands into resistance values.
1. Each non-blank line is one resistor: whitespace-separated colour names, lower-cased before lookup. Accept 'grey' as a spelling of 'gray'.
2. Digit colours are black 0, brown 1, red 2, orange 3, yellow 4, green 5, blue 6, violet 7, gray 8, white 9.
3. Multiplier colours are the same ten colours meaning 10 raised to that digit, plus gold meaning 0.1 and silver meaning 0.01.
4. Tolerance colours are brown 1, red 2, green 0.5, blue 0.25, violet 0.1, gold 5, silver 10.
5. A line of three bands is digit, digit, multiplier with an implied tolerance of 20. A line of four bands adds a tolerance band. A line of five bands is digit, digit, digit, multiplier, tolerance. Any other count, or an unknown colour in any position, makes the line invalid: emit '<the stripped line> -> INVALID'.
6. Compute the resistance exactly with decimal arithmetic: the digits form an integer which is multiplied by the multiplier.
7. Render the value with the largest of 'ohm' (below 1000), 'kohm' (at least 1000), 'Mohm' (at least 1000000) and 'Gohm' (at least 1000000000) that applies. Divide by the unit, then print the number with up to two decimal places, rounding half-up, with trailing zeros and a trailing decimal point removed.
8. Emit '<the stripped line> -> <value> <unit> +/-<tolerance>%' where the tolerance is printed the same way, without trailing zeros.
9. Finally emit 'resistors=<count of decoded lines> invalid=<count of invalid lines>'.
10. Join the lines with '\n' and return them with no trailing newline.


Submission KF4CQ8

import re

PLAN = re.compile(r"^1\.\.(\d+)$")
TEST = re.compile(r"^(not ok|ok)\b\s*(\d+)?\s*(.*)$")

def transform(text):
    plan = None
    tests = []
    for raw in text.split("\n"):
        if not raw.strip():
            continue
        if raw[0].isspace():
            continue
        line = raw.strip()
        if line.lower().startswith("tap version"):
            continue
        if line.startswith("#"):
            continue
        m = PLAN.match(line)
        if m:
            plan = int(m.group(1))
            continue
        m = TEST.match(line)
        if not m:
            continue
        status, _number, rest = m.groups()
        directive = None
        reason = ""
        if "#" in rest:
            body, _, tail = rest.partition("#")
            tail = tail.strip()
            keyword, _, remainder = tail.partition(" ")
            if keyword.upper() in ("SKIP", "TODO"):
                directive = keyword.upper()
                reason = remainder.strip()
                rest = body
        description = rest.strip()
        if description.startswith("- "):
            description = description[2:].strip()
        if directive == "SKIP":
            kind = "skip"
        elif directive == "TODO":
            kind = "todo"
        elif status == "ok":
            kind = "pass"
        else:
            kind = "fail"
        tests.append((kind, description, reason))

    out = []
    for position, (kind, description, _reason) in enumerate(tests, start=1):
        if kind == "fail":
            out.append("FAIL %d %s" % (position, description))
    for position, (kind, description, reason) in enumerate(tests, start=1):
        if kind == "skip":
            out.append("SKIP %d %s (%s)" % (position, description, reason or "no reason"))

    counts = {"pass": 0, "fail": 0, "skip": 0, "todo": 0}
    for kind, _d, _r in tests:
        counts[kind] += 1
    out.append("plan=%s ran=%d pass=%d fail=%d skip=%d todo=%d" % (
        plan if plan is not None else "?", len(tests),
        counts["pass"], counts["fail"], counts["skip"], counts["todo"]))
    good = counts["fail"] == 0 and (plan is None or plan == len(tests))
    out.append("result=%s" % ("PASS" if good else "FAIL"))
    return "\n".join(out)

TAP version 13
1..8
ok 1 - loads configuration
not ok 2 - parses response header
  ---
  message: expected 200 but got 500
  ...
ok 3 - retries transient errors # SKIP network disabled in CI
ok 4 - writes cache entry
not ok 5 - flushes the queue # TODO known flake, see #421
# a bare comment line
ok 6 - closes the socket
not ok 7 - reports metrics
ok 8 - shuts down cleanly # skip requires root

FAIL 2 parses response header
FAIL 7 reports metrics
SKIP 3 retries transient errors (network disabled in CI)
SKIP 8 shuts down cleanly (requires root)
plan=8 ran=8 pass=3 fail=2 skip=2 todo=1
result=FAIL

Summarize a TAP version 13 test stream.
1. Ignore a leading 'TAP version <n>' line. A line matching '1..<n>' is the plan; remember n. Ignore indented lines (they are YAML diagnostics) and lines starting with '#'.
2. Every other non-blank line must start with 'ok' or 'not ok', optionally followed by a test number and then a description that may begin with '- '. Anything else is ignored.
3. A description may carry a trailing directive introduced by an unescaped '#': '# SKIP <reason>' or '# TODO <reason>', with the keyword compared case-insensitively. The description is the text before the '#', stripped.
4. Classify each test: a directive of SKIP makes it 'skip'; a directive of TODO makes it 'todo' regardless of ok or not ok; otherwise 'ok' means 'pass' and 'not ok' means 'fail'.
5. Tests are numbered by their position in the stream starting at 1, ignoring any number written in the line.
6. Emit one line per failing test, in stream order: 'FAIL <position> <description>'. Then one line per skipped test: 'SKIP <position> <description> (<reason or no reason>)'.
7. Then emit 'plan=<n or ?> ran=<count> pass=<count> fail=<count> skip=<count> todo=<count>'.
8. Then emit a final line 'result=PASS' when there are no failures and the plan is either absent or equal to the number of tests run; otherwise 'result=FAIL'.
9. Join the lines with '\n' and return them with no trailing newline.


Submission YE53QO

import json

def transform(text):
    counts = {}
    for line in text.strip().split('\n'):
        record = json.loads(line)
        if record.get('action') == 'login':
            user = record['user']
            counts[user] = counts.get(user, 0) + 1
    return json.dumps(counts)

Parse newline-delimited JSON (NDJSON) records and count how many records have action 'login', grouped by user, returning a JSON object.


Submission K6L6ZC

import json
from urllib.parse import quote

def transform(text):
    params = json.loads(text)
    parts = []
    for key in sorted(params.keys()):
        parts.append(f"{quote(str(key))}={quote(str(params[key]))}")
    return '&'.join(parts)

Convert a JSON object of query parameters into a URL query string, with keys sorted alphabetically and values percent-escaped for spaces.


Submission WZDF7L

import re
import json

def transform(text):
    pattern = r'\(?(\d{3})\)?[.\-\s]?(\d{3})[.\-](\d{4})'
    matches = re.findall(pattern, text)
    normalized = [f"{a}-{b}-{c}" for a, b, c in matches]
    return json.dumps(normalized)

Extract all US-style phone numbers from text (formats with dots, dashes, or parentheses) and normalize each to XXX-XXX-XXXX, returning a JSON array in order found.


Submission W6GC1O

import json

def transform(text):
    result = {}
    for line in text.strip().split('\n'):
        key_part, _, value = line.partition('=')
        keys = [k.strip() for k in key_part.strip().split('.')]
        value = value.strip()
        node = result
        for k in keys[:-1]:
            node = node.setdefault(k, {})
        node[keys[-1]] = value
    return json.dumps(result)

app.debug = true
app.port = 8080
db.host = localhost
db.port = 5432

Parse dotted-key = value config lines into a nested JSON object, splitting each key on '.' to build nested levels.


Submission SHKPQE

def transform(text):
    vowels = "aeiou"
    words = text.strip().split()
    result = []
    for word in words:
        if word[0] in vowels:
            result.append(word + "way")
        else:
            i = 0
            while i < len(word) and word[i] not in vowels:
                i += 1
            result.append(word[i:] + word[:i] + "ay")
    return ' '.join(result)

Translate each space-separated word into Pig Latin: move the leading consonant cluster to the end and append 'ay'; words starting with a vowel just get 'way' appended. Return the words space-joined.


Submission RS9T2E

import json
from collections import Counter

def transform(text):
    words = text.strip().split()
    counts = Counter(words)
    ranked = sorted(counts.items(), key=lambda kv: (-kv[1], kv[0]))
    return json.dumps(ranked[:2])

Find the 2 most frequent words. Break ties by choosing the alphabetically earlier word first. Return a JSON array of [word, count] pairs.


Submission 2GMIXH

import json

def is_balanced(line):
    depth = 0
    for ch in line:
        if ch == '(':
            depth += 1
        elif ch == ')':
            depth -= 1
            if depth < 0:
                return False
    return depth == 0

def transform(text):
    lines = text.split('\n')
    return json.dumps([is_balanced(line) for line in lines])

For each line, determine whether its parentheses are balanced (every '(' has a matching later ')' and never goes negative). Return a JSON array of booleans, one per line.


Submission XFGPK3

import json
import statistics

def transform(text):
    nums = [int(line) for line in text.strip().split('\n')]
    stats = {
        "min": min(nums),
        "max": max(nums),
        "mean": round(statistics.mean(nums), 2),
        "stdev": round(statistics.pstdev(nums), 2)
    }
    return json.dumps(stats)

Compute basic statistics (min, max, mean, and population standard deviation, each rounded to 2 decimals) over the list of integers (one per line), returning a JSON object with keys min, max, mean, stdev.


Submission AXX5O6

def transform(text):
    if not text:
        return ""
    result = []
    prev = text[0]
    count = 1
    for ch in text[1:]:
        if ch == prev:
            count += 1
        else:
            result.append(f"{prev}{count}")
            prev = ch
            count = 1
    result.append(f"{prev}{count}")
    return ''.join(result)

Apply run-length encoding to the text: each maximal run of a repeated character becomes '<char><count>'; a run of length 1 still gets a count of 1.


Submission WS2752

import ipaddress
import json

def transform(text):
    network = ipaddress.ip_network('192.168.1.0/24')
    result = []
    for line in text.strip().split('\n'):
        ip = ipaddress.ip_address(line.strip())
        if ip in network:
            result.append(line.strip())
    return json.dumps(result)

Given a fixed CIDR block of 192.168.1.0/24, determine which of the listed IPv4 addresses (one per line) fall inside it, returning a JSON array of the matching addresses in order.


Submission 4CE8JQ

import re
import json

def transform(text):
    pattern = re.compile(r'^([A-Za-z_][\w.]*(?:Error|Exception|Warning)): (.+)$', re.MULTILINE)
    counts = {}
    examples = {}
    for m in pattern.finditer(text):
        exc_type, msg = m.group(1), m.group(2).strip()
        counts[exc_type] = counts.get(exc_type, 0) + 1
        if exc_type not in examples:
            examples[exc_type] = msg
    result = [
        {'type': t, 'count': c, 'example_message': examples[t]}
        for t, c in counts.items()
    ]
    result.sort(key=lambda x: (-x['count'], x['type']))
    return json.dumps(result, indent=2, ensure_ascii=False)

2026-08-10 10:22:01 ERROR Processing failed
Traceback (most recent call last):
  File "app.py", line 10, in <module>
    main()
  File "app.py", line 5, in main
    raise ValueError("bad input")
ValueError: bad input
2026-08-10 10:22:05 ERROR Processing failed
Traceback (most recent call last):
  File "app.py", line 22, in worker
    process(item)
KeyError: 'missing_field'
2026-08-10 10:23:00 ERROR Processing failed
Traceback (most recent call last):
  File "app.py", line 10, in <module>
    main()
  File "app.py", line 5, in main
    raise ValueError("bad input")
ValueError: bad input

This is an application log containing multiple Python tracebacks. Find every unindented line matching the pattern '<ExceptionType>: <message>' (where ExceptionType ends in Error, Exception, or Warning), and count how many times each exception type occurs, keeping the first message seen for each type as its example_message. Return a JSON array of objects {type, count, example_message} sorted by count descending, then by type name ascending for ties. Serialize with indent=2.


Submission MLH1E4

import json
import re

def transform(text):
    blocks = [b for b in text.strip('\n').split('\n\n') if b.strip()]
    records = []
    for block in blocks:
        lines = [l.strip() for l in block.strip('\n').split('\n')]
        recipient = lines[0]
        street = lines[1]
        city_line = lines[2]
        m = re.match(r'^(.+),\s*([A-Z]{2})\s+(\d+)$', city_line)
        city, state, zip_code = m.group(1), m.group(2), m.group(3)
        zip_valid = len(zip_code) == 5
        records.append({
            'recipient': recipient,
            'street': street,
            'city': city,
            'state': state,
            'zip': zip_code,
            'zip_valid': zip_valid
        })
    return json.dumps(records, indent=2, ensure_ascii=False)

John Carter
482 Elm Street
Springfield, IL 62704

Maria Gomez
19 Rue de Paris
Paris, TX 75460

Wei Zhang
1200 5th Ave Apt 3B
New York, NY 1001

Tom Baker
77 Ocean Drive
Miami, FL 33139

This text contains shipping address blocks separated by blank lines. Each block has exactly 3 lines: recipient name, street address, and 'City, ST ZIP'. Parse each block into a record with keys recipient, street, city, state, zip, and zip_valid (true only if the zip is exactly 5 digits). Return a JSON array of these records serialized with indent=2, in original order.


Submission O3070B

def roman_to_int(s):
    vals = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
    total = 0
    prev = 0
    for ch in reversed(s):
        v = vals[ch]
        if v < prev:
            total -= v
        else:
            total += v
            prev = v
    return total

def transform(text):
    lines = [l for l in text.strip('\n').split('\n') if l.strip()]
    header = lines[0]
    out = [header + ',quantity']
    for line in lines[1:]:
        item, roman = line.split(',')
        qty = roman_to_int(roman.strip())
        out.append(f'{item},{roman},{qty}')
    return '\n'.join(out)

item,quantity_roman
Widget,XIV
Gadget,IX
Gizmo,XL
Sprocket,IV
Doohickey,MCMXCIX

item,quantity_roman,quantity
Widget,XIV,14
Gadget,IX,9
Gizmo,XL,40
Sprocket,IV,4
Doohickey,MCMXCIX,1999

This CSV has an 'item' column and a 'quantity_roman' column containing Roman numerals. Convert each Roman numeral to its integer value and append it as a new 'quantity' column. Return the result as CSV text (comma-separated, newline-joined, no trailing newline), keeping the original columns and appending the new one.


Submission UJ7SDU

import json

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

    def walk(node, depth):
        lines.append('  ' * depth + f"[{node['score']}] {node['author']}: {node['text']}")
        children = sorted(node.get('replies', []), key=lambda c: -c['score'])
        for child in children:
            walk(child, depth + 1)

    walk(data, 0)
    return '\n'.join(lines)

Great post!

I agree completely.

Same here.

Not sure about this.

[15] alice: Great post!
  [42] bob: I agree completely.
    [3] carol: Same here.
  [7] dave: Not sure about this.

This is a JSON comment tree where each node has id, author, score, text, and a 'replies' list of child nodes. Flatten the tree into indented text lines: at every level, sort sibling nodes by score descending, and render each node as '<indent>[score] author: text' where indent is two spaces per depth level (root is depth 0). Depth-first traverse in that sorted order. Return all lines newline-joined.


Submission NI7I5L

import json

def parse_value(v):
    v = v.strip()
    if v.lower() == 'true':
        return True
    if v.lower() == 'false':
        return False
    try:
        return int(v)
    except ValueError:
        pass
    try:
        return float(v)
    except ValueError:
        pass
    return v

def transform(text):
    sections = {}
    order = []
    current = None
    for line in text.strip('\n').split('\n'):
        line = line.strip()
        if not line:
            continue
        if line.startswith('[') and line.endswith(']'):
            current = line[1:-1]
            sections[current] = {}
            order.append(current)
        elif '=' in line and current:
            key, val = line.split('=', 1)
            sections[current][key.strip()] = parse_value(val)

    resolved = {}

    def resolve(name):
        if name in resolved:
            return resolved[name]
        raw = dict(sections[name])
        parent_name = raw.pop('extends', None)
        if parent_name:
            merged = dict(resolve(parent_name))
            merged.update(raw)
        else:
            merged = raw
        resolved[name] = merged
        return merged

    output = {name: resolve(name) for name in order}
    return json.dumps(output, indent=2, ensure_ascii=False)

[base]
timeout = 30
retries = 3
env = production

[service_a]
extends = base
timeout = 10

[service_b]
extends = service_a
retries = 5
debug = true

This is an INI-like config with sections that may declare 'extends = <parent_section>' to inherit key/value pairs from another section, with the child's own keys overriding the parent's (recursively resolved, since a parent may itself extend another section). The 'extends' key must not appear in the final output. Convert values: 'true'/'false' (case-insensitive) to booleans, integer-looking strings to ints, float-looking strings to floats, otherwise leave as strings. Return a JSON object mapping each section name to its fully resolved key/value dict, in original section order, serialized with indent=2.


Submission ZIMABD

import re
import json

def parse_logfmt(line):
    pairs = re.findall(r'(\w+)=("[^"]*"|\S+)', line)
    result = {}
    for k, v in pairs:
        if v.startswith('"') and v.endswith('"'):
            v = v[1:-1]
        result[k] = v
    return result

def transform(text):
    lines = [l for l in text.strip('\n').split('\n') if l.strip()]
    groups = {}
    for line in lines:
        fields = parse_logfmt(line)
        level = fields.get('level', 'unknown')
        duration = float(fields.get('duration', 0))
        groups.setdefault(level, []).append(duration)
    result = {}
    for level, durations in groups.items():
        result[level] = {
            'count': len(durations),
            'avg_duration': round(sum(durations) / len(durations), 2)
        }
    return json.dumps(result, indent=2, ensure_ascii=False)

time=2026-08-10T10:00:00 level=info msg="request handled" duration=120
time=2026-08-10T10:00:05 level=error msg="db timeout" duration=5000
time=2026-08-10T10:00:07 level=info msg="request handled" duration=95
time=2026-08-10T10:00:09 level=warn msg="slow response" duration=800
time=2026-08-10T10:00:12 level=error msg="db timeout" duration=4900
time=2026-08-10T10:00:15 level=info msg="request handled" duration=110

Each line is logfmt-style text with space-separated key=value pairs, where values may be double-quoted strings containing spaces. Parse the 'level' and 'duration' fields from each line, group lines by level, and compute count and average duration (rounded to 2 decimals) per level. Return a JSON object mapping level to {count, avg_duration}, serialized with indent=2, in order of first appearance.


Submission SVSMT0

import json

def transform(text):
    lines = text.strip('\n').split('\n')
    request_line = lines[0].strip()
    parts = request_line.split(' ')
    method, path = parts[0], parts[1]
    protocol = parts[2] if len(parts) > 2 else ''
    headers = {}
    for line in lines[1:]:
        line = line.rstrip('\r')
        if not line.strip() or ':' not in line:
            continue
        key, val = line.split(':', 1)
        key = key.strip().lower()
        values = [v.strip() for v in val.split(',') if v.strip()]
        if key in headers:
            for v in values:
                if v not in headers[key]:
                    headers[key].append(v)
        else:
            headers[key] = values
    for k in list(headers.keys()):
        if len(headers[k]) == 1:
            headers[k] = headers[k][0]
    result = {
        'method': method,
        'path': path,
        'protocol': protocol,
        'headers': headers
    }
    return json.dumps(result, indent=2, ensure_ascii=False)

GET /api/users?active=true HTTP/1.1
Host: api.example.com
Accept: application/json, text/html
X-Forwarded-For: 10.0.0.1, 10.0.0.2, 10.0.0.3
User-Agent: curl/7.68.0
Cache-Control: no-cache
Accept: */*

Parse this raw HTTP request text. The first line is the request line 'METHOD PATH PROTOCOL'. The remaining lines are 'Header-Name: value' pairs. Lower-case every header name. Split each header's value on commas into a list of trimmed values; if a header name repeats, merge and deduplicate its value lists in order of first appearance. After merging, any header whose final list has exactly one value should be stored as a plain string rather than a single-element list; headers with multiple values remain lists. Return JSON {method, path, protocol, headers} serialized with indent=2.


Submission 6NLC1C

import json
import math

def transform(text):
    parts = text.split('---')
    frontmatter_raw = parts[1].strip('\n')
    body = '---'.join(parts[2:]).strip('\n')
    metadata = {}
    for line in frontmatter_raw.splitlines():
        if ':' not in line:
            continue
        key, val = line.split(':', 1)
        key = key.strip()
        val = val.strip()
        if key == 'tags':
            metadata[key] = [t.strip() for t in val.split(',') if t.strip()]
        elif val.lower() in ('true', 'false'):
            metadata[key] = val.lower() == 'true'
        else:
            metadata[key] = val
    words = body.split()
    word_count = len(words)
    reading_time = max(1, math.ceil(word_count / 200))
    result = {
        'metadata': metadata,
        'word_count': word_count,
        'reading_time_minutes': reading_time
    }
    return json.dumps(result, indent=2, ensure_ascii=False)

---
title: Getting Started
author: Jane Doe
tags: python, tutorial, beginner
published: true
---
# Getting Started

This is a short guide to get you started with the tool.
It covers installation and basic usage in a few short paragraphs.

## Installation

Run pip install tool to install.

Getting Started

This is a markdown document with a YAML-like frontmatter block delimited by '---' lines, followed by a body. Parse the frontmatter into a metadata dict: split the 'tags' value on commas into a list of trimmed strings; convert 'true'/'false' values (case-insensitive) to booleans; leave other values as strings. Count the number of whitespace-separated tokens in the body (everything after the closing '---') as word_count. Compute reading_time_minutes as ceil(word_count / 200), minimum 1. Return JSON {metadata, word_count, reading_time_minutes} serialized with indent=2.


Submission OVBDKQ

import re
import json

def transform(text):
    blocks = text.strip().split('BEGIN:VCARD')
    contacts = []
    for block in blocks:
        block = block.strip()
        if not block:
            continue
        block = block.replace('END:VCARD', '').strip()
        fields = {}
        for line in block.splitlines():
            line = line.strip()
            if not line or ':' not in line:
                continue
            key, val = line.split(':', 1)
            fields[key.strip().upper()] = val.strip()
        name = fields.get('FN', '')
        tel_raw = fields.get('TEL', '')
        digits = re.sub(r'\D', '', tel_raw)
        if tel_raw.strip().startswith('+'):
            phone = '+' + digits
        elif len(digits) == 10:
            phone = '+1' + digits
        elif len(digits) == 11 and digits.startswith('1'):
            phone = '+' + digits
        else:
            phone = digits
        email = fields.get('EMAIL', '').lower()
        org = fields.get('ORG')
        contacts.append({
            'name': name,
            'phone': phone,
            'email': email,
            'org': org
        })
    return json.dumps(contacts, indent=2, ensure_ascii=False)

BEGIN:VCARD
FN:John Smith
TEL:(555) 123-4567
EMAIL:John.Smith@EXAMPLE.com
ORG:Acme Corp
END:VCARD
BEGIN:VCARD
FN:Maria Garcia
TEL:+34 91 123 4567
EMAIL:maria@example.org
END:VCARD
BEGIN:VCARD
FN:Bob Lee
TEL:1-800-555-0199
EMAIL:BOB@TEST.COM
ORG:Widgets Inc
END:VCARD

Parse this text containing multiple BEGIN:VCARD/END:VCARD blocks into a JSON array of contact objects with keys name, phone, email, org. Normalize each phone number to E.164 format: strip all non-digit characters; if the original number already starts with '+', keep it as '+' followed by the digits; if the digits are exactly 10 long, prefix with '+1'; if 11 digits and starting with '1', prefix with '+'; otherwise keep the raw digits. Lowercase the email. If ORG is missing for a contact, its value should be null. Return the JSON serialized with indent=2.


Submission 6FKQRT

def transform(text):
    lines = [l for l in text.strip('\n').split('\n') if l.strip()]
    out = ['os\tbrowser\tversion']
    for ua in lines:
        if 'Windows' in ua:
            os_name = 'Windows'
        elif 'iPhone' in ua:
            os_name = 'iOS'
        elif 'Macintosh' in ua or 'Mac OS X' in ua:
            os_name = 'macOS'
        elif 'Linux' in ua:
            os_name = 'Linux'
        else:
            os_name = 'Unknown'

        if 'Chrome/' in ua:
            browser = 'Chrome'
            version = ua.split('Chrome/')[1].split(' ')[0]
        elif 'Version/' in ua and 'Safari' in ua:
            browser = 'Safari'
            version = ua.split('Version/')[1].split(' ')[0]
        elif ua.startswith('curl/'):
            browser = 'curl'
            version = ua.split('curl/')[1].split(' ')[0]
        else:
            browser = 'Unknown'
            version = ''
        out.append(f'{os_name}\t{browser}\t{version}')
    return '\n'.join(out)

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36
Mozilla/5.0 (Macintosh; Intel Mac OS X 13_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Safari/605.1.15
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0 Safari/537.36
Mozilla/5.0 (iPhone; CPU iPhone OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Mobile/15E148 Safari/604.1
curl/7.68.0

os	browser	version
Windows	Chrome	115.0.0.0
macOS	Safari	16.5
Linux	Chrome	114.0
iOS	Safari	16.5
Unknown	curl	7.68.0

Parse each User-Agent line into an operating system and browser with version, using these rules in order: OS is 'Windows' if the string contains 'Windows'; else 'iOS' if it contains 'iPhone'; else 'macOS' if it contains 'Macintosh' or 'Mac OS X'; else 'Linux' if it contains 'Linux'; else 'Unknown'. Browser: 'Chrome' with the version following 'Chrome/' if present; else 'Safari' with the version following 'Version/' if the string also contains 'Safari'; else 'curl' with version following 'curl/' if the line starts with 'curl/'; else 'Unknown' with empty version. Output tab-separated text with header 'os\tbrowser\tversion', one row per input line, newline-joined.


Submission XP7S2O

import json

def transform(text):
    lines = text.strip('\n').split('\n')
    rows = []
    warnings = 0
    for line in lines[1:]:
        cols = line.split('\t')
        sku, location, stock = cols[0], cols[1], int(cols[2])
        if stock < 0:
            stock = 0
            warnings += 1
        rows.append({'sku': sku, 'location': location, 'stock': stock})
    result = {'corrected_rows': rows, 'warnings': warnings}
    return json.dumps(result, indent=2, ensure_ascii=False)

sku	location	stock
A1	WH1	50
A2	WH1	-5
A3	WH2	12
A2	WH2	-20
A4	WH1	0

This is tab-separated inventory data with header 'sku\tlocation\tstock'. Some stock values are negative due to a data error; clamp any negative stock to 0 and count how many rows were clamped as 'warnings'. Return JSON {corrected_rows: [{sku, location, stock}, ...], warnings: <int>} serialized with indent=2, preserving row order.


Submission 0D5LIW

import json

def transform(text):
    out = ['order_id,customer,sku,qty,price,line_total']
    for line in text.strip('\n').split('\n'):
        if not line.strip():
            continue
        order = json.loads(line)
        items = order.get('items', [])
        if not items:
            out.append(f"{order['order_id']},{order['customer']},,0,0.00,0.00")
        else:
            for item in items:
                qty = item['qty']
                price = item['price']
                line_total = qty * price
                out.append(f"{order['order_id']},{order['customer']},{item['sku']},{qty},{price:.2f},{line_total:.2f}")
    return '\n'.join(out)

Each line is a JSON order object with an 'items' array of {sku, qty, price}. Flatten this into a CSV with header 'order_id,customer,sku,qty,price,line_total' with one row per item, where line_total = qty * price formatted to 2 decimal places (price also formatted to 2 decimals). If an order's items list is empty, emit a single row for that order with sku empty and qty=0, price=0.00, line_total=0.00. Return the CSV text (newline-joined, no trailing newline).


Submission NHT6AF

def transform(text):
    lines = [l for l in text.strip('\n').split('\n') if l.strip()]
    header = [h.strip() for h in lines[0].split(',')]
    seen = {}
    order = []
    for line in lines[1:]:
        cols = [c.strip() for c in line.split(',')]
        name, email, city = cols[0], cols[1], cols[2]
        key = (name.lower(), email.lower())
        if key not in seen:
            seen[key] = [name, email.lower(), city]
            order.append(key)
    out_lines = [','.join(header)]
    for key in order:
        out_lines.append(','.join(seen[key]))
    return '\n'.join(out_lines)

Name , Email ,City
 Alice Wong ,alice@example.com , Seattle
Bob Chen,BOB@EXAMPLE.COM,Portland
alice wong , ALICE@EXAMPLE.COM ,seattle
Carol Diaz,carol@example.com,Denver
BOB CHEN, bob@example.com ,Portland

Name,Email,City
Alice Wong,alice@example.com,Seattle
Bob Chen,bob@example.com,Portland
Carol Diaz,carol@example.com,Denver

This CSV has inconsistent whitespace and duplicate rows that only differ by case. Trim whitespace from every field. Treat two rows as duplicates if their name and email match case-insensitively after trimming; keep only the first occurrence of each unique (name, email) pair, in original order. In the kept rows, lower-case the email but keep the original casing of name and city as first seen. Return the result as CSV text (comma-separated, newline-joined, no trailing newline, same header trimmed).


Submission 5EYKL6

import json
import re

def transform(text):
    lines = [l for l in text.strip('\n').split('\n') if l.strip()]
    totals = {}
    for line in lines[1:]:
        desc, amount = line.split(',', 1)
        m = re.match(r'^([^\d.]+)([\d.]+)$', amount.strip())
        symbol, value = m.group(1), float(m.group(2))
        totals[symbol] = round(totals.get(symbol, 0) + value, 2)
    return json.dumps(totals, indent=2, ensure_ascii=False)

description,amount
Coffee,$4.50
Book,€12.99
Lunch,$8.25
Museum,€7.00
Taxi,£15.00
Snack,$2.10
Gift,£3.50

This CSV has a description column and an amount column where amounts are prefixed with a currency symbol ($, €, or £) and no thousands separators. Sum the numeric amounts grouped by currency symbol, rounding each running total to 2 decimals. Return a JSON object mapping each currency symbol to its total, serialized with indent=2.


Submission Q99CCI

import json

def parse_semver(v):
    core = v
    build = None
    if '+' in core:
        core, build = core.split('+', 1)
    prerelease = None
    if '-' in core:
        core, prerelease = core.split('-', 1)
    major, minor, patch = (int(x) for x in core.split('.'))
    return major, minor, patch, prerelease, build

def sort_key(v):
    major, minor, patch, prerelease, build = parse_semver(v)
    pre_flag = 1 if prerelease is None else 0
    pre_parts = []
    if prerelease:
        for part in prerelease.split('.'):
            if part.isdigit():
                pre_parts.append((0, int(part)))
            else:
                pre_parts.append((1, part))
    return (major, minor, patch, pre_flag, pre_parts, v)

def transform(text):
    versions = [l.strip() for l in text.strip('\n').split('\n') if l.strip()]
    unique = list(dict.fromkeys(versions))
    unique.sort(key=sort_key)
    return json.dumps(unique, indent=2, ensure_ascii=False)

This is a list of semantic version strings (major.minor.patch[-prerelease][+build]), one per line, with exact duplicates and mixed pre-release/build metadata. Remove exact duplicate lines (keeping first occurrence order irrelevant since we re-sort), then sort all unique versions by semver precedence rules: compare major, minor, patch numerically; a version with a pre-release has lower precedence than the same version without one; pre-release identifiers are compared dot-segment by dot-segment, numeric segments compared numerically and sorting before any non-numeric segment types when compared cross-type is not needed here; build metadata is ignored for precedence but if two versions have identical precedence, break the tie by comparing the full original string lexicographically ascending. Return the sorted unique list as a JSON array serialized with indent=2.


Submission 9F5YQ5

import json

FLAGS = [(1, 'READ'), (2, 'WRITE'), (4, 'DELETE'), (8, 'ADMIN')]

def transform(text):
    lines = [l for l in text.strip('\n').split('\n') if l.strip()]
    result = []
    for line in lines[1:]:
        user, mask = line.split(',')
        mask = int(mask)
        flags = [name for bit, name in FLAGS if mask & bit]
        result.append({'user': user, 'mask': mask, 'flags': flags})
    return json.dumps(result, indent=2, ensure_ascii=False)

user,permissions_mask
alice,7
bob,1
carol,15
dave,0
erin,10

This CSV has a user and a permissions_mask (integer bitmask) column. Bit 1 = READ, bit 2 = WRITE, bit 4 = DELETE, bit 8 = ADMIN. Decode each mask into the list of flag names whose bits are set (empty list if mask is 0). Return a JSON array of objects {user, mask, flags} in original order, serialized with indent=2.


Submission VGW1GX

Each line is Morse code where letters within a word are separated by single spaces and words are separated by ' / '. Decode each line to uppercase plain text (words separated by a single space) and return all decoded lines newline-joined, in original order.


Submission YXLYL9

import unicodedata
import re
import json

def slugify(s):
    s = unicodedata.normalize('NFKD', s).encode('ascii', 'ignore').decode('ascii')
    s = s.lower()
    s = re.sub(r'[^a-z0-9\s-]', '', s)
    s = re.sub(r'[\s-]+', '-', s).strip('-')
    return s

def transform(text):
    titles = [l for l in text.strip('\n').split('\n') if l.strip()]
    result = [{'title': t, 'slug': slugify(t)} for t in titles]
    return json.dumps(result, indent=2, ensure_ascii=False)

Café Del Mar: A Sunset Story!
10 Tips & Tricks for Beginners
Résumé Writing 101
C++ Programming — The Basics
Hello, World?? (2024 Edition)

Café Del Mar: A Sunset Story!

10 Tips & Tricks for Beginners

Résumé Writing 101

C++ Programming — The Basics

Hello, World?? (2024 Edition)

For each title line, generate a URL slug: transliterate accented/unicode characters to their closest ASCII equivalent (using NFKD normalization and dropping non-encodable characters), lower-case the result, remove any character that isn't a lowercase letter, digit, whitespace, or hyphen, then collapse any run of whitespace/hyphens into a single hyphen and strip leading/trailing hyphens. Return a JSON array of objects {title, slug} in original order, serialized with indent=2.