Skip to content

Instantly share code, notes, and snippets.

@daurnimator
Forked from DavidBuchanan314/cursed_mandelbrot.c
Last active November 14, 2018 04:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save daurnimator/da3d4a6d9b582fd38d2cde160e269cdc to your computer and use it in GitHub Desktop.
Save daurnimator/da3d4a6d9b582fd38d2cde160e269cdc to your computer and use it in GitHub Desktop.
Compile-time mandelbrot in pure C and Zig. Outputs a PGM image file to stdout.
#include <stdio.h>
#define SQ(x) (x)*(x)
#define M0(x,y) SQ(x)+SQ(y)<4?0:0xe0
#define M1(x,y,x0,y0) (SQ(x)+SQ(y)<4)?M0(SQ(x)-SQ(y)+(x0),2*(x)*(y)+(y0)):0xc0
#define M2(x,y,x0,y0) (SQ(x)+SQ(y)<4)?M1(SQ(x)-SQ(y)+(x0),2*(x)*(y)+(y0),x0,y0):0xa0
#define M3(x,y,x0,y0) (SQ(x)+SQ(y)<4)?M2(SQ(x)-SQ(y)+(x0),2*(x)*(y)+(y0),x0,y0):0x80
#define M4(x,y,x0,y0) (SQ(x)+SQ(y)<4)?M3(SQ(x)-SQ(y)+(x0),2*(x)*(y)+(y0),x0,y0):0x60
#define M5(x,y,x0,y0) (SQ(x)+SQ(y)<4)?M4(SQ(x)-SQ(y)+(x0),2*(x)*(y)+(y0),x0,y0):0x40
#define M6(x,y,x0,y0) (SQ(x)+SQ(y)<4)?M5(SQ(x)-SQ(y)+(x0),2*(x)*(y)+(y0),x0,y0):0x20
#define XF(x) (x)/20-2.2
#define YF(y) (y)/20-1.6
#define C1(x,y) M4(XF(x), YF(y), XF(x), YF(y)),
// ^- change this to 5 or 6 to increase detail
#define C2(x,y) C1(x,y) C1(x+1,y)
#define C4(x,y) C2(x,y) C2(x+2,y)
#define C8(x,y) C4(x,y) C4(x+4,y)
#define C16(x,y) C8(x,y) C8(x+8,y)
#define C32(x,y) C16(x,y) C16(x+16,y)
#define C64(x,y) C32(x,y) C32(x+32,y)
#define R2(y) C64(0.0,y) C64(0.0,y+1)
#define R4(y) R2(y) R2(y+2)
#define R8(y) R4(y) R4(y+4)
#define R16(y) R8(y) R8(y+8)
#define R32(y) R16(y) R16(y+16)
#define R64(y) R32(y) R32(y+32)
static const unsigned char pixels[] = {
R64(0.0)
};
int main() {
fputs("P5\n64 64\n255\n", stdout);
fwrite(pixels, sizeof(pixels), 1, stdout);
return 0;
}
const std = @import("std");
fn SQ(x:f64) f64 { return x*x; }
fn M0(x:f64,y:f64) u8 {
// return if ((SQ(x)+SQ(y))<4) 0 else 0xe0;
if ((SQ(x)+SQ(y))<4) { return 0;}else{ return 0xe0; }
}
fn M1(x:f64,y:f64,x0:f64,y0:f64) u8 { return if (SQ(x)+SQ(y)<4) M0(SQ(x)-SQ(y)+x0,2*(x)*(y)+y0) else 0xc0; }
fn M2(x:f64,y:f64,x0:f64,y0:f64) u8 { return if (SQ(x)+SQ(y)<4) M1(SQ(x)-SQ(y)+x0,2*(x)*(y)+y0,x0,y0) else 0xa0; }
fn M3(x:f64,y:f64,x0:f64,y0:f64) u8 { return if (SQ(x)+SQ(y)<4) M2(SQ(x)-SQ(y)+x0,2*(x)*(y)+y0,x0,y0) else 0x80; }
fn M4(x:f64,y:f64,x0:f64,y0:f64) u8 { return if (SQ(x)+SQ(y)<4) M3(SQ(x)-SQ(y)+x0,2*(x)*(y)+y0,x0,y0) else 0x60; }
fn M5(x:f64,y:f64,x0:f64,y0:f64) u8 { return if (SQ(x)+SQ(y)<4) M4(SQ(x)-SQ(y)+x0,2*(x)*(y)+y0,x0,y0) else 0x40; }
fn M6(x:f64,y:f64,x0:f64,y0:f64) u8 { return if (SQ(x)+SQ(y)<4) M5(SQ(x)-SQ(y)+x0,2*(x)*(y)+y0,x0,y0) else 0x20; }
fn XF(x:i32) f64 { return @intToFloat(f64, x)/20-2.2; }
fn YF(y:i32) f64 { return @intToFloat(f64, y)/20-1.6; }
fn C1(x:i32, y:i32) [1]u8 { return []u8{ M4(XF(x), YF(y), XF(x), YF(y)) }; }
// ^- change this to 5 or 6 to increase detail
fn C2(comptime x:i32,comptime y:i32) [2]u8 { return C1(x,y) ++ C1(x+1,y); }
fn C4(comptime x:i32,comptime y:i32) [4]u8 { return C2(x,y) ++ C2(x+2,y); }
fn C8(comptime x:i32,comptime y:i32) [8]u8 { return C4(x,y) ++ C4(x+4,y); }
fn C16(comptime x:i32,comptime y:i32) [16]u8 { return C8(x,y) ++ C8(x+8,y); }
fn C32(comptime x:i32,comptime y:i32) [32]u8 { return C16(x,y) ++ C16(x+16,y); }
fn C64(comptime x:i32,comptime y:i32) [64]u8 { return C32(x,y) ++ C32(x+32,y); }
fn R2(comptime y:i32) [2*64]u8 { return C64(0.0,y) ++ C64(0.0,y+1); }
fn R4(comptime y:i32) [4*64]u8 { return R2(y) ++ R2(y+2); }
fn R8(comptime y:i32) [8*64]u8 { return R4(y) ++ R4(y+4); }
fn R16(comptime y:i32) [16*64]u8 { return R8(y) ++ R8(y+8); }
fn R32(comptime y:i32) [32*64]u8 { return R16(y) ++ R16(y+16); }
fn R64(comptime y:i32) [64*64]u8 { return R32(y) ++ R32(y+32); }
pub fn main() !void {
@setEvalBranchQuota(100000);
const pixels = comptime(R64(0.0));
var stdout_file = try std.io.getStdOut();
try stdout_file.write("P5\n64 64\n255\n");
try stdout_file.write(pixels);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment