agentlang-index · task easy
Balanced bracket checker
005-balanced-parens. Read a single line of printable ASCII (at most 1000 characters) from standard
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.
## Task: Balanced bracket checker
Read a single line of printable ASCII (at most 1000 characters) from standard
input. Decide whether the bracket characters `(`, `)`, `[`, `]`, `{`, `}` are
balanced:
- Every opener (`(`, `[`, `{`) has a matching closer (`)`, `]`, `}`).
- Every closer matches the most recent unmatched opener of the same kind.
- The opener/closer pairs nest without crossing.
- All non-bracket characters are ignored when judging balance.
- The empty input is balanced.
Write `yes` followed by a newline if the input is balanced, or `no` followed
by a newline if not. Exit with status 0.
## Acceptance
- Stdin: one line, at most 1000 printable-ASCII characters, terminated by `\n`.
- Stdout: exactly `yes\n` or exactly `no\n`.
- Stderr: empty.
- Exit code: 0.
## Examples
| input | output |
| -------------------------- | ------- |
| (empty) | `yes` |
| `()` | `yes` |
| `([{}])` | `yes` |
| `([)]` | `no` |
| `(` | `no` |
| `)` | `no` |
| `abc(def[gh{ij}kl]mn)` | `yes` |
| `if (x[0] == y) { a = 1 }` | `yes` | 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 | parsing, stack, strings |
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 | ✓ | ✓ | ✓ | ✓ |
| gpt-4o-mini | compile | ✓ | ✓ | ✓ | ✓ |
| gpt-5 | compile | ✓ | ✓ | ✓ | ✓ |
| opus | compile | ✓ | ✓ | ✓ | ✓ |
| sonnet | wrong output | ✓ | ✓ | ✓ | ✓ |
Failure excerpts
5 of 25 attempts failed. Each card is one attempt, with the captured first line of the diagnostic.
-
ref.zero:1:1 IMP001: unknown package-local import 'std' -
ref.zero:3:18 PAR100: expected expression -
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 31 lines
// Balanced bracket checker, TypeScript reference.
// Reads one line of printable ASCII (up to 1000 chars), prints `yes` or `no`.
import { readFileSync } from "node:fs";
function main(): void {
let line = readFileSync(0, "utf8");
if (line.endsWith("\n")) line = line.slice(0, -1);
const stack: string[] = [];
const pairs: Record<string, string> = { ")": "(", "]": "[", "}": "{" };
let balanced = true;
for (const ch of line) {
if (ch === "(" || ch === "[" || ch === "{") {
stack.push(ch);
} else if (ch === ")" || ch === "]" || ch === "}") {
if (stack.length === 0 || stack[stack.length - 1] !== pairs[ch]) {
balanced = false;
break;
}
stack.pop();
}
}
if (balanced && stack.length === 0) {
process.stdout.write("yes\n");
} else {
process.stdout.write("no\n");
}
}
main();
Rust 46 lines
// Balanced bracket checker, Rust reference.
// Reads one line of printable ASCII (up to 1000 chars), prints `yes` or `no`.
use std::io::{self, Read, Write};
fn main() {
let mut input = String::new();
io::stdin().read_to_string(&mut input).unwrap();
if input.ends_with('\n') {
input.pop();
}
let mut stack: Vec<char> = Vec::new();
let mut balanced = true;
for ch in input.chars() {
match ch {
'(' | '[' | '{' => stack.push(ch),
')' => {
if stack.pop() != Some('(') {
balanced = false;
break;
}
}
']' => {
if stack.pop() != Some('[') {
balanced = false;
break;
}
}
'}' => {
if stack.pop() != Some('{') {
balanced = false;
break;
}
}
_ => {}
}
}
let out = io::stdout();
let mut h = out.lock();
if balanced && stack.is_empty() {
h.write_all(b"yes\n").unwrap();
} else {
h.write_all(b"no\n").unwrap();
}
}
Go 53 lines
// Balanced bracket checker, Go reference.
// Reads one line of printable ASCII (up to 1000 chars), prints `yes` or `no`.
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
line, _ := reader.ReadString('\n')
line = strings.TrimRight(line, "\n")
stack := make([]byte, 0, 1024)
balanced := true
for i := 0; i < len(line); i++ {
ch := line[i]
switch ch {
case '(', '[', '{':
stack = append(stack, ch)
case ')':
if len(stack) == 0 || stack[len(stack)-1] != '(' {
balanced = false
} else {
stack = stack[:len(stack)-1]
}
case ']':
if len(stack) == 0 || stack[len(stack)-1] != '[' {
balanced = false
} else {
stack = stack[:len(stack)-1]
}
case '}':
if len(stack) == 0 || stack[len(stack)-1] != '{' {
balanced = false
} else {
stack = stack[:len(stack)-1]
}
}
if !balanced {
break
}
}
if balanced && len(stack) == 0 {
fmt.Print("yes\n")
} else {
fmt.Print("no\n")
}
}
Python 31 lines
"""Balanced bracket checker, Python reference.
Reads one line of printable ASCII (up to 1000 chars), prints `yes` or `no`.
"""
import sys
def main() -> None:
line = sys.stdin.readline()
if line.endswith("\n"):
line = line[:-1]
stack: list[str] = []
pairs = {")": "(", "]": "[", "}": "{"}
balanced = True
for ch in line:
if ch in "([{":
stack.append(ch)
elif ch in ")]}":
if not stack or stack[-1] != pairs[ch]:
balanced = False
break
stack.pop()
if balanced and not stack:
sys.stdout.write("yes\n")
else:
sys.stdout.write("no\n")
if __name__ == "__main__":
main()
Design notes
Algorithm, failure modes, cross-language parity, and where Zero needed a workaround. From corpus/005-balanced-parens/notes.md.
Algorithm
Single stack of openers. Walk the input character by character. Push on
( [ {; on ) ] } pop and verify the popped opener matches the
closer kind. Anything else is ignored. Balanced iff no mismatch occurred
AND the stack is empty at the end.
Zero-specific notes
- argv[1] is the input string. The 1000-char spec cap matches the
[1000]u8flat stack buffer. - Bracket bytes used directly:
(40,)41,[91,]93,{123,}125. Encoded asu8literals (40_u8, etc). - Zero 0.1.2 has no
breakkeyword inside awhile. To short-circuit on the first mismatch, the loop setsi = ninstead ofi = i + 1. The same exit shape worked in tasks 001-004. - Empty argv[1] is allowed (operator may run
zero run ref.zero "") and Zero'sstd.args.getstill returns a value with an empty span. We branch on.hasfor safety but the empty-span path falls through cleanly:n = 0, the while loop is skipped, balanced + empty stack printsyes\n.
Edge cases checked
| input | expected |
|---|---|
| empty line | yes |
() |
yes |
([{}]) |
yes |
([)] |
no |
) |
no |
( |
no |
if (x[0] == y) { a = 1 } |
yes |
{[()()]{[]}}([{}]) |
yes |
Cross-implementation parity
All five references produce byte-exact yes\n or no\n on every case in
both stdin (TS/Rust/Go/Python) and argv (Zero) input modes.
Cost
| Model | Prompt tokens | Completion tokens | API ms |
|---|---|---|---|
| gpt-4o | 2,935 | 1,072 | 9,986 |
| gpt-4o-mini | 2,935 | 1,006 | 22,095 |
| gpt-5 | 2,930 | 8,954 | 96,147 |
| opus | 14 | 1,250 | 80,790 |
| sonnet | 14 | 5,914 | 128,879 |
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.