Add 2006/monge/alt code + format/typo checks
The alt code allows one to reconfigure the dimensions and the number of iterations, based on the author's remarks (three #defines at the top of the file). Format/typo check README.md file. Update bugs.md about the entry. It not only requires rwx memory but also x86/x86_64 machines (this was already noted). This was said to be worth fixing if possible (though in some systems it's impossible) so I kept it that way. I was going to suggest alt version instead but since it seemed like a good idea to have an alt version I decided to make it so that it might be good if they update both versions.
This commit is contained in:
1 parent
471a1f48fa
commit
b6ed00e3b4
6 files changed
+190
-31
No files matched your search
@@ -1,3 +1,4 @@
|
||||
monge
|
||||
monge.alt
|
||||
monge.orig
|
||||
prog.orig
|
||||
+6
-3
@@ -42,7 +42,7 @@ CSILENCE= -Wno-bitwise-op-parentheses -Wno-conditional-type-mismatch \
|
||||
-Wno-declaration-after-statement -Wno-dollar-in-identifier-extension \
|
||||
-Wno-error -Wno-implicit-function-declaration \
|
||||
-Wno-incompatible-pointer-types -Wno-int-conversion -Wno-parentheses \
|
||||
-Wno-return-type -Wno-strict-prototypes
|
||||
-Wno-return-type -Wno-strict-prototypes -Wno-implicit-int
|
||||
|
||||
# Common C compiler warning flags
|
||||
#
|
||||
@@ -119,8 +119,8 @@ OBJ= ${PROG}.o
|
||||
DATA=
|
||||
TARGET= ${PROG}
|
||||
#
|
||||
ALT_OBJ=
|
||||
ALT_TARGET=
|
||||
ALT_OBJ= ${PROG}.alt.o
|
||||
ALT_TARGET= ${PROG}.alt
|
||||
|
||||
|
||||
#################
|
||||
@@ -143,6 +143,9 @@ ${PROG}: ${PROG}.c
|
||||
alt: data ${ALT_TARGET}
|
||||
@${TRUE}
|
||||
|
||||
${PROG}.alt: ${PROG}.alt.c
|
||||
${CC} ${CFLAGS} $< -o $@ ${LDFLAGS}
|
||||
|
||||
# data files
|
||||
#
|
||||
data: ${DATA}
|
||||
|
||||
+82
-21
@@ -6,6 +6,9 @@ Make sure you have the SDL1 (not SDL2!) development environment installed.
|
||||
make
|
||||
```
|
||||
|
||||
There is alternate code that lets you redefine the width and height and number
|
||||
of iterations to use. See [alternate code](#alternate-code) below.
|
||||
|
||||
|
||||
### Bugs and (Mis)features:
|
||||
|
||||
@@ -42,6 +45,49 @@ That's not a bug, that's a feature.
|
||||
```
|
||||
|
||||
|
||||
## Alternate code:
|
||||
|
||||
This alternate code lets you specify the width and height of the image as well
|
||||
as the number of iterations to perform.
|
||||
|
||||
|
||||
### Alternate build:
|
||||
|
||||
|
||||
To use the default values, the same as [monge.c](monge.c), just do:
|
||||
|
||||
|
||||
```sh
|
||||
make alt
|
||||
```
|
||||
|
||||
But if you wish to actually make use of it you will want to redefine one or more
|
||||
of the variables `W`, `H` and `I`. The defaults are (respectively) 400, 300 and
|
||||
\128. If you wish to change the image size to 500x500 but keep the iterations
|
||||
the same then do:
|
||||
|
||||
```sh
|
||||
make clobber CDEFINE="-DW=500 -DH=500" alt
|
||||
```
|
||||
|
||||
If you wish to keep the dimensions the same but change the iterations to 512:
|
||||
|
||||
```sh
|
||||
make clobber CDEFINE="-DI=512" alt
|
||||
```
|
||||
|
||||
If you specify a value less than 1 for any of these it sets it back to the
|
||||
default. The value 1 was selected arbitrarily and such a small number as 1 will
|
||||
not do anything useful but as long as it's at least 1 it'll not be redefined.
|
||||
Does not try taking care of overflows but such large values would be impractical
|
||||
anyway.
|
||||
|
||||
|
||||
### Alternate use:
|
||||
|
||||
Use `monge.alt` exactly as you would `monge` above.
|
||||
|
||||
|
||||
## Judges' remarks:
|
||||
|
||||
For those who are familiar with the previous [IOCCC winners](/winners.html),
|
||||
@@ -81,6 +127,7 @@ 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.
|
||||
@@ -103,68 +150,81 @@ as you like (as understood by the C function `isspace()`).
|
||||
|
||||
Supported operations and functions are:
|
||||
|
||||
```
|
||||
Operation | Description
|
||||
:-------- | :----------
|
||||
`+,-,*,/` | Arithmetic operations, priority of `*`,`/` over `+,-` is
|
||||
respected.
|
||||
+,-,*,/ | Arithmetic operations, priority of * , / over +,- is
|
||||
| respected.
|
||||
|
|
||||
`<,>` | Compares the real parts of two complex numbers (the imaginary part
|
||||
<,> | 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, i.e.: `Abs2(a+b*i)` is `(a*a+b*b)+0*i`.
|
||||
`Re` | Extract the real part, i.e.: `Re(a+b*i)` is `a+0*i`.
|
||||
`Im` | Extract the imaginary part, i.e.: `Im(a+b*i) is b+0*i`.
|
||||
`Exp` | Calculates the complex exponential, i.e. `Exp(a+b*i)` is
|
||||
| `e^a*(cos(b)+sin(b)*i)`
|
||||
`Ln` | Calculates the principal value of the natural logarithm, i.e.
|
||||
`Ln(a+b*i)` is `ln(a*a+b*b)/2` + `atan(b/a)*i`
|
||||
Abs2 | Calculates the squared norm, i.e.: Abs2(a+b*i) is (a*a+b*b)+0*i.
|
||||
Re | Extract the real part, i.e.: Re(a+b*i) is a+0*i.
|
||||
Im | Extract the imaginary part, i.e.: Im(a+b*i) is b+0*i.
|
||||
Exp | Calculates the complex exponential, i.e. Exp(a+b*i) is
|
||||
| e^a*(cos(b)+sin(b)*i).
|
||||
Ln | Calculates the principal value of the natural logarithm, i.e.
|
||||
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:
|
||||
|
||||
./monge "z=1" "z=z*z+c; Abs2(z)<4"
|
||||
```sh
|
||||
./monge "z=1" "z=z*z+c; Abs2(z)<4"
|
||||
```
|
||||
|
||||
- Mandelbrot (return time variation):
|
||||
|
||||
./monge "z=c" "z=z*z+c; Abs2(z-c)>0.0001"
|
||||
```sh
|
||||
./monge "z=c" "z=z*z+c; Abs2(z-c)>0.0001"
|
||||
```
|
||||
|
||||
- Julia, for `c=0.31+i*0.5`:
|
||||
|
||||
./monge "z=c; c=0.31+i*0.5" "z=z*z+c; Abs2(z)<4"
|
||||
```sh
|
||||
./monge "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`:
|
||||
|
||||
./monge "z=c; c=0.31+i*0.5" "z=z*z+c; Abs2(z-c)>0.0001"
|
||||
```sh
|
||||
./monge "z=c; c=0.31+i*0.5" "z=z*z+c; Abs2(z-c)>0.0001"
|
||||
```
|
||||
|
||||
- Newton, for `x^3-1`:
|
||||
|
||||
./monge "z=c" "p=z; z=0.6666*z+0.3333/(z*z); Abs2(p-z) > 0.001"
|
||||
```sh
|
||||
./monge "z=c" "p=z; z=0.6666*z+0.3333/(z*z); Abs2(p-z) > 0.001"
|
||||
```
|
||||
|
||||
- Newton-Mandelbrot:
|
||||
|
||||
```
|
||||
```sh
|
||||
./monge "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:
|
||||
|
||||
```
|
||||
```sh
|
||||
./monge "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`:
|
||||
|
||||
```
|
||||
```sh
|
||||
./monge "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,
|
||||
but it requires the SDL library.
|
||||
|
||||
Another system requirement is the `mmap()` function (as `#define`d at the
|
||||
Another system requirement is the `mmap(2)` 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
|
||||
@@ -186,17 +246,18 @@ changing the definitions of `W`, `H` and `I` at the beginning of the code.
|
||||
- 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
|
||||
`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 chosen
|
||||
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 sentences with ';' instead
|
||||
that with '.', and I worried for my sanity), but just in case...
|
||||
of 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
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
#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)
|
||||
|
||||
#ifndef W
|
||||
#define W 400
|
||||
#elif W < 1
|
||||
#undef W
|
||||
#define W 400
|
||||
#endif
|
||||
#ifndef H
|
||||
#define H 300
|
||||
#elif H < 1
|
||||
#undef H
|
||||
#define H 300
|
||||
#endif
|
||||
#ifndef I
|
||||
#define I 128
|
||||
#elif I < 1
|
||||
#undef I
|
||||
#define I 128
|
||||
#endif
|
||||
|
||||
#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;
|
||||
}
|
||||
} }
|
||||
@@ -2339,10 +2339,18 @@ with possibly corrupt GIF files.
|
||||
### Source code: [2006/monge/monge.c](2006/monge/monge.c)
|
||||
### Information: [2006/monge/README.md](2006/monge/README.md)
|
||||
|
||||
This program requires being able to read, write and execute memory. With the
|
||||
This program requires x86 (with an x87 FPU) or x86_64 machine and it requires
|
||||
the SDL1 library.
|
||||
|
||||
This program also requires being able to read, write and execute memory. With the
|
||||
Apple silicon chips this is not allowed. Fixing this might be quite challenging
|
||||
but you are welcome to try and fix it.
|
||||
|
||||
If you do fix this it might be good to fix the alternate code as well or else
|
||||
provide it as an additional alt version. Fixing this is very likely to be very
|
||||
challenging and in some systems it will not be possible to fix but you are
|
||||
welcome to try and fix it if you wish to!
|
||||
|
||||
|
||||
### STATUS: INABIAF - please **DO NOT** fix
|
||||
|
||||
|
||||
+13
-6
@@ -2971,12 +2971,19 @@ Cody also added the [try.sh](2006/hamre/try.sh) script.
|
||||
|
||||
## [2006/monge](2006/monge/monge.c) ([README.md](2006/monge/README.md]))
|
||||
|
||||
Cody pointed out that without SDL1 (**not** SDL2) this will not link because two
|
||||
functions that are used were removed from SDL2. Since SDL1 is still available
|
||||
and since changing the code to use SDL2 would be more complicated he decided to
|
||||
change the Makefile to use `sdl-config` not `sdl2-config`. Nevertheless he
|
||||
points out that the entry requires x86/x86_64 CPUs. Without it it might very
|
||||
well segfault (for instance it segfaulted on his MacBook Pro with the M1 chip).
|
||||
Cody added the [alternate code](2006/monge/README.md#alternate-code) that lets
|
||||
one resize the image and redefine the number of iterations.
|
||||
|
||||
Cody also fixed the Makefile to use `sdl-config` (which is what the author
|
||||
stated too though that was noticed later), not `sdl2-config` as two functions
|
||||
that are used were removed from SDL2, thus making it not link. Since SDL2 is
|
||||
still available and since changing the code to use SDL2 is much more complicated
|
||||
and also makes the entry less like the original it was simply made to link in
|
||||
SDL1.
|
||||
|
||||
Nevertheless this entry does require x86/x86_64 CPUS. This is a documented
|
||||
feature but one which we will accept fixes to. See [2006/monge in
|
||||
bugs.md](/bugs.md#2006-monge).
|
||||
|
||||
|
||||
## [2006/night](2006/night/night.c) ([README.md](2006/night/README.md]))
|
||||
|
||||
Reference in new issue
Block a user