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!
That is correct. It is cheating, but the judges let a small amount of it slide, especially if you come up with an amusing enough justification. I could not get it to fit otherwise!
I'm not a judge or a competitor, but I feel like a little bit of cheating on the rules is within the spirit of the game. Especially if it a) it makes it more obfuscated and b) it wouldn't have fit otherwise.
Wow! And it also implements a very interesting variant of SUBLEQ that is turing complete.
>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
I've spent the past few weeks coming up with my own simple programming language, which compiles to linux/amd64 assembly.
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!
I think I like this idea, but the linked-to Eternal Software Initiative [1] is a bit confusing. There are several different versions of the instructions to decode this, all conflicting.
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.
Maybe answering my own question, but I'm now wondering if the reason that the divide by 4 was chosen (so essentially using byte addressing instead of word addressing) is so that the linker can do symbol fixup / relocation.
What I find fascinating is the fact that you can implement those few lines in an esoteric language such as FRACTRAN or Game of Life and even boot Linux on them. Seems doable now. In theory.
In case anyone was wondering, the IOCCC specifically permits LLM use in their guidelines.
"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."
I'm in the no-AI camp, but for this case, I find it interesting, especially since there's little obfuscated C online, and LLMs cannot infer intention from the actual code. Did you spot any entries with LLM support?
Also, the reverse is interesting: how well can they guess the function of the obfuscated code?
This primarily affects the judges who are opening themselves up to potentially a flood of shoddy code, but given the nature of the contest, I suspect they are very good at differentiating interesting code from low quality code.
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.
I don't think rule 7 would be self-contradictory since you indeed don't own the output of an LLM, but crucially, also no one else owns it. I read that rule as don't submit someone else's code without permission, which isn't violated by using an LLM.
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.
Either you view LLM code as stolen, in which case you cannot get permission of the original owners, or you accept that LLM code is not copyrightable and has no original owners.
Even that requires clicking on unintuitive username links... scrolling to the very bottom of what are sometimes very long pages... and locating the "entry source code" file out of a sometimes very large list of files.
When most visitors obviously just want to glance at the programs and see what they do, this is horrifically organized.
After I made the emulator I trawled GitHub to try to find games it could play within the 32K limit. I found yours - thank you :-) - and the ./try.sh script has an option to download it from GitHub for the user to test.
Back in 2000 I was being interviewed for my first internship, to join a team of C programmers. They showed me one of the winner entries of the prior years, asked me to review the code and left the room. About 5 minutes later they came back:
– 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.
Capture the flag has clear objectives while obfuscated C contest does not. I understand improvements in AI for goal-orientated contests, I am not sure what would be considered improvements in open-ended contests with artistic flair.
Maybe you are asking "can't someone think up a clever idea and ask the AI to implement it according to IOCCC constraints?" And I believe current AI tools are still unable do that at a level that the human judges find worthy.
I love the submissions of IOCCC generally, but the schedule and submission process looks like a mess, is that part of the joke? Or is it just because being consistent and designing a simple process is hard¡
I'm not sure this kind of competition is still meaningful, given that LLM can easily convert a program clearly written in any programming language to the most obfuscated C code, and can still easily verify it's correctness in an automated way.
Yes, you haven’t tried it. LLMs are actually awesome at deobfuscation, but terrible at obfuscation. They just can’t do it yet.
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.
Yes, I’ve tried it. For example, this was my winning entry from a year ago [0].
The LLM only performs trivial obfuscation, not advanced transformations.
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.
One of the main instruments of obfuscation (and the way to get more out of the size constraints) is making the code as short as possible, so in that example you'd prefer
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).
extrano84 already found some errors but also 0 will fail and if x is int (instead of unsigned int) all negative numbers will also fail (but so will the original s-macke obfuscation as well).
Just two months ago I tried to write a short K code with Claude Opus 4.6, only to find that while it had sufficient knowledge about K vocabularies it didn't try to make good use of them. K is, while slightly obscure and obfuscated, a real programming language and certainly better known than obfuscated programming. I don't have high hope for IOCCC-grade obfuscation.
The competition never was about actual obfuscation. If you really just want obfuscation, you are actually writing a DRM system, like Denuvo.
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.
I think what they mean is that this sort of competition makes sense because it's about humans competing against each other, so that, even if we could have LLMs do it, the human version is still what captures our interest. In a similar way, we don't look at chess tournaments with computers playing against each others, but we look at chess grandmaster challenging each other. Even if it has been decades now that computers can beat grandmaster.
yes llm can do it but i think competitions have more to do with developing scientific temperament, competitive mindset and complex problem solving skills. that's why i think they are still relevant and will be relevant for a long time.
> 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.
In my experience LLMs were pretty good at deobfuscating many entries (including mine) but very awful at generating any significantly obfuscated code. So obfuscation can be regarded as a truly humane art---at least for now.
I was talking to a Claude Opus 4.7 chatbot about low-discrepancy sequences and made the mistake of framing a thought experiment as "deceiving" a vendor who owns a scrambler by making a hard to scramble low-discrepancy sequence generator. Admittedly that sounds sketchy but the conversation up to that point--without the explicit framing--was about the same subject just shorn of metaphor. With the framing I got a refusal message that likened my request to Dual_EC_DRBG!
well, at some point I (like after 5 hours of CC) I can swear im looking at pure random coming out. so perhaps the ability of LLMs to make complex stuff even more complex, would be beneficial. obfuscation, after all, is not about having performant code, but an art form, right?
/curious though given the very nice conversation we're having here, why the parent topic gets down-voted. is neither off-topic, nor rude.../
I think the "obfuscation" is actually two very different acts: the apparent obfuscation, that is concerned with randomly looking output, and the information-theoretic obfuscation, that takes computational effort to undo it. Commercial obfuscators are mostly the former, making undo much more annoying but easy to undo if you have a right tool. The obfuscation in IOCCC is much more the latter, requiring the heavy logic and deduction to see through that. In my experience LLMs have been capable of doing the former and undoing the latter but not doing the latter, presumably because any obfuscated program still has to run somehow. Given that this form of obfuscation is not common (and that LLMs tend to work well with established things), your initial statement was I believe quite far-fetched.
It's a bit annoying getting frontier models to even work on IOCCC code because of "safety", but even if you get around that LLMs just aren't very good at it. Obfuscating code involves a level of creativity and deviousness that LLMs struggle to meet.
Maybe, but it can't make the gameboy code look like a gameboy too, unless asked to, and that probably would not work even. That's the difference between an LLM and a human, and that's what make this competition worthwhile.
While this has been downvoted to the death, it is fun to guess how many entries are submitted to each IOCCC. My best guess is around 10^2.5, i.e. 3--400. Rationales:
- 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.
The GameBoy emulator's code also looks like the GameBoy. Slow clap this is insane, definitely my favorite entry.
https://github.com/ioccc-src/winner/blob/master/2025/ncw1/pr...
The author, Nick Craig-Wood, is the creator of rclone!
Glad you enjoyed it :-)
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.
Uh... is this supposed to be valid standalone C?
GCC says there are a bunch of undefined symbols, first one being "R" right in the beginning:
That's defined in Makefile
That is correct. It is cheating, but the judges let a small amount of it slide, especially if you come up with an amusing enough justification. I could not get it to fit otherwise!
I'm not a judge or a competitor, but I feel like a little bit of cheating on the rules is within the spirit of the game. Especially if it a) it makes it more obfuscated and b) it wouldn't have fit otherwise.
"The best kind of correct." -No. 1.0, How Hermes Got his Groove Back, Futurama
https://github.com/ncw/ccforth
https://github.com/ncw/ccforth/tree/master/examples/gameboy
Damn, that is cool! Looking at me typing css & php...
It's an overdone trope in obfuscated programming contests - to make the code look like a picture.
It's a trope, I would not say it's overdone! :)
There’s a company that’s become very successful selling basic sponges shaped like smiley faces.
My favorite is the 366-byte C program emulator that can run Linux and Doom [0]. The VM implements an OISC - a One Instruction Set Computer [1].
[0] https://github.com/ioccc-src/winner/blob/master/2025/cable/p...
[1] https://github.com/ioccc-src/winner/blob/master/2025/cable/R...
Wow! And it also implements a very interesting variant of SUBLEQ that is turing complete.
>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've spent the past few weeks coming up with my own simple programming language, which compiles to linux/amd64 assembly.
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!
https://github.com/skx/s-lang
I think I like this idea, but the linked-to Eternal Software Initiative [1] is a bit confusing. There are several different versions of the instructions to decode this, all conflicting.
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
Maybe answering my own question, but I'm now wondering if the reason that the divide by 4 was chosen (so essentially using byte addressing instead of word addressing) is so that the linker can do symbol fixup / relocation.
I downloaded and built this, and I feel confident in stating that this is the most impressive thing I have ever seen.
Here is the video:
https://www.youtube.com/live/MoWCwZx1Swc?si=eIOlRsKWNKRVRZeB...
What I find fascinating is the fact that you can implement those few lines in an esoteric language such as FRACTRAN or Game of Life and even boot Linux on them. Seems doable now. In theory.
In case anyone was wondering, the IOCCC specifically permits LLM use in their guidelines.
"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."
I'm in the no-AI camp, but for this case, I find it interesting, especially since there's little obfuscated C online, and LLMs cannot infer intention from the actual code. Did you spot any entries with LLM support?
Also, the reverse is interesting: how well can they guess the function of the obfuscated code?
This primarily affects the judges who are opening themselves up to potentially a flood of shoddy code, but given the nature of the contest, I suspect they are very good at differentiating interesting code from low quality code.
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.
So it turned into an LLM-gymnastics competition?
Rule 7 would be self-contradictory if "tools" include AI.
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)?
I don't think rule 7 would be self-contradictory since you indeed don't own the output of an LLM, but crucially, also no one else owns it. I read that rule as don't submit someone else's code without permission, which isn't violated by using an LLM.
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.
Either you view LLM code as stolen, in which case you cannot get permission of the original owners, or you accept that LLM code is not copyrightable and has no original owners.
In both cases you cannot get permission.
But, in the second case, you don't need permission. This is the crucial point.
The website itself is obfuscated, it’s not easy to find the C sources at all!
Can jump straight to https://www.ioccc.org/2025/#inventory
Even that requires clicking on unintuitive username links... scrolling to the very bottom of what are sometimes very long pages... and locating the "entry source code" file out of a sometimes very large list of files.
When most visitors obviously just want to glance at the programs and see what they do, this is horrifically organized.
It's really hard to navigate. I cannot work out what the contest is; it seems to assume you know what it is already.
Apparently, if your not cool enough to know how to get in the club, you are not cool enough to be in the club.
The first sentence links to the section that lists the winning entries, each of which have a “C code” link in the top right.
I with the Underhanded C Contest would come back, it was far more interesting to me. No disrespect intended to the Obfuscated C competitors.
There's a Frieren [1] reference in there! https://www.ioccc.org/2025/yang2/index.html
One of the main characters is called Fern, and she almost exclusively uses the common offensive magic of Zoltraak.
[1] https://en.wikipedia.org/wiki/Frieren
There are two Frieren references, the other one is https://www.ioccc.org/2025/yang1/index.html
OMG, my game boy game of life implementation is included in one of the winning entries!
After I made the emulator I trawled GitHub to try to find games it could play within the 32K limit. I found yours - thank you :-) - and the ./try.sh script has an option to download it from GitHub for the user to test.
It's after the fact now, but I maintain a list of 32K Game Boy games on itch.io here: https://itch.io/c/3521183/game-boy-32k-roms
Great project btw
Back in 2000 I was being interviewed for my first internship, to join a team of C programmers. They showed me one of the winner entries of the prior years, asked me to review the code and left the room. About 5 minutes later they came back:
– 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.
OOOOOH! IOCCC is back!
All my love <3 <3 <3 to organizers, thank you for continuing the IOCCC context, please never go away again!
Wait, I kind of don't get it.
So Obfuscated C Code Contest works but Capture the Flag doesn't? Because of AI?
https://twit.tv/posts/tech/ai-disrupts-capture-flag-what-mea...
Capture the flag has clear objectives while obfuscated C contest does not. I understand improvements in AI for goal-orientated contests, I am not sure what would be considered improvements in open-ended contests with artistic flair.
Maybe you are asking "can't someone think up a clever idea and ask the AI to implement it according to IOCCC constraints?" And I believe current AI tools are still unable do that at a level that the human judges find worthy.
I love the submissions of IOCCC generally, but the schedule and submission process looks like a mess, is that part of the joke? Or is it just because being consistent and designing a simple process is hard¡
There's another contest called Underhanded C that I enjoyed a lot reading, but it has been inactive for a decade at this point...
I'm not sure this kind of competition is still meaningful, given that LLM can easily convert a program clearly written in any programming language to the most obfuscated C code, and can still easily verify it's correctness in an automated way.
Do I miss anything?
Yes, you haven’t tried it. LLMs are actually awesome at deobfuscation, but terrible at obfuscation. They just can’t do it yet.
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.
They should train on some of my colleagues code - they have an inate skill of turning anything simple and clear into a mindboggling mess
Lol you're so much smarter, nice
> They just can’t do it yet.
Have you tried it or are you guessing this?
Yes, I’ve tried it. For example, this was my winning entry from a year ago [0]. The LLM only performs trivial obfuscation, not advanced transformations.
For example:
can be transformed into: 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...
One of the main instruments of obfuscation (and the way to get more out of the size constraints) is making the code as short as possible, so in that example you'd prefer
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).I checked this in an online C-compiler and it is not equivalent to x==1 | x==2.
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.
extrano84 already found some errors but also 0 will fail and if x is int (instead of unsigned int) all negative numbers will also fail (but so will the original s-macke obfuscation as well).
It's pretty easy to see what that does though, even if it is shorter. Wouldn't the other approach be more obfuscated?
Not sure what you mean by advanced transformations but I got these versions from ChatGPT without explicit instructions.
But then we all know that LLM has come a long way since one year ago.
Are you sure they still can't do it?
Just two months ago I tried to write a short K code with Claude Opus 4.6, only to find that while it had sufficient knowledge about K vocabularies it didn't try to make good use of them. K is, while slightly obscure and obfuscated, a real programming language and certainly better known than obfuscated programming. I don't have high hope for IOCCC-grade obfuscation.
The competition never was about actual obfuscation. If you really just want obfuscation, you are actually writing a DRM system, like Denuvo.
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.
> Do I miss anything?
That human art is worth the humanity in the art.
As soon as anything is automated, it's worth nothing.
Chess?
I think what they mean is that this sort of competition makes sense because it's about humans competing against each other, so that, even if we could have LLMs do it, the human version is still what captures our interest. In a similar way, we don't look at chess tournaments with computers playing against each others, but we look at chess grandmaster challenging each other. Even if it has been decades now that computers can beat grandmaster.
yes llm can do it but i think competitions have more to do with developing scientific temperament, competitive mindset and complex problem solving skills. that's why i think they are still relevant and will be relevant for a long time.
You are missing that the IOCCC isn’t just about obfuscation, that the judges have taste.
Where's the fun in that?
> Do I miss anything?
School ? /s
Tis a pity to not have LLMs compete, given level of obfuscation they be capable of.
LLMs are allowed. [0]
> 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.
[0] https://www.ioccc.org/faq.html#ai
In my experience LLMs were pretty good at deobfuscating many entries (including mine) but very awful at generating any significantly obfuscated code. So obfuscation can be regarded as a truly humane art---at least for now.
I pointed Claude Opus 4.7 at my Forth entry ( https://github.com/ioccc-src/winner/blob/master/2025/ncw3/pr... ) and it absolutely refused to have anything to do with it citing security violations and accusing me of creating malware :-)
Claude seems OK with it now, so I don't know whether that was a glitch but it was quite funny.
I was talking to a Claude Opus 4.7 chatbot about low-discrepancy sequences and made the mistake of framing a thought experiment as "deceiving" a vendor who owns a scrambler by making a hard to scramble low-discrepancy sequence generator. Admittedly that sounds sketchy but the conversation up to that point--without the explicit framing--was about the same subject just shorn of metaphor. With the framing I got a refusal message that likened my request to Dual_EC_DRBG!
well, at some point I (like after 5 hours of CC) I can swear im looking at pure random coming out. so perhaps the ability of LLMs to make complex stuff even more complex, would be beneficial. obfuscation, after all, is not about having performant code, but an art form, right?
/curious though given the very nice conversation we're having here, why the parent topic gets down-voted. is neither off-topic, nor rude.../
I think the "obfuscation" is actually two very different acts: the apparent obfuscation, that is concerned with randomly looking output, and the information-theoretic obfuscation, that takes computational effort to undo it. Commercial obfuscators are mostly the former, making undo much more annoying but easy to undo if you have a right tool. The obfuscation in IOCCC is much more the latter, requiring the heavy logic and deduction to see through that. In my experience LLMs have been capable of doing the former and undoing the latter but not doing the latter, presumably because any obfuscated program still has to run somehow. Given that this form of obfuscation is not common (and that LLMs tend to work well with established things), your initial statement was I believe quite far-fetched.
I mean they can generate 1 million lines of code, it's obfuscation by brute force, how are you going to read that if not with another LLM
IOCCC disallows such entries for the obvious reason ;-)
It's a bit annoying getting frontier models to even work on IOCCC code because of "safety", but even if you get around that LLMs just aren't very good at it. Obfuscating code involves a level of creativity and deviousness that LLMs struggle to meet.
Maybe, but it can't make the gameboy code look like a gameboy too, unless asked to, and that probably would not work even. That's the difference between an LLM and a human, and that's what make this competition worthwhile.
So like at a film festival, 90% of the entries won a price, but unlike a film festival there's not a single best. Weird, like modern education.
While this has been downvoted to the death, it is fun to guess how many entries are submitted to each IOCCC. My best guess is around 10^2.5, i.e. 3--400. Rationales:
- 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.