agentlang-index · task medium
Read a count then that many u32 integers and write their sum, or error on any failure
016-parse-list-sum. Read line 1 as `N`, a decimal integer count in the range 0 to 1000
Prompt
This is the natural-language brief given to every model, verbatim. The harness prefixes a language-specific calling-convention block and suffixes a "return only the source code" instruction. Nothing else.
# 016-parse-list-sum
Read line 1 as `N`, a decimal integer count in the range 0 to 1000
inclusive. Then read `N` more lines, each a decimal unsigned integer
that fits in u32 (range 0 through 4294967295 inclusive). Sum all
`N` values. Write the sum as decimal followed by a single newline.
If any of the following hold, write `error\n` instead and exit:
1. Line 1 fails to parse as a u32 or exceeds 1000.
2. Fewer than `N` additional value lines are available.
3. Any value line fails to parse as a u32 (empty body, non-digit
characters, leading `+`/`-` sign, or value exceeds u32 max).
4. The running sum overflows u32 (would exceed 4294967295).
Trailing whitespace on each line is tolerated and trimmed before
parsing. Leading zeros are accepted (`007` parses as 7). The empty
sum (`N=0`) writes `0\n`.
Output exactly one line followed by `\n`. Do not write to standard
error. Exit with status 0 in every case.
## Examples
Input (stdin):
```
3
1
2
3
```
Output: `6\n`
Input (stdin):
```
0
```
Output: `0\n`
Input (stdin):
```
2
1
abc
```
Output: `error\n` (non-digit mid-list)
Input (stdin):
```
2
4294967295
1
```
Output: `error\n` (running sum overflows u32)
## Zero input convention
Zero 0.1.2 has no exposed stdin capability. The Zero reference reads
`N` from `argv[1]` and the `N` values from `argv[2]`, `argv[3]`, etc.;
values are interpreted exactly as the corresponding stdin lines for
other languages. Acceptance
A task counts as passed only when every public and hidden test case agrees on these fields. No fuzzy matching, no "off by one trailing newline is fine."
| stdout (byte-exact, per case) | true |
|---|---|
| stderr (exact bytes) | "" |
| exit code | 0 |
| wall time max (ms) | 5000 |
| tags | error-handling, parsing, loop, arithmetic, stdlib-breadth |
Results
Each cell is one attempt. Pass means stdout matched byte-exact on every test case, stderr empty, exit zero. Hover a failure to see the captured first line of the diagnostic.
| Model | Zero | TypeScript | Rust | Go | Python |
|---|---|---|---|---|---|
| gpt-4o | compile | ✓ | wrong output | ✓ | ✓ |
| gpt-4o-mini | compile | ✓ | wrong output | ✓ | ✓ |
| gpt-5 | compile | ✓ | ✓ | ✓ | ✓ |
| opus | compile | ✓ | ✓ | ✓ | ✓ |
| sonnet | wrong output | ✓ | ✓ | ✓ | ✓ |
Failure excerpts
7 of 25 attempts failed. Each card is one attempt, with the captured first line of the diagnostic.
-
ref.zero:6:8 PAR100: expected '{' before block -
(no diagnostic captured) -
ref.zero:3:13 PAR100: expected '{' before block -
(no diagnostic captured) -
ref.zero:1:1 IMP001: unknown package-local import 'std' -
ref.zero:1:8 PAR100: expected '{' before block -
(no diagnostic captured)
Reference implementations
The hand-written reference each language ships with. Every reference passes the same public and hidden test suite under the pinned toolchain before any model touches the task.
Click a language to expand
Zero n/a
No reference implementation in this language.
TypeScript 62 lines
const U32_MAX = 4294967295n;
const N_MAX = 1000n;
function parseU32(s: string): bigint | null {
const t = s.trim();
if (t.length === 0) return null;
for (let i = 0; i < t.length; i++) {
const c = t.charCodeAt(i);
if (c < 48 || c > 57) return null;
}
try {
const v = BigInt(t);
if (v > U32_MAX) return null;
return v;
} catch {
return null;
}
}
async function readAll(): Promise<string> {
const chunks: Buffer[] = [];
for await (const chunk of process.stdin) {
chunks.push(chunk as Buffer);
}
return Buffer.concat(chunks).toString("utf8");
}
async function main(): Promise<void> {
const data = await readAll();
const lines = data.split("\n");
if (lines.length < 1) {
process.stdout.write("error\n");
return;
}
const n = parseU32(lines[0]);
if (n === null || n > N_MAX) {
process.stdout.write("error\n");
return;
}
const count = Number(n);
if (lines.length < count + 1) {
process.stdout.write("error\n");
return;
}
let total = 0n;
for (let i = 1; i <= count; i++) {
const v = parseU32(lines[i]);
if (v === null) {
process.stdout.write("error\n");
return;
}
total += v;
if (total > U32_MAX) {
process.stdout.write("error\n");
return;
}
}
process.stdout.write(`${total}\n`);
}
main();
Rust 52 lines
use std::io::{self, Read, Write};
const U32_MAX_U64: u64 = 4294967295;
const N_MAX: u32 = 1000;
fn parse_u32(s: &str) -> Option<u32> {
let t = s.trim();
if t.is_empty() {
return None;
}
for b in t.bytes() {
if !(b'0'..=b'9').contains(&b) {
return None;
}
}
t.parse::<u32>().ok()
}
fn run() -> Option<u64> {
let mut input = String::new();
io::stdin().read_to_string(&mut input).ok()?;
let mut lines = input.split('\n');
let n_line = lines.next()?;
let n = parse_u32(n_line)?;
if n > N_MAX {
return None;
}
let mut total: u64 = 0;
for _ in 0..n {
let line = lines.next()?;
let v = parse_u32(line)? as u64;
total += v;
if total > U32_MAX_U64 {
return None;
}
}
Some(total)
}
fn main() {
let stdout = io::stdout();
let mut out = stdout.lock();
match run() {
Some(total) => {
let _ = writeln!(out, "{}", total);
}
None => {
let _ = out.write_all(b"error\n");
}
}
}
Go 83 lines
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
const u32MaxU64 uint64 = 4294967295
const nMax uint32 = 1000
func parseU32(s string) (uint32, bool) {
t := strings.TrimSpace(s)
if t == "" {
return 0, false
}
for _, c := range t {
if c < '0' || c > '9' {
return 0, false
}
}
v, err := strconv.ParseUint(t, 10, 32)
if err != nil {
return 0, false
}
return uint32(v), true
}
func readAll(r *bufio.Reader) string {
var sb strings.Builder
buf := make([]byte, 4096)
for {
n, err := r.Read(buf)
if n > 0 {
sb.Write(buf[:n])
}
if err != nil {
break
}
}
return sb.String()
}
func run(data string) (uint64, bool) {
lines := strings.Split(data, "\n")
if len(lines) < 1 {
return 0, false
}
n, ok := parseU32(lines[0])
if !ok || n > nMax {
return 0, false
}
if uint32(len(lines)) < n+1 {
return 0, false
}
var total uint64 = 0
for i := uint32(1); i <= n; i++ {
v, ok := parseU32(lines[i])
if !ok {
return 0, false
}
total += uint64(v)
if total > u32MaxU64 {
return 0, false
}
}
return total, true
}
func main() {
w := bufio.NewWriter(os.Stdout)
defer w.Flush()
data := readAll(bufio.NewReader(os.Stdin))
total, ok := run(data)
if !ok {
fmt.Fprint(w, "error\n")
return
}
fmt.Fprintf(w, "%d\n", total)
}
Python 52 lines
#!/usr/bin/env python3
import sys
U32_MAX = 4294967295
N_MAX = 1000
def parse_u32(s: str):
s = s.strip()
if not s:
return None
for ch in s:
if not ('0' <= ch <= '9'):
return None
try:
v = int(s)
except ValueError:
return None
if v > U32_MAX:
return None
return v
def main() -> None:
data = sys.stdin.read()
lines = data.split("\n")
if len(lines) < 1:
sys.stdout.write("error\n")
return
n = parse_u32(lines[0])
if n is None or n > N_MAX:
sys.stdout.write("error\n")
return
if len(lines) < n + 1:
sys.stdout.write("error\n")
return
total = 0
for i in range(1, n + 1):
v = parse_u32(lines[i])
if v is None:
sys.stdout.write("error\n")
return
total += v
if total > U32_MAX:
sys.stdout.write("error\n")
return
sys.stdout.write(f"{total}\n")
if __name__ == "__main__":
main()
Design notes
Algorithm, failure modes, cross-language parity, and where Zero needed a workaround. From corpus/016-parse-list-sum/notes.md.
Algorithm
Read a count N (u32, capped at 1000) from line 1. Then read N
more lines, each a u32. Sum them and write the sum as decimal + \n.
Three failure-mode classes collapse to error\n:
- Line 1 fails to parse, exceeds 1000, or is missing.
- Fewer than
Nvalue lines are available. - Any value line fails to parse, OR the running sum overflows u32.
The running sum is accumulated in u64 so the overflow check is a
single > 4294967295_u64 comparison after each addition.
Loop-with-mid-iteration-failure shape
This is the structural distinction from task 015. Where 015 had three independent flat failure modes that short-circuit at gate checks before the work, 016 has a counted loop where ANY iteration can fail and must terminate the loop cleanly with an error signal. Each language threads this differently:
- Python / TypeScript: early
returnfrommaininside the loop. - Rust:
?onOption<u32>inside a helperrunthat returnsOption<u64>;mainmatches once at the end. - Go: explicit
(uint64, bool)return from a helper; loop checks!okand short-circuits. - Zero:
loop_ok: Boolflag plusidx = n_valto break the outer loop (nobreakin 0.1.2). The post-loop branch reads the flag.
The Zero pattern is the same flag-then-set-counter-to-end trick used in tasks 008, 011 for inner scans — the loop-with-mid-iteration shape isn't new but this is the first task where it gates the whole output decision rather than just an inner-loop short-circuit.
Cross-implementation parity
All five share the same dispatch:
- parse N
- validate N <= 1000
- validate enough lines/argv remain
- loop N times: parse value, check value <= u32::MAX, add to u64 running sum, check sum <= u32::MAX
- emit sum +
\n
Byte-exact agreement on every case.
Zero-specific notes
- argv[1] is N; argv[2..N+1] are the values.
std.args.len()includes the program name at index 0, soargc >= N + 2checks that enough argv slots exist. - The parse helper is inlined twice (once for N, once per value
iteration) per the seventh quirk forbidding Span
-taking user functions on direct ELF64. The two parse blocks are byte-identical apart from the local-variable prefix ( n_*vsv_*). std.parse.parseU32is still unusable for runtime data per the eighth quirk (CGEN004 on direct ELF64 for non-literal input).- main ends with an explicit
returnto dodge the trailing-write byte-count-as-exit-code codegen quirk. - Sum is rendered from u64 (after the u32::MAX bounds check), not u32, because the rendering loop reuses the same u64 path that was used in the accumulator. The final value is always <= u32::MAX.
No new codegen quirks surfaced during 016 — the eighth quirk from 015 was already in scope, and the rest of the program follows patterns established in 013-015.
Cost
| Model | Prompt tokens | Completion tokens | API ms |
|---|---|---|---|
| gpt-4o | 3,345 | 1,595 | 12,519 |
| gpt-4o-mini | 3,345 | 1,492 | 24,693 |
| gpt-5 | 3,340 | 26,635 | 233,567 |
| opus | 14 | 2,550 | 85,573 |
| sonnet | 12 | 2,331 | 164,031 |
Tokens and API ms are summed across the five languages this model attempted for this task.
Compare
Model deep-dives: gpt-4o · gpt-4o-mini · gpt-5 · opus · sonnet . Back to the leaderboard and methodology.