Add preview of 1984-2019
The 2020 winners are hinted it, but the source code is not there,
nor are the hints. Someone could look into the HTML and
see what was commented out, but that is not a problem because
WHO won is known and the name of their AWARD is known already.
Moreover a number of the winners have talked about what their
entirs do, so the commented out spoiler text is not a bit problem.
One will find HTML commented out with:
<!-- XXX remove when 2020 is ready
2020 links here
XXX remove when 2020 is ready -->
The "XXX remove when 2020 is ready" string is found at the
start and end comment blocks. Again, soneone could read
what was commented out, but that is OK since most of that
information is known or can be known. The following files
have such HTML comment blocks in them.
./winners.html
./years-spoiler.html
./years.html
In addition, ./all/summary.txt was modified to not
include the 2020 entries for the momemt.
The 2020 winner code AND write-ups are NOT part of this set.
p.s. The all/all.tar.bz2 does not contain the 2020 source code (yet?).
This commit is contained in:
1 parent
28efc67f5d
commit
c0663537cb
1683 files changed
+220064
No files matched your search
@@ -0,0 +1,41 @@
|
||||
# 2006 makefile
|
||||
#
|
||||
# Copyright (C) 2006-2009, Landon Curt Noll, Simon Cooper, Peter Seebach
|
||||
# and Leonid A. Broukhis. All Rights Reserved. Permission for personal,
|
||||
# educational or non-profit use is granted provided this copyright and
|
||||
# notice are included in its entirety and remains unaltered. All other
|
||||
# uses must receive prior permission from the contest judges.
|
||||
|
||||
# Special flags for this entry
|
||||
#
|
||||
LOCAL_FLAGS= -O3 `sdl-config --libs --cflags`
|
||||
|
||||
# For Mac OS X with Darwin Ports installed
|
||||
# LOCAL_FLAGS= -O3 `/opt/local/bin/sdl-config --libs --cflags`
|
||||
|
||||
# Data files for this entry
|
||||
#
|
||||
DATA=
|
||||
|
||||
|
||||
build: ${ENTRY} ${ENTRY}_orig
|
||||
|
||||
|
||||
clean:
|
||||
-${RM} ${ENTRY} ${ENTRY}_orig
|
||||
|
||||
|
||||
clobber: clean
|
||||
|
||||
|
||||
alt:
|
||||
|
||||
|
||||
data:
|
||||
|
||||
|
||||
${ENTRY}: ${ENTRY}.c ${DATA}
|
||||
${CC} ${LOCAL_FLAGS} ${ENTRY}.c -o ${ENTRY}
|
||||
|
||||
${ENTRY}_orig: ${ENTRY}_orig.c
|
||||
${CC} ${LOCAL_FLAGS} ${ENTRY}_orig.c -o ${ENTRY}_orig
|
||||
@@ -0,0 +1,185 @@
|
||||
# Best Compiled Graphics
|
||||
|
||||
Maurizio Monge
|
||||
Department of Mathematics
|
||||
University of Pisa
|
||||
Pisa
|
||||
Italy
|
||||
maurizio.monge at gmail dot com
|
||||
|
||||
## Judges' comments:
|
||||
|
||||
### To build:
|
||||
|
||||
echo Make sure you have the SDL development environment installed
|
||||
make monge
|
||||
|
||||
### Try:
|
||||
|
||||
./monge "z = 0" "z = z*z*z + c; Abs2(z) < 4"
|
||||
|
||||
For those who are familiar with the previous IOCCC winners, this program
|
||||
is best described as "1994/tvr meets 2001/bellard". Here you have
|
||||
mouse-manipulated fractals AND generated binary code, all in one package.
|
||||
|
||||
A more appropriate award could have been "Best abuse of the
|
||||
rules", because on a non-x86-based architecture this program
|
||||
is, quite predictably, a dud.
|
||||
|
||||
At the time of judging we were too mesmerized by the graphics
|
||||
to realize it; and, after all, this entry does take a special
|
||||
effort to work on both i386 and x86_64. Portable it is! :)
|
||||
|
||||
## Author's comments:
|
||||
|
||||
### For the impatients
|
||||
|
||||
0. Compile using the Makefile, or just run:
|
||||
|
||||
gcc monge.c -o monge -O3 `sdl-config --libs --cflags`
|
||||
|
||||
1. Run:
|
||||
|
||||
./monge "z = 0" "z = z*z + c; Abs2(z) < 4"
|
||||
|
||||
2. Keep clicked with left or right button to zoom in or out.
|
||||
|
||||
3. Use the numpad '+' and '-' to increase/decrease the iteration
|
||||
count when needed.
|
||||
|
||||
4. Enjoy, unless you're more interested in trying to understand
|
||||
how it works. :)
|
||||
|
||||
### Introduction
|
||||
|
||||
This is a fractal generator that supports custom formulas and
|
||||
real time zoom. The program needs to be run with two arguments,
|
||||
the first being a semicolon separated list of assignments to
|
||||
do once per pixel, and the second a semicolon separated list
|
||||
of assignents and conditions that will be executed (and conditions
|
||||
checked) for each iteration (up to the maximum). Using the
|
||||
left and right mouse buttons you will be able to zoom in and
|
||||
out (a la Xaos), the zooming algorithm is a bit slower than
|
||||
Xaos's but it should give slightly better results.
|
||||
|
||||
Formulas can use all a-z (lowercase) variables, and the special
|
||||
variables 'c' and 'i' are respectively set by default to the
|
||||
complex coordinate of the pixel and to the complex imaginary 'i'.
|
||||
|
||||
All the constant numbers will be interpreted as real double
|
||||
values. Each expression must be an assignment ([variable] =
|
||||
[expr]) or a comparison with < or > ([expr1] < or > [expr2]),
|
||||
and you can add spaces as you like (as understood by the c
|
||||
function 'isspace').
|
||||
|
||||
Supported operations and functions are:
|
||||
|
||||
> Operation | Description
|
||||
> :-------- | :----------
|
||||
> +,-,*,/ | Arithmetic operations, priority of *,/ over +,- is respected.
|
||||
> <,> | Compares the real parts of two complex numbers (the imaginary part is ignored). Any number of conditions is allowed, the iteration will just stop as soon as one of them fails.
|
||||
> Abs2 | Calculates the squared norm, ie: Abs2(a+b*i) is (a*a+b*b)+0*i
|
||||
> Re | Extract the real part, ie: Re(a+b*i) is a+0*i
|
||||
> Im | Extract the imaginary part, ie: Im(a+b*i) is b+0*i
|
||||
> Exp | Calculates the complex exponential, ie Exp(a+b*i) is e^a*(cos(b)+sin(b)*i)
|
||||
> Ln | Calculates the principal value of the natural logarithm, ie Ln(a+b*i) is ln(a*a+b*b)/2 + atan(b/a)*i
|
||||
|
||||
Here are a few examples of fractals you can draw:
|
||||
|
||||
- Mandelbrot:
|
||||
|
||||
./program "z=1" "z=z*z+c; Abs2(z)<4"
|
||||
|
||||
- Mandelbrot (return time variation):
|
||||
|
||||
./program "z=c" "z=z*z+c; Abs2(z-c)>0.0001"
|
||||
|
||||
- Julia, for c=0.31+i*0.5:
|
||||
|
||||
./program "z=c; c=0.31+i*0.5" "z=z*z+c; Abs2(z)<4"
|
||||
|
||||
- Julia (return time variation), for c=0.31+i*0.5:
|
||||
|
||||
./program "z=c; c=0.31+i*0.5" "z=z*z+c; Abs2(z-c)>0.0001"
|
||||
|
||||
- Newton, for x^3-1:
|
||||
|
||||
./program "z=c" "p=z; z=0.6666*z+0.3333/(z*z); Abs2(p-z) > 0.001"
|
||||
|
||||
- Newton-Mandelbrot:
|
||||
|
||||
./program "z=0" "p=z; z=z-(z*z*z + (c-1)*z - c)/(3*z*z+c-1); Abs2(p-z) > 0.001"
|
||||
|
||||
- Phoenix, Mandelbrot version:
|
||||
|
||||
./program "z=0; q=0" "t=z; z=z*z+Re(c)+Im(c)*q; q=t; Abs2(z)<4"
|
||||
|
||||
- Phoenix, Julia version for c=0.56667-i*0.5
|
||||
|
||||
./program "z=c; c=0.56667-i*0.5; q=0" "t=z; z=z*z+Re(c)+Im(c)*q; q=t; Abs2(z)<4"
|
||||
|
||||
### Compilation and portability
|
||||
|
||||
This program will only work on x86 (with an x87 FPU) or x86_64 machines,
|
||||
and requires the SDL library.
|
||||
|
||||
Another system requirement is the mmap function (as #define'd
|
||||
at the beginning of the program). If it is not available the
|
||||
macro M(a) will have to be replaced with a system dependent
|
||||
function that allocates readable, writable *AND* executable
|
||||
memory (it will not be possible to make this program run on
|
||||
paranoid systems (like OpenBSD IIRC) do not allow rwx memory).
|
||||
|
||||
However i was able to compile and make work the program under
|
||||
Linux (Debian/x86 and OpenSuSE/x86_64) and under Cygwin/x86. A
|
||||
friend of mine was able to make it work under MacOSX too.
|
||||
|
||||
If you want you can change the window width and height, or the default
|
||||
number of iterations (that one can be tweaked at runtime, anyway) by
|
||||
changing the definitions of W, H and I at the beginnning of the code.
|
||||
|
||||
### Caveats (i just a selected few of them!)
|
||||
|
||||
- The zooming speed depends on the speed of the computer.
|
||||
- Incorrect formulas will ungracefully crash the program.
|
||||
- Many SDL identifiers are hardcoded as number, this is safe up to ABI
|
||||
incompatibility.
|
||||
- Better optimization could be done treating known real numbers as just one
|
||||
double, instead of adding a 0 imaginary part to treat them as complex
|
||||
numbers.
|
||||
- There should be some way to switch from Mandelbrot to Julia with choosen
|
||||
parameter.
|
||||
|
||||
### Spoiler
|
||||
|
||||
Sure, i don't want to deprive you of the pleasure of digging
|
||||
into the infernal mess created by my corrupted mind (writing
|
||||
this remark i noticed that i was ending senteces with ';' instead
|
||||
that with '.', and i worried for my sanity), but just in case...
|
||||
|
||||
I used many obfuscation techniques, including a few ones that
|
||||
are different from the tricks used in most common IOCCC program
|
||||
(more 'highlevel', in the sense that they require an understanding
|
||||
of how all the program works to be worked out).
|
||||
|
||||
This program is a formula parser that outputs machine code that
|
||||
calculates the formula and check the given conditions. The
|
||||
machine code targets the x87 stack based FPU, and it is almost
|
||||
identical for x86 and x86_64 (except for the comparison
|
||||
instructions, that have to be generated differently). The
|
||||
program keeps track of the FPU stack (the FPU has a cyclic stack
|
||||
of 8 registers) and will automatically swap to and from the
|
||||
main memory when required (ie, adds instructions to the generated
|
||||
machine code to take care of this issue).
|
||||
|
||||
The formulas are parsed recursively and machine code for the
|
||||
inner iteration loop is also generated.
|
||||
|
||||
After generating the machine code, a big event loop creates (or
|
||||
zooms into) the factal executing the generated code when needed,
|
||||
and then waits for input events.
|
||||
|
||||
The zooming algorithm works by remembering for each pixel the
|
||||
floating point offset to where the value was actually calculated.
|
||||
When zooming, the best match is searched, and if the offset is
|
||||
too big (>1) the pixel is recalculated.
|
||||
@@ -0,0 +1,64 @@
|
||||
#include <stdlib.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
#define M(a) mmap(0, a, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0)
|
||||
|
||||
#define W 400
|
||||
#define H 300
|
||||
#define I 128
|
||||
|
||||
#define L char*
|
||||
#define _ Sint32
|
||||
#define h(a,b) for(a=0; a<b; a++)
|
||||
#define O while(
|
||||
#define b D[j][i][
|
||||
#define J(b) a(#b)
|
||||
|
||||
SDL_Event
|
||||
e;
|
||||
SDL_Surface
|
||||
*F; float f, m,
|
||||
n,d,D[H][W][6],
|
||||
v; L A; L X; L
|
||||
V,G[H][W]; L
|
||||
E ; L Q; double
|
||||
R=2/( W-1. ),T=2/(H-1.),c,g, z=2 ,*
|
||||
K,*Z,*S; _ B, C, o,i,j,q,k,l,x,y,*u,Y=512; P(
|
||||
L f){ *(u=V)=f-X-5; V+=4; } a(L e){ O l=*e++)
|
||||
l-38?l==36?s(2),o--:l-37?*V++=l==35?k=*e++
|
||||
,k* 16+*e++-81:l^128:o>7?J(Yv]#JJ), P(S++):o++
|
||||
:s(4); } s(_ n){ O o<n){ J(]#IB); P(--S); J(]);
|
||||
*V ++=217+o++; } } p(L e,_ q,L *t){ _ x=9; do{ A="%]#IB"
|
||||
; _ i =*e; 5==q?*K=strtod(e,t),e-*t?e=*t,a(A),P(K++), J(%Yn)
|
||||
: i<6 ?p ( e+1,4,t),i-5||J(Y`YIY`YI), e=*t:i>96?a(A),P(Z+i-97),a
|
||||
(A),P (Z+*e++-71) :(p(index( e, 40)+1,1,t), i^82?i^73?i^65?i^69?i^76?1:J
|
||||
(%YhY`%YmY}]YYB%YBXHYIXH$^A$YqYJ$Ys):J(%Y{YJ%Yj^IY@Y|\\iYIYp%Yh$^AY}$]Y\\J$^I)
|
||||
: J(XHYIXH^AYn):J(]YYn) : J (]XYn),e= index( *t,41 )+ 1): p ( e , q+ 1, &e); A
|
||||
= "&%YCXJYLXIYK\\J$^I$^k$^A"; (x -=3)<1?J(&]X]Y),1L <<31<0? J(Zi_`#JO):J(_i]X),x
|
||||
?J (#HH):J(#HC),J(#AD#IJPC) ,o-=4:--x?--x?--x?x-3?J(&%YA%YAXHYIXH^AYh$^q\\J$^IY`)
|
||||
, a(A): 1:a(A):J(&$^j$^j):J(&$^B$^B); } O q==(x=*(*t=e++))/2); } main(_ r,L*U){
|
||||
X =V=(Z =(S=(K=M(Y*32))+Y)+ Y)+Y; J(h#AA#AA#AA#AA#FJ:+-*/); h(q,2){ A =E =Q=U[ q+1]; O * A=*A^B++
|
||||
[ ";<>+-*/" ]?*A:B,(B%=7)||(isspace(*E=*A)||++E,*A++)); E=V; O B=*Q){ if(Q[1]-61)p(
|
||||
Q,1,&Q); else{ p(Q+2,1,&Q); h(j,2){ J(]#JJ); P(Z+B-71-j*26); o--; } } *Q&&Q++; }
|
||||
} J(#PPJ#AP#IF); P (E -V+X +1); J(#IJPC); 0[u =X+7] =I; SDL_Init( 32 ); F=
|
||||
SDL_SetVideoMode(W,H,8 ,0); A=F->pixels; B=F->pitch; O 1){ C^=3; h(j,H)h(i,
|
||||
W )b C+2]=9; if(r=(k =SDL_GetMouseState(&x,&y))&5){ f=z/50; f=k&1 ?f:-f ;
|
||||
c+=(x*T-T/R)*f; g += f*y*T-f; z*=f=1-f/z; v=1/f; h(j,H)h(i,W)h(q,4){ k=
|
||||
x+(i- x)* f +q/2; l=y+(j-y)*f+q%2; if(k>=0&k<W&l>=0&l<H){ m=x+(k+D[
|
||||
l][k ][ 3-C]-x)*v-i; n=y+( l+D[l][k][4 -C]-y)*v-j; d= m*m+ n*n;
|
||||
if ( d<b C+2]){ b C]=m; b C+1]=n; b C+2]=d; G[j][i]=A[l*B+
|
||||
k ]; } } } } h(j,H)h(i,W)if(q=b C+2]){ Z[2]=(i *T-T /
|
||||
R)*z+c; Z[28]=z-j *T*z-g; Z[8]= 0; Z[34]=1; q =((_(*
|
||||
)( ))X)(); A[j* B+i]=q? *u-q:0; h(q,3)b C+q]=0;
|
||||
} else A[j*B+i]=G[j][i]; SDL_UpdateRect(F,
|
||||
0,0,W,H); O(r?SDL_PollEvent:SDL_WaitEvent)(&e
|
||||
)) { k=e.type; l=e.key.keysym.sym; if ( k==
|
||||
12|k== 2& l ==27)return; if(
|
||||
e.type-5?k==
|
||||
2&(l==270|l==
|
||||
269)?*u=l-270
|
||||
? *u/2:*u*2:0:1
|
||||
) break;
|
||||
}
|
||||
} }
|
||||
@@ -0,0 +1,64 @@
|
||||
#include <stdlib.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
#define M(a) mmap(0, a, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0)
|
||||
|
||||
#define W 400
|
||||
#define H 300
|
||||
#define I 128
|
||||
|
||||
#define L char*
|
||||
#define _ Sint32
|
||||
#define h(a,b) for(a=0; a<b; a++)
|
||||
#define O while(
|
||||
#define b D[j][i][
|
||||
#define J(b) a(#b)
|
||||
|
||||
SDL_Event
|
||||
e;
|
||||
SDL_Surface
|
||||
*F; float f, m,
|
||||
n,d,D[H][W][6],
|
||||
v; L A; L X; L
|
||||
V,G[H][W]; L
|
||||
E ; L Q; double
|
||||
R=2/( W-1. ),T=2/(H-1.),c,g, z=2 ,*
|
||||
K,*Z,*S; _ B, C, o,i,j,q,k,l,x,y,*u,Y=512; P(
|
||||
L f){ *(u=V)=f-X-5; V+=4; } a(L e){ O l=*e++)
|
||||
l-38?l==36?s(2),o--:l-37?*V++=l==35?k=*e++
|
||||
,k* 16+*e++-81:l^128:o>7?J(Yv]#JJ), P(S++):o++
|
||||
:s(4); } s(_ n){ O o<n){ J(]#IB); P(--S); J(]);
|
||||
*V ++=217+o++; } } p(L e,_ q,L *t){ _ x=9; do{ A="%]#IB"
|
||||
; _ i =*e; 5==q?*K=strtod(e,t),e-*t?e=*t,a(A),P(K++), J(%Yn)
|
||||
: i<6 ?p ( e+1,4,t),i-5||J(Y`YIY`YI), e=*t:i>96?a(A),P(Z+i-97),a
|
||||
(A),P (Z+*e++-71) :(p(index( e, 40)+1,1,t), i^82?i^73?i^65?i^69?i^76?1:J
|
||||
(%YhY`%YmY}]YYB%YBXHYIXH$^A$YqYJ$Ys):J(%Y{YJ%Yj^IY@Y|\\iYIYp%Yh$^AY}$]Y\\J$^I)
|
||||
: J(XHYIXH^AYn):J(]YYn) : J (]XYn),e= index( *t,41 )+ 1): p ( e , q+ 1, &e); A
|
||||
= "&%YCXJYLXIYK\\J$^I$^k$^A"; (x -=3)<1?J(&]X]Y),1L <<31<0? J(Zi_`#JO):J(_i]X),x
|
||||
?J (#HH):J(#HC),J(#AD#IJPC) ,o-=4:--x?--x?--x?x-3?J(&%YA%YAXHYIXH^AYh$^q\\J$^IY`)
|
||||
, a(A): 1:a(A):J(&$^j$^j):J(&$^B$^B); } O q==(x=*(*t=e++))/2); } main(_ r,L*U){
|
||||
X =V=(Z =(S=(K=M(Y*32))+Y)+ Y)+Y; J(h#AA#AA#AA#AA#FJ:+-*/); h(q,2){ A =E =Q=U[ q+1]; O * A=*A^B++
|
||||
[ ";<>+-*/" ]?*A:B,(B%=7)||(isspace(*E=*A)||++E,*A++)); E=V; O B=*Q){ if(Q[1]-61)p(
|
||||
Q,1,&Q); else{ p(Q+2,1,&Q); h(j,2){ J(]#JJ); P(Z+B-71-j*26); o--; } } *Q&&Q++; }
|
||||
} J(#PPJ#AP#IF); P (E -V+X +1); J(#IJPC); 0[u =X+7] =I; SDL_Init( 32 ); F=
|
||||
SDL_SetVideoMode(W,H,8 ,0); A=F->pixels; B=F->pitch; O 1){ C^=3; h(j,H)h(i,
|
||||
W )b C+2]=9; if(r=(k =SDL_GetMouseState(&x,&y))&5){ f=z/50; f=k&1 ?f:-f ;
|
||||
c+=(x*T-T/R)*f; g += f*y*T-f; z*=f=1-f/z; v=1/f; h(j,H)h(i,W)h(q,4){ k=
|
||||
x+(i- x)* f +q/2; l=y+(j-y)*f+q%2; if(k>=0&k<W&l>=0&l<H){ m=x+(k+D[
|
||||
l][k ][ 3-C]-x)*v-i; n=y+( l+D[l][k][4 -C]-y)*v-j; d= m*m+ n*n;
|
||||
if ( d<b C+2]){ b C]=m; b C+1]=n; b C+2]=d; G[j][i]=A[l*B+
|
||||
k ]; } } } } h(j,H)h(i,W)if(q=b C+2]){ Z[2]=(i *T-T /
|
||||
R)*z+c; Z[28]=z-j *T*z-g; Z[8]= 0; Z[34]=1; q =((_(*
|
||||
)( ))X)(); A[j* B+i]=q? *u-q:0; h(q,3)b C+q]=0;
|
||||
} else A[j*B+i]=G[j][i]; SDL_UpdateRect(F,
|
||||
0,0,W,H); O(r?SDL_PollEvent:SDL_WaitEvent)(&e
|
||||
)) { k=e.type; l=e.key.keysym.sym; if ( k==
|
||||
12|k== 2& l ==27)return; if(
|
||||
e.type-5?k==
|
||||
2&(l==270|l==
|
||||
269)?*u=l-270
|
||||
? *u/2:*u*2:0:1
|
||||
) break;
|
||||
}
|
||||
} }
|
||||
Reference in new issue
Block a user