#include #include #include #include #include const char* const input[] = { #ifdef TEST #include "input-test.h" #else #include "input.h" #endif }; // input_sz // #ifdef TEST #include "input-test-sz.h" #else #include "input-sz.h" #endif #define INPUT_WIDTH (input_sz-1) #define INPUT_HEIGHT (sizeof(input)/sizeof(char*)) #define box(t) aligned_alloc(_Alignof(t), sizeof(t)) enum gol_state { STATE_INVALID=0, STATE_FLOOR='.', STATE_EMPTY='L', STATE_OCCU='#', }; #define GOL_INDEX(w,h) ((h*INPUT_WIDTH)+w) typedef struct gol_arena { enum gol_state arena[INPUT_HEIGHT*INPUT_WIDTH]; } gol_t; gol_t* gol_clone(const gol_t* from) { gol_t* out = box(gol_t); *out = *from; return out; } pure gol_t generate_arena() { gol_t gol; for(size_t h=0;h= (int)INPUT_WIDTH || y<0 || y >= (int)INPUT_HEIGHT); } static inline pure enum gol_state gol_index(const gol_t* gol, int x, int y) { if (!gol_in_bounds(x,y)) return STATE_FLOOR; return gol->arena[GOL_INDEX(x,y)]; } static inline void gol_set(gol_t* restrict gol, int x,int y, enum gol_state st) { if (!gol_in_bounds(x,y)) return; gol->arena[GOL_INDEX(x,y)] = st; } static inline int count_states(const enum gol_state* state, enum gol_state s, size_t n) { register int j=0; for(register size_t i=0;iarena, s, INPUT_WIDTH*INPUT_HEIGHT); } static inline int nneighbours(const gol_t* gol, int n, int x, int y, enum gol_state out[restrict 8]) { out[0] = gol_index(gol, x-n, y-n); out[1] = gol_index(gol, x, y-n); out[2] = gol_index(gol, x+n, y-n); out[3] = gol_index(gol, x-n, y); //out[4] = gol_index(gol, x, y); out[4] = gol_index(gol, x+n, y); out[5] = gol_index(gol, x-n, y+n); out[6] = gol_index(gol, x, y+n); out[7] = gol_index(gol, x+n, y+n); return gol_in_bounds(x-n, y-n) || gol_in_bounds(x+n, y-n) || gol_in_bounds(x-n, y+n) || gol_in_bounds(x+n, y+n); } inline static int neighbours(const gol_t* gol, int x, int y, enum gol_state out[restrict 8]) { return nneighbours(gol, 1, x, y, out); } #define CEAR_WITH(clr, num, with) do { for(size_t __i=0;__i=5) #else if(count_states(n, STATE_OCCU, 8)>=4) #endif next = STATE_EMPTY; default: break; } gol_set(dest, w, h, next); } } static inline int gol_eq(const gol_t* g1, const gol_t* g2) { return memcmp(g1->arena, g2->arena, sizeof(g1->arena))==0; } static inline gol_t simulate_once(const gol_t* from) { gol_t out; simulate_ip(from, &out); return out; } #ifdef DEBUG static void print_arena(const gol_t* gol) { for(size_t h=0;h