

ASCII animated donut in obfuscated C - yogsototh
http://a1k0n.net/2006/09/15/obfuscated-c-donut.html

======
rhdoenges
His entire blog is a pure obfuscated goldmine. Just look at his footer:

    
    
        _=0;k;main(){while(_<641){for(k=0;"##K#8(38D-##C]L5870.X7\\M_b;90\\"
        "MC-M/NZGB6Q,I0VGB6a0FbN<VG.6Q\\bNb7^@`X=N@`XQaOVX:^]NX=:Z8PY]B`:>P"
        "NY8^$#SM):XA"[_/6]-35>>_++%6&1;k++);putchar(k[" _/\\\n,`)('<-"]);}}

~~~
a1k0n
(also, click on it)

~~~
pbhjpbhj
It's really cool. This should be at about +8 to +12 IMO.

(Sorry I hate this sort of thing but without comment scores, yes I'm still
riding that horse, no one can see that anyone agrees with you).

------
a1k0n
Haha. I don't get why this particular one attracts so much attention, as it
was my first one and is pretty amateurish compared to this one:

<http://a1k0n.net/2006/09/20/obfuscated-c-donut-2.html>

~~~
donut
Dude, I'm gonna have to decipher that one too??

~~~
a1k0n
Well, since you seem to have signed up to HN just for this (and have done an
admirable job already)... I'm afraid so.

------
donut
Here's a more readable version:

<https://gist.github.com/1073922>

~~~
donut
I've updated the code to be even more readable, and as an aside, made it more
optimal.

sin(A) and sin(B) were being computed repeatedly in the most inner of inner
loops, which I pulled out, because A and B don't change in the middle. sin(j)
and cos(j) was being computed for every i, even though j wasn't changing. And
the intensity was being computed even if the pixel was going to appear beyond
the buffer (or wasn't going to appear at all because of a closer pixel in the
z buffer).

I also refactored parts of it, and gave names to some constants which you can
tweak for fun. DELTA_I can be increased without apparent detriment to image
quality. I can't think of good names for the two constants in the middle of
the code though: 2 and 5. Are those the minor and major radius of the donut?

~~~
a1k0n
Re: repeatedly computing sin(A)/sin(B)/etc: I don't remember why I did that,
as it was five years ago, but it was probably intentional just to move code
around so it fit within the shape. Or it was an oversight.

IIRC, yes, 5 and 2 are the major and minor radii, meaning 5 is the radius of
the ring at the center of the donut (a torus of thickness 0, as it were) and 2
is the thickness -- the radius of the circle extruded around the central ring.

------
JonnieCache
If this is the kind of thing you're into, check out the The International
Obfuscated C Code Contest at <http://www.ioccc.org>

Some of the submissions are absolutely fiendish. Fabrice Bellard's are
particularly interesting, just like all his other work.

See if you can work out what westley.c from 1988 does:

    
    
        #define _ -F<00||--F-OO--;
        int F=00,OO=00;main(){F_OO();printf("%1.3f\n",4.*-F/OO/OO);}F_OO()
        {
                    _-_-_-_
               _-_-_-_-_-_-_-_-_
            _-_-_-_-_-_-_-_-_-_-_-_
          _-_-_-_-_-_-_-_-_-_-_-_-_-_
         _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
         _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
        _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
        _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
        _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
        _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
         _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
         _-_-_-_-_-_-_-_-_-_-_-_-_-_-_
          _-_-_-_-_-_-_-_-_-_-_-_-_-_
            _-_-_-_-_-_-_-_-_-_-_-_
                _-_-_-_-_-_-_-_
                    _-_-_-_
        }

~~~
__rkaup__
On my machine, this comes up with 2.50.

~~~
jessedhillon
On mine it's 0.250

~~~
__rkaup__
You need to change the #define to

#define _ F-->00||F-OO--;

See <http://ioccc.org/1988/westley.hint>

------
KonradKlause
I'm totally impressed that

b[o] = ".,-~:;=!*#$@"[N > 0 ? N : 0];

is allowed in C.

~~~
jurjenh
I had no idea that printing something like "\x1b[2J\x1b[H" can clear the
screen - with a bit of googling I found out that this is not that unusual a
command, but it still took a little reading to figure it out! [1]

Looks like the rest of the code is for generating the donut. Quite a bit of
math involved - too much for a sunday morning to look into and attempt to
decipher!

[1]
[http://www.codeguru.com/forum/archive/index.php/t-311110.htm...](http://www.codeguru.com/forum/archive/index.php/t-311110.html)
explains it quite well:

Those are so-called ANSI terminal escape sequences - there is a whole list of
them. Hex 1B is the escape character, the characters after that determine the
action (clearing the screen, changin text color, moving the cursor etc.) Well,
and "[2J" is the sequence for clearing the screen.

~~~
a1k0n
<ESC>[H ("home") moves the cursor to the upper-left hand corner, so I
initially clear the screen and then use "home" to do the animation.

An alternative method to animate ascii stuff, used in the Yahoo logo, is just
to cursor-up 25 lines (or whatever) with <ESC>[25A between frames. That way it
doesn't have to clear the screen and you can see your command history, etc.

------
zkarcher
I can't compile this. What am I doing wrong? Here is the output:

$ gcc -o donut donut.c -lm

donut.c:1: warning: data definition has no type or storage class

donut.c: In function ‘main’:

donut.c:4: warning: incompatible implicit declaration of built-in function
‘printf’

donut.c:5: warning: incompatible implicit declaration of built-in function
‘memset’

~~~
Abica
You need to go add:

    
    
      #include <stdio.h> 
      #include <string.h>
    

and then add int directly before the k on the first line of the donut.

~~~
zkarcher
That did it. Thanks!

------
jgeralnik
Wow. Just wow. Compile this. Run this. Just wow.

------
memset
Very cool - I've never played with sending special terminal characters before
to clear the screen and the like; like others, I will definitely add this to
my repertoire!

My suggestion for deciphering it - let's not forget about `indent`!

Both iterations of the donut.c program: <https://gist.github.com/1074316>

------
edge17
that was cool for a saturday afternoon. extra points for creative packaging.

------
john2x
How does one go about making stuff like this?

~~~
JonnieCache
I imagine it requires an absolute mastery of, but also a certain profound
contempt for the C language.

If preprocessors were people, the organisers of the IOCCC would be up before
the hague.

