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:
Cody Boone Ferguson committed 2023-11-24 10:40:05 -08:00
1 parent 471a1f48fa
commit b6ed00e3b4
6 files changed
+190 -31

No files matched your search

+1
View File
@@ -1,3 +1,4 @@
monge
monge.alt
monge.orig
prog.orig
+6 -3
View File
@@ -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
View File
@@ -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
+79
View File
@@ -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;
}
} }
+9 -1
View File
@@ -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
View File
@@ -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]))