ASCII animated donut in obfuscated C
a1k0n.net
a1k0n.net
_=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,`)('<-"]);}}(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).
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?
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.
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()
{
_-_-_-_
_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_-_-_-_-_
_-_-_-_-_-_-_-_
_-_-_-_
}#define _ F-->00||F-OO--;
$ 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’
#include <stdio.h>
#include <string.h>
and then add int directly before the k on the first line of the donut. ./donut
:)TBH, this is beautiful.
b[o] = ".,-~:;=!*#$@"[N > 0 ? N : 0];
is allowed in C.
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... 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.
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.
This is an assignment to index o of the array b
b[0] =
this is the string ".,-~:;=!*#$@"
and this is indexing into the string literal with N, or 0 if N is less than 0. [N > 0 ? N : 0]My suggestion for deciphering it - let's not forget about `indent`!
Both iterations of the donut.c program: https://gist.github.com/1074316
If preprocessors were people, the organisers of the IOCCC would be up before the hague.
In this particular example the only really odd thing about it is the lighting calculation, which is an algebraically simplified dot product of the light direction (0, 1, -1) IIRC with the surface normal of a torus (gradient of the equation defining the shape). The derivation of that is long gone but it wasn't hard math.