#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define iterations 108U

typedef unsigned char u8;
typedef unsigned int u32;

/* ascii display table */
const u8 charlut[] = {' ', '8'};

/* starting pattern */
const u8 seed[] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,
0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1
};

void evolve(u8* b1, u8* b2){ u32 i; u32 pop;
    for(i=0; i<256U; i++) {
        pop=0;
        
        if(b1[(i+17)&255U]) pop++;
        if(b1[(i+16)&255U]) pop++;
        if(b1[(i+15)&255U]) pop++;
        if(b1[(i+1 )&255U]) pop++;
        if(b1[(i-1 )&255U]) pop++;
        if(b1[(i-15)&255U]) pop++;
        if(b1[(i-16)&255U]) pop++;
        if(b1[(i-17)&255U]) pop++;
        
        if(pop <2) b2[i]=0;
        if(pop >3) b2[i]=0;
        if(pop==2) b2[i]=b1[i];
        if(pop==3) b2[i]=1;
    }
}

int main(void){ u8* bmem; u8* b1; u8* b2; u8* t1; u32 i;
    /* get memory */
    bmem = (u8*)malloc(512U);
    b1 = bmem;
    b2 = bmem + 256U;
    
    /* copy seed to b1 */
    memcpy(b1, seed, 256U);
    
    /* actually run */
    for(i=0; i<iterations; i++){ u32 p;
        printf("generation %u\n", i+1);
        for(p=0; p<256U; p++){
            putchar(charlut[b1[p]]); putchar(charlut[b1[p]]); /* display twice */
            if(0xF == (p&0xF)) putchar('\n');
        }
        evolve(b1, b2); /* iterate boards */
        t1 = b1; b1 = b2; b2 = t1; /* swap boards */
    }
    
    /* we're dun */
    free(bmem);
    return 0;
}