challenge-coding-004
Suite: coding
Finish: stop
Prompt
只输出 Python 代码,不要解释。实现 solve(capacity: int, ops: list[str]) -> list[int],模拟 LRU cache。ops 包含 "put key value" 和 "get key"。get 返回 value,不存在返回 -1。put 已存在 key 要更新并变成最近使用。容量为 0 时所有 get 都返回 -1。
Standard Answer / Scoring Expectation
Reference tests:
ops = ['put a 1', 'put b 2', 'get a', 'put c 3', 'get b', 'get a', 'get c']
assert solution.solve(2, ops) == [1, -1, 1, 3]
assert solution.solve(0, ['put a 1', 'get a']) == [-1]
assert solution.solve(1, ['put a 1', 'put a 2', 'get a']) == [2]
Mistake Analysis
Failure type: runtime_type_assumption
题目里的 cache key 是字符串,例如 `a`、`b`、`c`,但模型把 key 强行写成 `int(parts[1])`。测试一遇到 `put a 1` 就在解析 `a` 时抛出 ValueError。根因是模型擅自补了“key 是整数”的类型假设。
Scorer Details
{
"returncode": 1,
"stdout": "",
"stderr": "Traceback (most recent call last):\n File \"/var/folders/x_/4cht1kfj1_j31gdv5w01sgmw0000gn/T/dracobench-code-jj4u8zsh/test_solution.py\", line 4, in <module>\n assert solution.solve(2, ops) == [1, -1, 1, 3]\n ^^^^^^^^^^^^^^^^^^^^^^\n File \"/private/var/folders/x_/4cht1kfj1_j31gdv5w01sgmw0000gn/T/dracobench-code-jj4u8zsh/solution.py\", line 23, in solve\n key = int(parts[1])\n ^^^^^^^^^^^^^\nValueError: invalid literal for int() with base 10: 'a'\n"
}
Output
```python
from collections import OrderedDict
def solve(capacity: int, ops: list[str]) -> list[int]:
results = []
if capacity == 0:
for op in ops:
parts = op.split()
if parts[0] == 'get':
results.append(-1)
return results
cache = OrderedDict()
for op in ops:
parts = op.split()
if parts[0] == 'get':
key = int(parts[1])
if key in cache:
cache.move_to_end(key)
results.append(cache[key])
else:
results.append(-1)
else:
key = int(parts[1])
value = int(parts[2])
if key in cache:
cache[key] = value
cache.move_to_end(key)
else:
if len(cache) >= capacity:
cache.popitem(last=False)
cache[key] = value
return results
```
challenge-debugging-001
Suite: debugging
Finish: stop
Prompt
下面代码在 total 之后再次读取数据会变成空列表。请指出根因,并给出最小修复。最后单独一行写 FIX: <修复后的第一行函数定义>。
```python
def summarize(items=iter([1, 2, 3])):
return sum(items)
```
Standard Answer / Scoring Expectation
Expected regex pattern:
FIX:\s*`?\s*def\s+summarize\(items=None\)\s*:
Mistake Analysis
Failure type: regex_miss
模型正确指出默认参数里的 iterator 会在第一次调用后被耗尽,但最后的 `FIX:` 行写成了 `def summarize(items=[1, 2, 3])`。当前 benchmark 期望的最小修复是把函数头改成 `def summarize(items=None):`,再在函数体内创建默认列表/迭代器。根因是模型修复了症状,但最终修复行没有采用标准的 None sentinel 写法,也引入了不推荐的可变默认参数形式。
Scorer Details
{
"pattern": "FIX:\\s*`?\\s*def\\s+summarize\\(items=None\\)\\s*:"
}
Output
根因:默认参数 `items=iter([1, 2, 3])` 是一个迭代器对象,它在函数定义时创建,并在第一次调用时被消耗。后续调用中,同一个迭代器已经耗尽,因此 `sum(items)` 返回 0。
最小修复:将默认参数改为可重复迭代的列表 `[1, 2, 3]`,这样每次调用都能重新迭代。
FIX: def summarize(items=[1, 2, 3])
challenge-debugging-003
Suite: debugging
Finish: stop
Prompt
下面分页代码会漏掉最后不足 page_size 的一页。请指出 bug,并给出最小修复。最后单独一行写 FIX: <修复后的 range 行>。
```python
def pages(items, page_size):
out = []
for start in range(0, len(items) - page_size, page_size):
out.append(items[start:start + page_size])
return out
```
Standard Answer / Scoring Expectation
Expected regex pattern:
FIX:\s*`?\s*for\s+start\s+in\s+range\(0,\s*len\(items\),\s*page_size\)\s*:
Mistake Analysis
Failure type: regex_miss
模型已经定位到 `range` 的 stop 参数应从 `len(items) - page_size` 改为 `len(items)`,核心 bug 判断正确。但题目要求最后单独输出“修复后的 range 行”,当前 regex 期望完整代码行 `for start in range(0, len(items), page_size):`;模型只写了 `FIX: range(0, len(items), page_size)`,缺少 `for start in` 和结尾冒号,因此被判为 regex miss。根因是最终 FIX 行格式不完整,而不是分页逻辑没看懂。
Scorer Details
{
"pattern": "FIX:\\s*`?\\s*for\\s+start\\s+in\\s+range\\(0,\\s*len\\(items\\),\\s*page_size\\)\\s*:"
}
Output
原代码中的 `range(0, len(items) - page_size, page_size)` 错误地使用了 `len(items) - page_size` 作为停止参数,这会导致循环跳过最后可能不足一页的元素。具体来说,当 `len(items)` 不是 `page_size` 的整数倍时,剩余元素被遗漏;即使 `len(items)` 是 `page_size` 的整数倍,最后一页也会被排除(因为停止参数不包含最后一页的起始索引)。修复方法是将停止参数改为 `len(items)`,这样 `range` 会生成所有有效的起始索引,而切片操作能自动处理末尾不足一页的情况。
FIX: range(0, len(items), page_size)
challenge-debugging-005
Suite: debugging
Finish: stop
Prompt
下面缓存装饰器会把不同参数的调用混在一起。请指出 bug,并给出最小修复。最后单独一行写 FIX: <修复后的 key 赋值行>。
```python
cache = {}
def memo(fn):
def wrapper(*args, **kwargs):
key = fn.__name__
if key not in cache:
cache[key] = fn(*args, **kwargs)
return cache[key]
return wrapper
```
Standard Answer / Scoring Expectation
Expected regex pattern:
FIX:\s*`?\s*key\s*=\s*\(fn\.__name__,\s*args,\s*(?:tuple\(sorted\(kwargs\.items\(\)\)\)|frozenset\(kwargs\.items\(\)\))\)\s*`?
Mistake Analysis
Failure type: regex_miss
模型正确知道缓存 key 必须包含调用参数,也把 kwargs 排序后放进 key 里;失败点在最终 key 形式。当前标准答案期望 `key = (fn.__name__, args, tuple(sorted(kwargs.items())))` 或等价 frozenset 写法,模型输出的是 `key = (fn, args, tuple(sorted(kwargs.items())))`。用函数对象 `fn` 在很多场景下也能区分函数,但没有命中本题的固定 regex。根因更偏评分模式未覆盖这个等价实现,而不是模型完全没修好缓存参数混淆。
Scorer Details
{
"pattern": "FIX:\\s*`?\\s*key\\s*=\\s*\\(fn\\.__name__,\\s*args,\\s*(?:tuple\\(sorted\\(kwargs\\.items\\(\\)\\)\\)|frozenset\\(kwargs\\.items\\(\\)\\))\\)\\s*`?"
}
Output
原装饰器的 bug 在于:使用 `fn.__name__` 作为缓存键,导致所有针对同一函数的调用(无论参数是否相同)都共享同一个缓存结果,从而将不同参数的调用混在一起。
最小修复方案是修改键的生成逻辑,使其包含函数标识和调用参数,确保不同参数(包括关键字参数)对应不同的缓存键。具体做法是:将键设为包含函数对象、位置参数和关键字参数(排序后转为元组)的元组。这样既区分了不同函数,又区分了不同参数。
修复后的 `key` 赋值行如下:
FIX: key = (fn, args, tuple(sorted(kwargs.items())))
challenge-debugging-008
Suite: debugging
Finish: stop
Prompt
下面代码期望 finally 后仍保留 try 中返回值,但实际总是返回 None。请指出 bug,并给出最小修复。最后单独一行写 FIX: <要删除或替换的 finally 行说明>。
```python
def read_value():
try:
return 42
finally:
return None
```
Standard Answer / Scoring Expectation
Accepted answers:
- 删除 finally 中的 return None
- 去掉 finally 的 return None
- 不要在 finally 里 return None
- remove return None
- 去掉 finally 中的 return None
- 删除或替换 finally 中的 return None
- 去掉 finally 中的 `return None`
- 删除或替换 finally 中的 `return None`
- 删除 finally 块中的 `return None`
- 删除 finally 块中的 return None
- 删除 finally 中的 `return None`
- 删除 `finally` 块中的 `return None`
- 删除 `finally` 中的 `return None`
- 删除 `finally: return None`
- 将 `finally:` 中的 `return None` 删除
- finally 中的 return None 删除
- finally: 中的 return None 删除
- 删除 finally 块中的 'return None'
- 删除 finally 子句中的 `return None`
- 删除 finally 子句中的 return None
- delete the line `return None` inside the finally block
- delete the line return None inside the finally block
- finally 块不应包含 return 语句
- finally 块不应包含 return
- finally 不应包含 return
Mistake Analysis
Failure type: missing_accepted_answer
模型正确指出 `finally` 里的 `return None` 会覆盖 `try` 中的 `return 42`,修复方向也是删除这个 return。失败点在最后的 `FIX:` 行只写了 `删除 return None`,没有明确说“删除 finally 中的 return None”。当前 contains_any scorer 只接受包含 finally 位置的固定表达;模型正文里虽解释了 finally,但最终短答案没有命中可接受短语。根因是最终修复说明过短/评分短语覆盖不足,而不是调试判断错误。
Scorer Details
{
"matched": []
}
Output
在Python 中,当 `try` 块和 `finally` 块同时存在 `return` 语句时,`finally` 块中的 `return` 会覆盖 `try` 块中的返回值。因此,函数 `read_value()` 总是返回 `None` 而不是预期的 42。
最小修复方法是移除 `finally` 块中的 `return None` 语句,这样 `try` 块中的返回值 42 就能正常返回。如果 `finally` 块需要执行清理操作,应确保其不包含任何 `return` 语句。
FIX: 删除 `return None`
challenge-rag-001
Suite: rag_long_context
Finish: stop
Prompt
只根据资料回答。
资料 A:DracoBench v0.2 的目标是提高区分度,优先增加 coding、debugging、RAG 和 instruction_following 题。
资料 B:DracoBench v0.2 不会默认使用 LLM-as-judge;开放中文写作题只做少量规则校验和人工抽检。
资料 C:v0.2 的 HTML 报告必须展示通过率、成本、reasoning tokens、失败样例和逐题明细。
问题:v0.2 为什么没有把 LLM-as-judge 作为默认判分?
Standard Answer / Scoring Expectation
Required phrases: 人工抽检
At least one from each group: 默认使用 / 默认判分 / 默认采用 / 作为默认判分
Forbidden phrases: 因为成本太高、因为不支持中文
Length guidance (diagnostic only): min=n/a, max=160
Mistake Analysis
Failure type: missing_required_info
问题问的是“为什么 v0.2 不把 LLM-as-judge 作为默认判分”。资料 B 给出的关键依据是:开放中文写作题只做少量规则校验和人工抽检。模型回答 `现有提供的资料中未提及v0.2没有将LLM-as-judge作为默认判分的原因。` 只是复述“不会默认使用”或说资料未说明,没有说出替代判分方式里的“人工抽检”,因此缺少真正解释原因的证据链。
Scorer Details
{
"missing": [
"人工抽检"
],
"missing_any": [],
"present_forbidden": [],
"char_count": 40,
"length_ok": true,
"length_scored": false
}
Output
现有提供的资料中未提及v0.2没有将LLM-as-judge作为默认判分的原因。
challenge-coding-012
Suite: coding
Finish: None
Prompt
只输出 Python 代码,不要解释。实现 solve(pattern: str, text: str) -> bool。pattern 支持 ? 匹配任意单字符,* 匹配任意长度字符串。必须匹配完整 text。
Standard Answer / Scoring Expectation
Reference tests:
assert solution.solve('a*b?d', 'axxxbc d'.replace(' ','')) is True
assert solution.solve('a*c', 'ab') is False
assert solution.solve('*', '') is True
assert solution.solve('file-??.txt', 'file-ab.txt') is True
Mistake Analysis
Failure type: empty_output
模型正常结束但没有输出任何可评分正文,形成空输出。评分器无法命中答案或关键字段,因此失败。根因是答案生成阶段没有产出内容,而不是评分规则过严。
Scorer Details
{
"returncode": 1,
"stdout": "",
"stderr": "Traceback (most recent call last):\n File \"/var/folders/x_/4cht1kfj1_j31gdv5w01sgmw0000gn/T/dracobench-code-43ksbsn1/test_solution.py\", line 3, in <module>\n assert solution.solve('a*b?d', 'axxxbc d'.replace(' ','')) is True\n ^^^^^^^^^^^^^^\nAttributeError: module 'solution' has no attribute 'solve'\n"
}
Output
challenge-reasoning-006
Suite: reasoning
Finish: None
Prompt
只回答最终数字:一个队列从左到右是 A,B,C,D,E。依次执行:把第 2 个移到末尾;删除第 3 个;在最前面插入 X;把最后两个反转。最终队列中 C 的位置是第几位?
Standard Answer / Scoring Expectation
Answer: 3
Mistake Analysis
Failure type: empty_output
模型正常结束但没有输出任何可评分正文,形成空输出。评分器无法命中答案或关键字段,因此失败。根因是答案生成阶段没有产出内容,而不是评分规则过严。
Scorer Details
{
"expected": "3",
"actual": ""
}
Output
challenge-rag-006
Suite: rag_long_context
Finish: stop
Prompt
只根据资料回答。
资料:一次失败分析显示,模型输出了 key = int(parts[1]),但测试数据里的 key 是字符串 a、b、c。报告认为这是“擅自补类型假设”,不是 token 截断。
问题:这次失败的根因是什么?
Standard Answer / Scoring Expectation
Required phrases: key
At least one from each group: 字符串 / 类型不匹配;整数 / int;类型假设 / 假设 key 为整数 / 假设 key 是整数 / key 为整数类型
Length guidance (diagnostic only): min=n/a, max=120
Mistake Analysis
Failure type: missing_required_info
模型回答没有覆盖评分规则要求的完整证据链。每组至少一个依据表达:整数 / int。这通常表示答案方向可能对,但没有把资料依据说清楚。
Scorer Details
{
"missing": [],
"missing_any": [
[
"整数",
"int"
]
],
"present_forbidden": [],
"char_count": 60,
"length_ok": true,
"length_scored": false
}
Output
这次失败的根因是模型擅自补充了类型假设,将测试数据中本为字符串类型的key错误按整型处理,该问题并非token截断导致。
challenge-reasoning-020
Suite: reasoning
Finish: length
Prompt
只回答最终数字:栈操作从空栈开始。push n 表示入栈;dup 复制栈顶;add 弹出两个数并压入它们的和;swap 交换栈顶两个数;sub 先弹出 x 再弹出 y,并压入 y-x。依次执行:push 2, push 3, dup, add, push 4, swap, sub。最终栈顶是多少?
Standard Answer / Scoring Expectation
Answer: -2
Mistake Analysis
Failure type: empty_output_length
模型耗尽输出预算后没有留下任何正文,形成空输出。评分器无法找到答案或 `solve` 函数,所以失败。这类问题应归因于输出预算/过度生成,而不是某个具体算法步骤写错。
Scorer Details
{
"expected": "-2",
"actual": ""
}
Output
challenge-coding-016
Suite: coding
Finish: stop
Prompt
只输出 Python 代码,不要解释。实现 solve(intervals: list[tuple[int, int]]) -> list[tuple[int, int]]。intervals 是整数闭区间,先按起点排序;重叠或端点相邻的区间要合并,例如 [1,2] 和 [3,4] 合并为 [1,4]。
Standard Answer / Scoring Expectation
Reference tests:
assert solution.solve([(5,7),(1,2),(3,4),(10,10)]) == [(1,7),(10,10)]
assert solution.solve([(1,1),(3,3)]) == [(1,1),(3,3)]
assert solution.solve([]) == []
Mistake Analysis
Failure type: code_syntax_error
区间合并思路本身接近正确,但生成的 Python 缩进坏了:`if start <= current_end + 1:` 下一行 `current_end = max(current_end, end)` 没有缩进到 if 块内,导入 `solution.py` 时直接抛 IndentationError。根因是代码格式/缩进损坏,不是区间合并条件本身被测试击穿。
Scorer Details
{
"returncode": 1,
"stdout": "",
"stderr": "Traceback (most recent call last):\n File \"/var/folders/x_/4cht1kfj1_j31gdv5w01sgmw0000gn/T/dracobench-code-x315v9vv/test_solution.py\", line 1, in <module>\n import solution\n File \"/private/var/folders/x_/4cht1kfj1_j31gdv5w01sgmw0000gn/T/dracobench-code-x315v9vv/solution.py\", line 9\n current_end = max(current_end, end)\nIndentationError: expected an indented block after 'if' statement on line 8\n"
}
Output
```python
def solve(intervals: list[tuple[int, int]]) -> list[tuple[int, int]]:
if not intervals:
return []
intervals.sort(key=lambda x: x[0])
merged = []
current_start, current_end = intervals[0]
for start, end in intervals[1:]:
if start <= current_end + 1:
current_end = max(current_end, end)
else:
merged.append((current_start, current_end))
current_start, current_end = start, end
merged.append((current_start, current_end))
return merged
```
challenge-coding-021
Suite: coding
Finish: stop
Prompt
只输出 Python 代码,不要解释。实现 solve(items: list[str], k: int) -> list[str],返回出现次数最高的前 k 个元素;次数相同按第一次出现的先后排序;k 大于不同元素数量时返回全部。
Standard Answer / Scoring Expectation
Reference tests:
assert solution.solve(['b','a','b','c','a','b'], 2) == ['b','a']
assert solution.solve(['x','y','z','y','z','x'], 2) == ['x','y']
assert solution.solve(['a'], 5) == ['a']
Mistake Analysis
Failure type: code_assertion_failure
频次统计方向正确,但“第一次出现位置”的记录方式错了。代码用字典推导 `{item: idx for idx, item in enumerate(items)}`,重复元素会被后面的索引覆盖,实际记录的是最后一次出现位置。第二组里 x、y、z 都出现 2 次,正确 tie-break 应按第一次出现得到 `[x, y]`;模型按最后出现位置排序成 `[y, z]`。根因是 tie-break 状态记录错,应只在元素第一次出现时写入索引。
Scorer Details
{
"returncode": 1,
"stdout": "",
"stderr": "Traceback (most recent call last):\n File \"/var/folders/x_/4cht1kfj1_j31gdv5w01sgmw0000gn/T/dracobench-code-nnsbo7j6/test_solution.py\", line 4, in <module>\n assert solution.solve(['x','y','z','y','z','x'], 2) == ['x','y']\nAssertionError\n"
}
Output
```python
from collections import Counter
def solve(items: list[str], k: int) -> list[str]:
if not items:
return []
# 统计频率并记录首次出现顺序
freq = Counter(items)
first_occurrence = {item: idx for idx, item in enumerate(items)}
# 排序:先按频率降序,再按首次出现顺序升序
sorted_items = sorted(
freq.keys(),
key=lambda x: (-freq[x], first_occurrence[x])
)
# 返回前k个或全部
return sorted_items[:k]
```
challenge-coding-024
Suite: coding
Finish: None
Prompt
只输出 Python 代码,不要解释。实现 solve(html: str) -> bool,校验简化 HTML 标签是否配对。标签形如 <a>、</a>、<br/>,标签名只含小写字母;自闭合标签不入栈;普通文本忽略。
Standard Answer / Scoring Expectation
Reference tests:
assert solution.solve('<div><br/><p>x</p></div>') is True
assert solution.solve('<a><b></a></b>') is False
assert solution.solve('text<a><b/></a>') is True
Mistake Analysis
Failure type: empty_output
模型正常结束但没有输出任何可评分正文,形成空输出。评分器无法命中答案或关键字段,因此失败。根因是答案生成阶段没有产出内容,而不是评分规则过严。
Scorer Details
{
"returncode": 1,
"stdout": "",
"stderr": "Traceback (most recent call last):\n File \"/var/folders/x_/4cht1kfj1_j31gdv5w01sgmw0000gn/T/dracobench-code-bxnkcvq4/test_solution.py\", line 3, in <module>\n assert solution.solve('<div><br/><p>x</p></div>') is True\n ^^^^^^^^^^^^^^\nAttributeError: module 'solution' has no attribute 'solve'\n"
}
Output
challenge-coding-026
Suite: coding
Finish: stop
Prompt
只输出 Python 代码,不要解释。实现 solve(nums: list[int], k: int) -> list[float],返回每个长度为 k 的滑动窗口中位数。k 为奇数时返回中间值;k 为偶数时返回两个中间值平均数。
Standard Answer / Scoring Expectation
Reference tests:
assert solution.solve([1,3,-1,-3,5,3,6,7], 3) == [1, -1, -1, 3, 5, 6]
assert solution.solve([1,2,3,4], 2) == [1.5, 2.5, 3.5]
Mistake Analysis
Failure type: code_execution_failure
双堆思路方向正确,但懒删除实现没有维护两个堆的“有效元素数量”。窗口滑动时旧元素只记在 `to_remove`,堆的物理长度仍参与 `balance()`,导致堆大小和真实窗口分布不同步;后半段窗口的中位数被旧元素/错误堆顶影响,第一组期望 `[1,-1,-1,3,5,6]`,模型给出后几项偏小。
Scorer Details
{
"returncode": 1,
"stdout": "",
"stderr": "Traceback (most recent call last):\n File \"/var/folders/x_/4cht1kfj1_j31gdv5w01sgmw0000gn/T/dracobench-code-p_ql0eh9/test_solution.py\", line 3, in <module>\n assert solution.solve([1,3,-1,-3,5,3,6,7], 3) == [1, -1, -1, 3, 5, 6]\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/private/var/folders/x_/4cht1kfj1_j31gdv5w01sgmw0000gn/T/dracobench-code-p_ql0eh9/solution.py\", line 38, in solve\n while len(high) - delay.get(high[0], 0) > size // 2:\n ~~~~^^^\nIndexError: list index out of range\n"
}
Output
```python
from heapq import *
from collections import defaultdict
def solve(nums: list[int], k: int) -> list[float]:
def median(low, high, k):
if k % 2 == 1:
return -low[0]
else:
return (-low[0] + high[0]) / 2
low = [] # max-heap (store negative)
high = [] # min-heap
delay = defaultdict(int)
res = []
size = 0
for i, num in enumerate(nums):
# insert
if not low or num <= -low[0]:
heappush(low, -num)
else:
heappush(high, num)
size += 1
# remove out-of-window elements lazily
if i >= k:
out = nums[i - k]
delay[out] += 1
size -= 1
# balance heaps
while len(low) - delay.get(-low[0], 0) > size - (size // 2):
val = -heappop(low)
delay[val] -= 1
if delay[val] == 0:
del delay[val]
heappush(high, val)
while len(high) - delay.get(high[0], 0) > size // 2:
val = heappop(high)
delay[val] -= 1
if delay[val] == 0:
del delay[val]
heappush(low, -val)
# clean delayed elements from heap tops
while low and delay.get(-low[0], 0) > 0:
val = -heappop(low)
delay[val] -= 1
if delay[val] == 0:
del delay[val]
while high and delay.get(high[0], 0) > 0:
val = heappop(high)
delay[val] -= 1
if delay[val] == 0:
del delay[val]
# compute median
if size == k:
res.append(median(low, high, k))
return res
```
challenge-coding-027
Suite: coding
Finish: stop
Prompt
只输出 Python 代码,不要解释。实现 solve(versions: list[str]) -> list[str],按简化语义版本排序。版本为 major.minor.patch 或 major.minor.patch-label;major/minor/patch 按数字比较;同一数字版本下,带 label 的预发布版本低于正式版本;label 按字典序比较。
Standard Answer / Scoring Expectation
Reference tests:
assert solution.solve(['1.0.0','1.0.0-alpha','1.0.1','1.0.0-beta','0.9.9']) == ['0.9.9','1.0.0-alpha','1.0.0-beta','1.0.0','1.0.1']
assert solution.solve(['1.0.10','1.0.2']) == ['1.0.2','1.0.10']
Mistake Analysis
Failure type: code_assertion_failure
版本排序方向写反了。题目要求同一数字版本下预发布版低于正式版,但模型的 key 是 `(numeric, 0 if label is None else 1, label)`,升序排序会把正式版 `1.0.0` 放在 `1.0.0-alpha` 和 `1.0.0-beta` 前面。根因是正式版/预发布版的排序标志位取值反了;应让带 label 的版本排在正式版之前,并为正式版使用可比较的占位 label。
Scorer Details
{
"returncode": 1,
"stdout": "",
"stderr": "Traceback (most recent call last):\n File \"/var/folders/x_/4cht1kfj1_j31gdv5w01sgmw0000gn/T/dracobench-code-snfjey05/test_solution.py\", line 3, in <module>\n assert solution.solve(['1.0.0','1.0.0-alpha','1.0.1','1.0.0-beta','0.9.9']) == ['0.9.9','1.0.0-alpha','1.0.0-beta','1.0.0','1.0.1']\nAssertionError\n"
}
Output
```python
def solve(versions: list[str]) -> list[str]:
def parse_version(v: str):
parts = v.split('-', 1)
numeric = tuple(map(int, parts[0].split('.')))
label = parts[1] if len(parts) > 1 else None
return (numeric, 0 if label is None else 1, label)
return sorted(versions, key=parse_version)
```