Zoltraak, 366 字节的虚拟机,和 22 个让评委熬夜到凌晨 1 点的 C 程序
2025 年 6 月,第 29 届国际混乱 C 代码大赛(IOCCC)公布了获奖名单。22 个条目从近两百份投稿中杀出重围。
如果你不知道 IOCCC 是什么——它是一个每年举办、要求参赛者写出最莫名其妙但完全合法的 C 代码的比赛。规则很简单:你的程序必须通过 ANSI C 编译,输出必须正确,但评审看了你的源码会偏头痛。
今年的亮点?有人用 366 字节写了一个能运行 Linux 和 Doom 的虚拟机。有人写了一个 Game Boy 模拟器,源码长成 Game Boy 的形状。有人做了一个只有一条指令的计算机。还有人——致敬《葬送的芙莉莲》——用「zoltraak」这一个词写了一个完整的编程语言。
目录
- 366 字节的计算机
- 一个关键词编程语言
- 长成 Game Boy 的 Game Boy 模拟器
- Nixie Tube 的 C 语言重现
- 吞掉自己尾巴的压缩程序
- 用整数模拟 C64
- AI 能参赛吗?
366 字节的计算机
作者 cable 提交的程序只有一个奖:「Best Imaginary Emulator」。但 366 字节的源码同时刷新了「最小体积」的记录。
这 366 个字节实现了一台完整的 OISC(One Instruction Set Computer)——只有一条指令的计算机。不要觉得一条指令什么也做不了。OISC 的「一条指令」通常是「减法并跳转」,靠这一条指令就能组合出加法、乘法、分支、循环——图灵完备的。
它的 boot image 里封装了一个完整的 vmlinux,跑起来之后你还能在这个 OISC 虚拟机里再跑 Doom。
评委评价:当我们盯着这个程序看的时候,我们想的不是「它做了什么」,而是「它这点代码能做什么?」
答案是:还挺多的。
其中还有一个未解出的「Fun Challenge」:为这台虚拟机写一个 C 编译器。如果有谁想挑战,IOCCC 说欢迎 PR。
一个关键词编程语言
这是今年最让我乐出声的条目。
作者 Don Yang(yang2)的灵感来自《葬送的芙莉莲》——魔法使芙莉莲最常用的普通攻击魔法(zoltraak),是一种只需要「一个咒语就能打败大多数敌人」的通用魔法。
于是 Yang 写了一个编程语言,它的保留字只有一个:zoltraak。
没有运算符。没有括号。没有变量声明。一个合法的 zoltraak 程序长这样:
zoltraak zoltraak zoltraak zoltraak zoltraak zoltraak zoltraak
这个程序会输出 216 个 + 符号——每行 zoltraak 对应若干字符。
这个 IOCCC 条目(作者称之为「Fern」,也就是芙莉莲的弟子费伦,因为「费伦负责把 zoltraak 编码成可执行代码」)做的事情是:你往 stdin 丢文本进去,它生成 C 代码,编译后执行这段 C 代码会原样输出你丢进去的文本。
换句话说:它用 zoltraak 这门语言写了一个自解压编码器。
空间编码 + zoltraak 语法的组合,在 Hacker News 上有人发现「output 里貌似包含一个神秘的单词」,评委也卖关子:「Space matters in the output, but why does it also contain that single word?」
去翻翻 prog.c 的源码,你会看到一个名为 p[] 的数组里面藏着点什么。
长成 Game Boy 的 Game Boy 模拟器
ncw1 的 Game Boy 模拟器能跑真正的 .gb ROM 文件,包括《Tetris》。这本身不稀奇——GitHub 上一搜一堆。
稀奇的是它的源码排列成 Game Boy 的形状——return 语句的间距和位置,让整个源码看起来像一个手持游戏机的轮廓。一位评委说他「看这个程序看到凌晨 1 点都没停下来」。
而且作者没有用 #define 来排列 return 语句的布局。这些返回语句全部是手写的。源码长度不到 4096 字节的老上限,但能跑完整的 Game Boy 指令集。
Nixie Tube 的 C 语言重现
endoh1 的作者(一位 IOCCC 常客,今年贡献了 3 个获奖条目)写了一款 Nixie Tube 模拟器。
Nixie Tube 是 1950-70 年代使用的数字显示管,每个数字是一个独立的发光阴极,叠在一起。你从管子的顶部看下去,会看到一个发光的数字浮在玻璃管里。
endoh1 用 ANSI 终端 256 色模拟了这个效果。从标准输入读入文本,然后在你的终端里用 Nixie Tube 的光效逐字显示出来。
它的源码还有一个有趣的属性:每行 C 代码恰好 42 个字符。随便修剪末尾空格或者加一行空格,程序就不工作了——字符串字面量中藏着对齐依赖的索引。
评委开玩笑说这是一个「embiggen」(辛普森家族梗)的挑战——如果你想让 Nixie Tube 显示大写字母,需要扩大管子的尺寸。
吞掉自己尾巴的压缩程序
diels-grabsch 只写了一行 C 代码,实现了一个 compress 命令(Unix LZW 压缩格式)。
不是玩笑。一个单行 C 程序,编译后能生成 .Z 文件,并且 uncompress 可以解压。
它的灵感来自 2019 年同一作者的另一个条目——评委当年说「你能不能用一行代码实现 compress?」6 年后,他做到了。
核心技巧:代码里有一个魔数 9018655,它的用途是一个未解出的 fun challenge。
用整数模拟 C64
ncw2 拿了一个「Best Rational Emulator」奖,模拟的是 Commodore 64。
它的原理比上面那个 OISC 虚拟机还要抽象:「标准模拟器太臃肿了——模拟 6502 指令、VIC-II 视频芯片、SID 音频芯片……这些太老派了。我意识到,C64 在任何一瞬间的状态都可以用一个整数表示。因此,从一个状态到下一个状态的转换只是一个数学变换。」
所以整个 C64 模拟器就是一个状态函数——把当前整数算成下一个整数。你的游戏就是这个数学函数的一次长跑。
内置了一个迷宫生成器 demo,跑起来能在终端里看到 C64 风格的彩色迷宫。
AI 能参赛吗?
IOCCC 每届都有关于 LLM 的讨论。今年尤其——Hacker News 上的回复分歧明显。
一方说:「LLM 可以把任何语言的程序转成混乱 C 代码,这比赛还有意义吗?」
另一方说(我也是站这头的):「允许LLM 参赛并不等于 LLM 能赢。」IOCCC 官方指南明确说了允许使用 AI 辅助。但评审看的不是「多混乱」,而是想法——366 字节跑 Linux 的 OISC 虚拟机、zoltraak 语言、行数对齐到 Game Boy 轮廓……这些东西不是被 prompt 说「make this code confusing」能写出来的。
而且 2025 年的投稿数量和质量都与 2024 年持平(2024 年因为 IOCCC 在 2020-2024 的四年空窗后重启,被认为是投稿量历史高峰)。这至少说明——在 AI 写代码比人快的 2026 年,还有一大群人更享受手写混乱 C 代码并看着它在终端里跑出东西来的快乐。
这种快乐,LLM 理解不了。至少现在还不能。
二十九年了。一个始于 C 语言还年轻的 1984 年的比赛,到今天还在收稿、还在折腾、还在用 366 字节挑战人类对计算机的理解上限。它不需要什么意义。有意义的是那些凌晨还在调 return 语句位置的人。
评论(0)
暂无评论,来写第一条吧~