Possibly The World's Smallest Fractal Viewer
Sun 06 February 2022Why?
Why not? Ever since I learned about code obfuscation through a programmer on YouTube known as "Bisqwit", I've been obsessed with the low-level optimizations you can do to make a program as unreadable as possible in the shortest amount of characters.
At first, I wanted to make a fractal viewer in C that printed in ASCII, but then I realized this was the perfect candidate for some code obfuscation. During my free time in school, I'd shorten this program character by character and it kept getting shorter and shorter.
I can't remember what it looked like when I first started to shorten it, but it was around 234 characters from when I introducted the idea to some friends. The first iteration I have of it is at 188 characters, which looks like:
main(p){for(p=0;p<3200;++p){int i=0;float x=0,y=0,r;while(i<95){r=x*x-y*y;y=2*x*y;x=r;if(x*x+y*y>16)break;++i;x+=(p%80-60)/30.f;y+=(p/80.f-20)/15;}if(p%80==0)putchar(10);putchar(32+i%5);}}
Early Optimizations
At 188 characters, I thought that the if(p%80==0)putchar(10);
statement seemed a bit verbose, so I happily toook use of the ternary operator to shorten
the whole print statement to just putchar(p%80==0?10:32+i%5);
. Cool, that shaved off 12
whole characters! I also then realized this can be shortened down ever further by swapping
the order of the ternary operator, and removing the conditional completely. Now it looks like:
putchar(p%80?32+i%5:10);
. That shaved off another 3 characters.
Fine Tuning
Unfortunately, the optimizations are starting to be harder to find, however
not impossible. In the first for loop, the p=0
in for(p=0;p<3200;++p)
is a little redundant,
because I do the B-style declaration for p
, which initializes it to 0. With this, the ++p
can
actually be thrown into our print statement to save a character. The print statement now
looks like: putchar(p++%80?32+i%5:10);
That brings us down to 169 characters. Nice.
I can also save another character by placing the ++i
into the while(i<95)
statement.
To save 4 more characters, I can declare i
using the B syntax, however this program
no longer compiles in clang. The main declaration now looks like main(p,i)
. However,
i
isn't initialized to 0, so i threw it in the declaration of x
. float x=i=0,y=0,r;
We are down to the final 2 characters we need to optimize.
Conclusion
We can change our for(;i<95;++i)
to for(;++i<95;)
to save a character, and for our last change, our multiplication of y
can be shortened to y*=2*x;
from y=2*x*y;
. That leaves us with the 160
character fractal viewer that looks like this:
main(p,i){while(p<3200){float x=i=0,y=0,r;for(;++i<95;){r=x*x-y*y;y*=2*x;x=r;if(x*x+y*y>16)break;x+=(p%80-60)/30.;y+=(p/80.-20)/15;}putchar(p++%80?32+i%5:10);}}
I tried to get this to be my senior quote, but I guess the people that work on the yearbook either don't have a sense of humor, or didn't have gcc to make sure I wasn't printing inappropriate body parts to the screen. Otherwise, I'm still proud of this creation, and maybe once I make business cards in the future, I'll be able to fit this on it.
More Information
Shortly after I wrote this article, I made a short youtube video explaining how this short program works. The video goes pretty fast, so you may need to pause to read the explanations.