https://github.com/ioccc-src/winner/blob/master/2025/ncw1/pr...
The author, Nick Craig-Wood, is the creator of rclone!
All my love <3 <3 <3 to organizers, thank you for continuing the IOCCC context, please never go away again!
– And?
– I'm sorry I wasted your time. I just can't understand it.
They burst into laughs and asked me to start the joining process.
I wonder if people still make fun of interns. I still have a good laugh when I remember myself freaking out.
One of the main characters is called Fern, and she almost exclusively uses the common offensive magic of Zoltraak.
"The IOCCC has a rich history of remarkable winning entries created by authors who skillfully employed various techniques (often their own tools) to develop their code."
Do I miss anything?
[0] https://github.com/ioccc-src/winner/blob/master/2025/cable/p...
[1] https://github.com/ioccc-src/winner/blob/master/2025/cable/R...
If you want to see how the sausage was made, here is the source:
https://github.com/ncw/ioccc-gameboy
You'll find an unobfuscated version (kind-of) there too. This the the one I actually worked on then I had a program squash all the variable names and squeeze it into the gameboy shape
The size limit for the entry was the killer. You are allowed 2503 non white space characters (a simplification - the rules are complicated) in IOCCC entries and 4K total code size. This isn't a lot to fit a Z80 processor and a GameBoy hardware emulator in!
I first wrote a full Gameboy emulator in C. It started out at about 6000 non white space characters. I then spent about about 100 hours work trying to get it to fit into the 2503 limit. For a long time I wasn't sure it was going to fit.
I decided making the emulator play Tetris (which is a fairly simple game) was the target so I stripped out features like the half carry flag in the Z80 emulator and the windowing system in the Gameboy emulation which Tetris didn't need. I also abused the C code terribly doing things with implicit int I can never un-see. I also got creative with the IOCCC rules which are implemented in a C program which checks your source and I spent some time reverse engineering that looking for loopholes! I discovered that the operators defined in <iso646.h> only count for one token which was very useful.
Once I had it small enough I had to supply some games to run with it. I created 4, a test program written in z80 assembler, a pi calculator (written in assembler), a 3d tic tac toe game (written in C with gbdk-2020) and a chess program also written in C. I discovered that quite a few open source games ran on the emulator too so I added a downloader for those where I could. Apparently not many games use BCD arithmetic - who would have thought!
It was a fun project.
>This VM implements an OISC - a One Instruction Set Computer. That instruction takes three signed 32-bit operands, a, b and c, and runs a program from memory m[] as follows:
1 PC (program counter) starts at 0
2 Fetch the next instruction (32-bit signed operands a, b and c)
3 If the low bit on any operand is set, remove it, and replace that operand with m[operand] i.e., a dereference of that address
4 Set m[b] = m[b] - m[a]
5 If m[b] is 0 or negative, set the PC to c, otherwise increment PC by 3 words
6 Go to step 2
I could have gone all out writing standard library routines for opening files, running shell commands, coding strstr, strcpy, and similar. And to be honest I did implement some things I didn't need as part of the learning process (for example print(getenv("HOME")) works). But I soon realized I needed some example programs to test things and show off.
So of course the first real program I implemented was a brainfuck interpreter. Which means my language is now, indirectly, turing complete!
My early versions took 9 minutes to output the famous mandelbrot program, so I had to make a bunch of optimizations, and later implemented support for switch/case statements to speed things up. Now I can generate the same output in two minutes - so room for improvement, but also a good bit of progress!
Cheating by implementing another language in my own was very very satisfying. Though of course this is all for fun/learning and not intended to be used seriously by anybody, not even myself!
> You are free to use whatever tools you wish to write your code. This includes tools that are AI based, LLM (large language model), Virtual coding assistants, code generators, or similar tools, as well as your own tools. The IOCCC judges do not discriminate on the basis of the tools used to write obfuscated C code so long as you are the ultimate author of the code you submit.
- The number of winning entries and losing entries that get revealed later in public suggests that this number should be at least 50.
- The number of judging rounds, as the FAQ says, is at least 3 and possibly more. If each judging round eliminates about a half of entries, we should expect at least 10 submissions per each winning entries. I personally think the actual elimination rate can be as low as 1--20% at the end, but at least first few rounds should be easy so I think this is a good minimum guess: 1--200.
- The current number of individual judges is just enough for the three-digit number of submissions. It has a striking resemblance with typical academic conferences with typical acceptance rate, by the way! If there were thousands of submissions (like today's AI conferences...) there ought to be much more judges, and more importantly, more levels of judges so that each judge can do just enough work throughout the entire process. So this establishes the maximum guess: 1,000.
- My best guess is simply a geometric mean of two extrema.
I think it's great that IOCCC accepts code that might have been built with machine assistance, because it makes the purely handcrafted winners seem even more valuable.
There's the one here: Set m[b] = m[b] - m[a]
Then it links to the reference implementation on github [2] which says you just need the napkin notes [3], which is dividing everything read by 4, which is corroborated by the reference implmentation [4], but it's not clear why 4 is chosen here rather than 2, as it seems to waste a bit. Was this bit needed, or is it reserved for future expansion?
I presume the original implementation didn't do the divide by 4 and it was added later, but I don't see why it was needed, other than perhaps just making LLVM code gen a little easier. I'd need to work through lots of examples to work out if the system as described is impossible without dividing by 4 (although you'd presumably only be able to access even addresses, and the PC increases by 3 each time, so it would definitely be annoying to refer to code locations).
Then the reference implementation starts doing magic when location 64 is accessed, overwriting locations 64-67 with the current time, which is mentioned in the napkin description, but not the description on the main page.
Both descriptions mention the magic -1 address, so it seems strange that the very implementation-dependent UTC clock isn't also implemented with -ve addresses rather than trashing memory that is otherwise free for the implementation to use as desired.
Both descriptions also mention the regular timer interrupt process, which also seems disappointing, reusing address 0 as the interrupt handler location and 1 as the saved PC, which means that you have to overwrite the initial entry point at location 0 as soon as the program starts.
[1] https://eternal-software.org/
[2] https://github.com/adriancable/eternal
[3] https://github.com/adriancable/eternal/blob/main/docs/napkin...
[4] https://github.com/adriancable/eternal/blob/main/vm/vm.c
GCC says there are a bunch of undefined symbols, first one being "R" right in the beginning:
typedef unsigned char u;
u w,X,T,D[1<<16],t[]=R,U=255;Also, the reverse is interesting: how well can they guess the function of the obfuscated code?
https://www.ioccc.org/2025/rules.html
It seems to refer to custom code generators. Why would they mean AI if they explicitly talk about a "rich history" (when AI wasn't available)?
Claude seems OK with it now, so I don't know whether that was a glitch but it was quite funny.
/curious though given the very nice conversation we're having here, why the parent topic gets down-voted. is neither off-topic, nor rude.../
The long tradition refers to the use of tooling in general, and could mean that, since past tools were accepted, recent tools like LLMs can be fair game as well.
But, since there can be doubts about this interpretation, them saying explicitly if LLMs are permitted or not could be beneficial. But then again, maybe they don't want to commit to an hard rule and have more freedom to decide on a case by case basis, or just don't advertise that LLMs are welcome to prevent a flood of vibe-coded submissions.
When most visitors obviously just want to glance at the programs and see what they do, this is horrifically organized.
If anything, it is closer to code golf, the main obfuscation is often a result of all the trickery needed to do something impressive in a small amount of code. Of course, minification techniques are used, like renaming variables to single character and messing with the formatting, but that's the boring part, no one is going to win because of that.
Another aspect is being clever and unique, and abusing the rules is often rewarded... once. LLMs are not good at that. The judges are human, the code needs to a appeal to a human, not just be hard to understand.
School ? /s
They also lack the creativity needed for those entries. Obfuscation is only one part of it. Coming up with the idea is another. Many entries also have special qualities that make them true works of art.
That human art is worth the humanity in the art.
As soon as anything is automated, it's worth nothing.
In both cases you cannot get permission.
For example:
if (x == 1 || x == 2) { ...
can be transformed into: if (!(2+x*x-3*x)) { ...
An LLM will do this if you explicitly ask it to, but not on its own.[0] https://github.com/ioccc-src/winner/blob/master/2024/macke/p...
if (!(x/2-1)) { ...
EDIT: Oops, confused the original with x==2 || x==3. Instead, we can use !(x-1>>1), which precedence rules parse as !((x-1)>>1). if(x-1<2&&x)...
if((1<<x)&6)...
if(x<3&x)...
if(3%x&&x<3)...
if(!((x-1)*(x-2)))
if(!(x^1|x^2))...
if(!(x*x-3*x+2))Are you sure they still can't do it?
this statement is equivalent to x==2 | x==3.
For example, x=3, 3/2 = 1 then 1-1 = 0 so that !(0) is 1 or true. Also for x=1, 1/2 = 0 then 0-1 = -1 and !(-1) = 0 or false.
I agree with your point in general though about size constraints.
See below for links to the 2025 winning IOCCC entries.
Check out the index.html web pages for each winning entry. They have most of the information you need to compile and run the winning program. Take a look at the winning source code and try to figure out how it works. You might also want to check out the author’s remarks for even more details.
You may download all winning entries in the form of a compressed tarball for this year’s contest.
For IOCCC29, the volume and quality of submissions were at near-historic heights.
IOCCC28 was speculated to have attracted a record number of submissions due to the 4-year absence, allowing authors to refine their submissions, resulting in a higher-than-usual submission quality.
IOCCC29 was the second consecutive contest after the 2020-2024 hiatus. And yet, the number of submissions for IOCCC29 was similar to last year’s contest, and the overall submission quality remained high for this contest. So perhaps the increased submission volume, combined with a higher-than-usual submission quality, is due to factors such as improved website design, increased social media presence, authors building on the ideas of past winning entries, and other factors?
Starting with the close of IOCCC28, the procedures used for closing the contest to new submissions, the judging process, selecting the winning entries, preparing the update to the website, and the process to create the live show on the Our Favorite Universe were carefully documented. And while this documentation required additional time as well as more effort, the documentation process resulted in overall improvements to how the IOCCC is run.
A few days after the presentation of the winning entries for IOCCC29 has been made on the Our Favorite Universe YouTube channel. The recording of the main show will be divided up into individual segments. Then, each winning entry will be updated to include a link to a YouTube segment under a new Award presentation near the top of the winning entry’s index.html page.
We have added fun challenges to this year’s winning entries competition, under the “Judges’ remarks” section. After you figure out what a given winning entry does, we encourage you to attempt the fun challenge.
Some of these challenges are easier than others. In some cases, you’re asked to create an alternative version of prog.c or a related file. In some cases you are asked to produce an explanation about something.
If the fun challenge is still open (check the “A fun challenge” section for the given winning entry), consider submitting a GitHub pull request as a contribution.
If the fun challenge is closed, but you think you have a better solution, consider submitting a GitHub pull request as a contribution. If the IOCCC Judges agree that you solution is better, we will consider it.
If you believe you have an even better (or improvement) to winning entry’s fun challenge, please consider submitting a GitHub pull request, for the IOCCC judges to consider.
The final versions of the IOCCC rules and guidelines that were in effect for this contest were:
The IOCCC rules and guidelines for IOCCC29 represented a substantial rewrite over previous contests, thanks in part to a number of volunteers: giving the IOCCC judges useful edits, text rewrites, consolidation, as well as overall improved organization.
We plan to open IOCCC30 towards the end of 2026 and have the contest run for a similar amount of time, closing sometime towards the end of Q1 2027.
As we perform the actions needed to open IOCCC30, we plan to internally document the process as we did during the closing of IOCCC29.
About two or three weeks after the IOCCC29 winning entries have been posted, and we process some of the early pull requests against the 2025 directory tree, the IOCCC Judges plan to go on an IOCCC vacation.
We had intended to go on an IOCCC vacation after releasing the winners of IOCCC28, but then the efforts to process bug fixes and enhancements to the mkiocccentry repo took so much time that by the time that repo was stable, it was time to open IOCCC29. Therefore, this time, we plan to wait until after the end of our post-IOCCC29 IOCCC vacation before working on any mkiocccentry repo PRs.
While working on creating potential write-ups for submissions that entered the final round of the set of judging rounds:
While the winning entry authors came from locations of previous winning authors, this IOCCC29 had an author - jingp49 from a new location: Taiwan.
This contest saw a Hat trick of Hat-tricks by:
Notable and remarkable winning entries of IOCCC29 include, but are not limited to:
Those are just a few of the many amazing winners of the IOCCC29, so be sure to check out the rest!
As we discussed above, there were quite a few excellent submissions that didn’t quite make the final cut. We truly appreciate the hard work each author put into their entries, but we’re sorry that we can’t award based solely on effort.
We received many great submissions that didn’t quite make the cut as winners. If you submitted something for IOCCC29 that didn’t win, think about polishing your code and giving it another shot for IOCCC30. Interestingly, more than one winner of IOCCC29 was actually an improved version of code that didn’t win in a previous contest.
We know many of you that submitted to the IOCCC put in a ton of effort into your submissions for this year’s IOCCC. We can’t just give out awards to everyone. That would mean taking away from the submissions that we think are the best and deserve to win.
Sometimes, a final round submission might be good enough to be a winning IOCCC entry, only to be beaten by a similar, but slightly better submission. If you think this happened with your submission, consider submitting an enhanced version to the next IOCCC.
PLEASE DO NOT give up hope! There are some submissions that have been submitted with revisions, multiple times before rising to the level of a winning IOCCC entry. You might also want to try with a different type of submission altogether for the next IOCCC.
If you’re not planning to improve and resubmit your non-winning entry for the next IOCCC, you’re welcome to publish it.
Some C compilers aren’t as great as they could be. If yours isn’t working well, you might want to try compiling with an updated version of clang and/or gcc instead.
If you encounter problems in compiling and/or running the winning entries, see the FAQ on:
For additional information on how to submit fixes, see the FAQ on:
Download all winning entries from 2025
Jump to: top