5 ms·
ASCII animated donut in obfuscated C
- edge17 15y agothat was cool for a saturday afternoon. extra points for creative packaging.
- donut 15y agoHere's a more readable version: https://gist.github.com/1073922 https://gist.github.com/1073922
- pavel_lishin 15y agoI kind of want someone to write some readable code that displays a spinning 3D representation of said readable code.
- a1k0n 15y agoA 3D quine? I've considered it. I have a blog post about something completely unrelated to obfuscated C coming up, but maybe after that I'll make an attempt. If nobody beats me to it.
- donut 15y agoI'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 15y agoRe: 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.
- deleted 15y ago[deleted]
- jgeralnik 15y agoWow. Just wow. Compile this. Run this. Just wow.
- KonradKlause 15y agoI'm totally impressed that b[o] = ".,-~:;=!*#$@"[N > 0 ? N : 0]; is allowed in C.
- jurjenh 15y agoI 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.html 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.
- a1k0n 15y ago<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.
- enneff 15y agoIt's not at all complicated. Most of it is a string literal. 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]
- rhdoenges 15y agoHis 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 15y agoHaha. 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 http://a1k0n.net/2006/09/20/obfuscated-c-donut-2.html
- donut 15y agoDude, I'm gonna have to decipher that one too??
- a1k0n 15y agoWell, since you seem to have signed up to HN just for this (and have done an admirable job already)... I'm afraid so.
- caf 15y agoThis one actually has a bug in it - you evaluate _/6 and _++ without an intervening sequence point.
- zkarcher 15y agoI 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 15y agoYou 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.
- jwecker 15y agoThey're just warnings. I got the same ones but it still created a perfectly good executable. (you kind of have to assume warnings with obfuscated code :)
- JonnieCache 15y agoIf this is the kind of thing you're into, check out the The International Obfuscated C Code Contest at http://www.ioccc.org 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__ 15y agoOn my machine, this comes up with 2.50.
- jessedhillon 15y agoOn mine it's 0.250
- __rkaup__ 15y agoYou need to change the #define to #define _ F-->00||F-OO--; See http://ioccc.org/1988/westley.hint http://ioccc.org/1988/westley.hint
- john2x 15y agoHow does one go about making stuff like this?
- JonnieCache 15y agoI 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.
- a1k0n 15y agoIt's really not that hard, once you have some idea of the kind of program you're writing. Write it out normally, and start eliminating everything that can be eliminated (in particular, whitespace, braces, if statements that can be conditionals, subroutines, variables, etc). Takes some ingenuity with loops but it's mostly straightforward. 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.
- memset 15y agoVery 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 https://gist.github.com/1074316