// produces second of http://reenigne.livejournal.com/114987.html

#include <stdio.h>
#include <stdlib.h>
#include <complex.h>
#include <math.h>
//#include <random.h>

#define W 2880
#define H 1800
#define zoom 800.0
#define count 400000000 // 
#define depth 40 // 40 
#define max 65535

#define MIN(a, b)  (((a) < (b)) ? (a) : (b))

int main() {
	double maxseen = 0.0;
	double scalefactor;
	complex double pt;
	double px[3];
	double new;
	double ***pixels;
	
	pixels = malloc(W * H * 3 * sizeof(double));
//	printf("hey\n");
	for (int y = 0; y < H; y++) {
		pixels[y] = malloc(W * 3 * sizeof(double));
		for (int x = 0; x < W; x++) {
			pixels[y][x] = malloc(3 * sizeof(double));
			for (int chan = 0; chan < 3; chan++) {
//				printf("%i %i %i\n", y, x, chan);
				pixels[y][x][chan] = 1.0; } } }

	srandom(2);

	printf("P3\n%i %i\n%i\n", W, H, max);
	
	for (int c = 0; c < count; c++) {
		int r;
		unsigned fx, fy;
		pt = 0.0 + 0.0*I;
		for (int d = 0; d < depth; d++) {
			r = ((int)random()) % 3;
			if (r == 0) {
				pt = pt + I; }
			else if (r == 1) {
				pt = pt * (0 + I); }
			else {
				pt = cpow(pt, (0 + I)); }
		}
		fy = (unsigned) lround(cimag(pt)*zoom+H/2);
		fx = (unsigned) lround(creal(pt)*zoom+W/2);
		if (fy % H != fy) { continue; }
		if (fx % W != fx) { continue; }
		
//		printf("hot this far\n");
		
		new = pixels[fy][fx][r];
		new = pow(new, 0.999) + (float)count/(float)depth/2; //(2.2 * pow(pixels[fy][fx][r], 1/2.2))-2.0;

//		new = new + /* pow(max-new, 2.0) +*/ pow((float)count/(float)depth, 0.5); //(2.2 * pow(pixels[fy][fx][r], 1/2.2))-2.0;
		pixels[fy][fx][r] = new;
		if (new > maxseen) {
			maxseen = new; }
	}
	
	scalefactor = maxseen / ((double) max);
	for (int y = 0; y < H; y++) {
		for (int x = 0; x < W; x++) {
			for (int chan = 0; chan < 3; chan++) {
//				unsinged scaled = ;
				printf("%i ", (unsigned) MIN((pixels[y][x][chan]/maxseen)*max, max));
			}
		}
		printf("\n");
	}
}
