17
authorMart Lubbers <mart@martlubbers.net>
Thu, 17 Dec 2020 08:47:07 +0000 (09:47 +0100)
committerMart Lubbers <mart@martlubbers.net>
Thu, 17 Dec 2020 08:47:07 +0000 (09:47 +0100)
17/one.c [new file with mode: 0644]
17/two.c [new file with mode: 0644]

diff --git a/17/one.c b/17/one.c
new file mode 100644 (file)
index 0000000..9733cb3
--- /dev/null
+++ b/17/one.c
@@ -0,0 +1,120 @@
+#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;
+}
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;
+}