--- /dev/null
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+enum cellstatus {active, inactive};
+
+//char *inp[] = {".#.","..#","###"};
+char *inp[] =
+ {"...#.#.#"
+ ,"..#..#.."
+ ,"#.#.##.#"
+ ,"###.##.."
+ ,"#####.##"
+ ,"#......."
+ ,"#..#..##"
+ ,"...##.##"
+ };
+
+int steps = 6;
+uint16_t *map = NULL;
+int xmax, ymax, zmax;
+
+#define mapel(x, y, z) map[(z)*ymax*xmax+(y)*xmax+(x)]
+
+enum cellstatus oldstatus(int x, int y, int z)
+{
+ if(x<0 || y<0 || z<0 || x >= xmax || y >= ymax || z >= zmax)
+ return inactive;
+ return (enum cellstatus)((mapel(x, y, z) >> 8) & 0xff);
+}
+
+enum cellstatus newstatus(int x, int y, int z)
+{
+ if(x<0 || y<0 || z<0 || x >= xmax || y >= ymax || z >= zmax)
+ return inactive;
+ return (enum cellstatus)(mapel(x, y, z) & 0xff);
+}
+
+void step()
+{
+ //Move the old to the leftmost byte
+ for (int z = 0; z<zmax; z++)
+ for (int y = 0; y<ymax; y++)
+ for (int x = 0; x<xmax; x++)
+ mapel(x, y, z) <<= 8;
+ //Do a step
+ for (int z = 0; z<zmax; z++) {
+ for (int y = 0; y<ymax; y++) {
+ for (int x = 0; x<xmax; x++) {
+ int count = 0;
+ for (int dz = -1; dz<=1; dz++) {
+ for (int dy = -1; dy<=1; dy++) {
+ for (int dx = -1; dx<=1; dx++) {
+ if (dx == 0 && dy == 0 && dz == 0)
+ continue;
+ if (oldstatus(x+dx, y+dy, z+dz) == active)
+ count++;
+ }
+ }
+ }
+// fprintf(stderr, "x=%u, y=%u, z=%u, count: %u\n", x, y, z, count);
+ switch (oldstatus(x, y, z)) {
+ case active:
+ mapel(x, y, z)
+ |= count == 2 || count == 3
+ ? active : inactive;
+ break;
+ case inactive:
+ mapel(x, y, z)
+ |= count == 3
+ ? active : inactive;
+ break;
+ }
+ }
+ }
+ }
+}
+
+int main()
+{
+ //Determine dimensions
+ int xorig = strlen(inp[0]);
+ int yorig = sizeof(inp)/sizeof(char *);
+ xmax = xorig+steps*2;
+ ymax = yorig+steps*2;
+ zmax = 1+steps*2;
+
+ fprintf(stderr, "Total size: %ux%ux%u, %u elements, %u steps\n",
+ xmax, ymax, zmax, xmax*ymax*zmax, steps);
+ map = malloc(sizeof(uint16_t)*xmax*ymax*zmax);
+
+ //Init initially
+ for(int z = 0; z<zmax; z++)
+ for(int y = 0; y<ymax; y++)
+ for(int x = 0; x<xmax; x++)
+ mapel(x, y, z) = inactive;
+ for(int y = 0; y<yorig; y++)
+ for(int x = 0; x<xorig; x++) {
+ mapel(x+steps, y+steps, steps) =
+ inp[y][x] == '#' ? active : inactive;
+ }
+
+ for(int i = 0; i<steps; i++) {
+ fprintf(stderr, "step: %d\n", i);
+ step(map);
+ }
+
+ int count = 0;
+ for(int z = 0; z<zmax; z++)
+ for(int y = 0; y<ymax; y++)
+ for(int x = 0; x<xmax; x++)
+ if (newstatus(x, y, z) == active)
+ count++;
+
+ printf("%d\n", count);
+
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+enum cellstatus {inactive, active};
+
+char *inp[] =
+ {"...#.#.#"
+ ,"..#..#.."
+ ,"#.#.##.#"
+ ,"###.##.."
+ ,"#####.##"
+ ,"#......."
+ ,"#..#..##"
+ ,"...##.##"
+ };
+
+#define steps 6
+#define xorig (sizeof(inp[0]))
+#define yorig (sizeof(inp)/sizeof(char *))
+#define xmax (xorig+steps*2)
+#define ymax (yorig+steps*2)
+#define zmax (1+steps*2)
+#define wmax (1+steps*2)
+uint16_t map[xmax*ymax*zmax*wmax] = {inactive};
+
+#define mapel(x, y, z, w) map[(w)*zmax*ymax*xmax+(z)*ymax*xmax+(y)*xmax+(x)]
+
+enum cellstatus oldstatus(int x, int y, int z, int w)
+{
+ if(x<0 || y<0 || z<0 || w<0 || x >= xmax || y >= ymax || z >= zmax || w >= wmax)
+ return inactive;
+ return (enum cellstatus)((mapel(x, y, z, w) >> 8) & 0xff);
+}
+
+enum cellstatus newstatus(int x, int y, int z, int w)
+{
+ if(x<0 || y<0 || z<0 || w<0 || x >= xmax || y >= ymax || z >= zmax || w >= wmax)
+ return inactive;
+ return (enum cellstatus)(mapel(x, y, z, w) & 0xff);
+}
+
+void step()
+{
+ //Move the old to the leftmost byte
+ for (int w = 0; w<wmax; w++)
+ for (int z = 0; z<zmax; z++)
+ for (int y = 0; y<ymax; y++)
+ for (int x = 0; x<xmax; x++)
+ mapel(x, y, z, w) <<= 8;
+ //Do a step
+ for (int w = 0; w<wmax; w++) {
+ for (int z = 0; z<zmax; z++) {
+ for (int y = 0; y<ymax; y++) {
+ for (int x = 0; x<xmax; x++) {
+ int count = 0;
+ for (int dw = -1; dw<=1; dw++) {
+ for (int dz = -1; dz<=1; dz++) {
+ for (int dy = -1; dy<=1; dy++) {
+ for (int dx = -1; dx<=1; dx++) {
+ if (dx == 0 && dy == 0 && dz == 0 && dw == 0)
+ continue;
+ if (oldstatus(x+dx, y+dy, z+dz, w+dw) == active)
+ count++;
+ }
+ }
+ }
+ }
+ switch (oldstatus(x, y, z, w)) {
+ case active:
+ mapel(x, y, z, w)
+ |= count == 2 || count == 3
+ ? active : inactive;
+ break;
+ case inactive:
+ mapel(x, y, z, w)
+ |= count == 3
+ ? active : inactive;
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+int main()
+{
+ fprintf(stderr, "Total size: %ux%ux%ux%u, %u elements, %u steps\n",
+ xmax, ymax, zmax, wmax, xmax*ymax*zmax*wmax, steps);
+
+ for(int y = 0; y<yorig; y++)
+ for(int x = 0; x<xorig; x++)
+ mapel(x+steps, y+steps, steps, steps) =
+ inp[y][x] == '#' ? active : inactive;
+
+ for(int i = 0; i<steps; i++) {
+ fprintf(stderr, "step: %d\n", i);
+ step(map);
+ }
+
+ int count = 0;
+ for(int w = 0; w<wmax; w++)
+ for(int z = 0; z<zmax; z++)
+ for(int y = 0; y<ymax; y++)
+ for(int x = 0; x<xmax; x++)
+ if (newstatus(x, y, z, w) == active)
+ count++;
+
+ printf("%d\n", count);
+
+ return 0;
+}