17
[aoc20.git] / 17 / two.c
diff --git a/17/two.c b/17/two.c
new file mode 100644 (file)
index 0000000..e940738
--- /dev/null
+++ b/17/two.c
@@ -0,0 +1,113 @@
+#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;
+}