CODE-0002 · claude-opus-4-8 (max)Both files are written to `/workspace/.repos/yardstick/runs/bench-opus48-max/outbox/CODE-0002/`. The solution passes a hand-written suite (~50 valid, ~45 invalid) and a 200,000-string differential fuzz test against the official semver.org reference regex with zero mismatches. The requested output file is `solution.py`; per the instructions I return its complete raw content below.
"""Parse a Semantic Versioning 2.0.0 version string.
Implements ``parse_semver(s)`` using only the Python standard library.
"""
import re
# A non-negative integer with no leading zeros: "0" or a non-zero digit
# followed by any digits.
_NUM = r"0|[1-9]\d*"
# A single dot-separated prerelease identifier. SemVer 2.0.0 allows two kinds:
# - a numeric identifier: all digits, with no leading zeros ("0" or [1-9]\d*).
# - an alphanumeric identifier: one or more of [0-9A-Za-z-] that contains at
# least one non-digit ([A-Za-z-]); leading zeros are permitted for these.
# The alphanumeric alternative is written so it cannot also match a pure-digit
# string, which keeps the numeric-identifier leading-zero rule authoritative.
_PRERELEASE_IDENT = r"(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*)"
_PRERELEASE = rf"{_PRERELEASE_IDENT}(?:\.{_PRERELEASE_IDENT})*"
# A single dot-separated build identifier: one or more of [0-9A-Za-z-], with no
# extra constraints (leading zeros are allowed in build metadata).
_BUILD_IDENT = r"[0-9A-Za-z-]+"
_BUILD = rf"{_BUILD_IDENT}(?:\.{_BUILD_IDENT})*"
# Full SemVer grammar. Anchored via fullmatch below.
_SEMVER_RE = re.compile(
rf"(?P<major>{_NUM})"
rf"\.(?P<minor>{_NUM})"
rf"\.(?P<patch>{_NUM})"
rf"(?:-(?P<prerelease>{_PRERELEASE}))?"
rf"(?:\+(?P<build>{_BUILD}))?"
)
def parse_semver(s):
"""Parse a SemVer 2.0.0 version string.
Returns a dict with keys ``major``, ``minor``, ``patch`` (ints),
``prerelease`` (str or None) and ``build`` (str or None) on success, or
``None`` if ``s`` is not a string or is not a valid SemVer version.
"""
if not isinstance(s, str):
return None
match = _SEMVER_RE.fullmatch(s)
if match is None:
return None
return {
"major": int(match.group("major")),
"minor": int(match.group("minor")),
"patch": int(match.group("patch")),
"prerelease": match.group("prerelease"),
"build": match.group("build"),
}