17
[aoc20.git] / 17 / two.c
1 #include <stdio.h>
2 #include <stdint.h>
3 #include <stdbool.h>
4
5 enum cellstatus {inactive, active};
6
7 char *inp[] =
8 {"...#.#.#"
9 ,"..#..#.."
10 ,"#.#.##.#"
11 ,"###.##.."
12 ,"#####.##"
13 ,"#......."
14 ,"#..#..##"
15 ,"...##.##"
16 };
17
18 #define steps 6
19 #define xorig (sizeof(inp[0]))
20 #define yorig (sizeof(inp)/sizeof(char *))
21 #define xmax (xorig+steps*2)
22 #define ymax (yorig+steps*2)
23 #define zmax (1+steps*2)
24 #define wmax (1+steps*2)
25 uint16_t map[xmax*ymax*zmax*wmax] = {inactive};
26
27 #define mapel(x, y, z, w) map[(w)*zmax*ymax*xmax+(z)*ymax*xmax+(y)*xmax+(x)]
28
29 enum cellstatus oldstatus(int x, int y, int z, int w)
30 {
31 if(x<0 || y<0 || z<0 || w<0 || x >= xmax || y >= ymax || z >= zmax || w >= wmax)
32 return inactive;
33 return (enum cellstatus)((mapel(x, y, z, w) >> 8) & 0xff);
34 }
35
36 enum cellstatus newstatus(int x, int y, int z, int w)
37 {
38 if(x<0 || y<0 || z<0 || w<0 || x >= xmax || y >= ymax || z >= zmax || w >= wmax)
39 return inactive;
40 return (enum cellstatus)(mapel(x, y, z, w) & 0xff);
41 }
42
43 void step()
44 {
45 //Move the old to the leftmost byte
46 for (int w = 0; w<wmax; w++)
47 for (int z = 0; z<zmax; z++)
48 for (int y = 0; y<ymax; y++)
49 for (int x = 0; x<xmax; x++)
50 mapel(x, y, z, w) <<= 8;
51 //Do a step
52 for (int w = 0; w<wmax; w++) {
53 for (int z = 0; z<zmax; z++) {
54 for (int y = 0; y<ymax; y++) {
55 for (int x = 0; x<xmax; x++) {
56 int count = 0;
57 for (int dw = -1; dw<=1; dw++) {
58 for (int dz = -1; dz<=1; dz++) {
59 for (int dy = -1; dy<=1; dy++) {
60 for (int dx = -1; dx<=1; dx++) {
61 if (dx == 0 && dy == 0 && dz == 0 && dw == 0)
62 continue;
63 if (oldstatus(x+dx, y+dy, z+dz, w+dw) == active)
64 count++;
65 }
66 }
67 }
68 }
69 switch (oldstatus(x, y, z, w)) {
70 case active:
71 mapel(x, y, z, w)
72 |= count == 2 || count == 3
73 ? active : inactive;
74 break;
75 case inactive:
76 mapel(x, y, z, w)
77 |= count == 3
78 ? active : inactive;
79 break;
80 }
81 }
82 }
83 }
84 }
85 }
86
87 int main()
88 {
89 fprintf(stderr, "Total size: %ux%ux%ux%u, %u elements, %u steps\n",
90 xmax, ymax, zmax, wmax, xmax*ymax*zmax*wmax, steps);
91
92 for(int y = 0; y<yorig; y++)
93 for(int x = 0; x<xorig; x++)
94 mapel(x+steps, y+steps, steps, steps) =
95 inp[y][x] == '#' ? active : inactive;
96
97 for(int i = 0; i<steps; i++) {
98 fprintf(stderr, "step: %d\n", i);
99 step(map);
100 }
101
102 int count = 0;
103 for(int w = 0; w<wmax; w++)
104 for(int z = 0; z<zmax; z++)
105 for(int y = 0; y<ymax; y++)
106 for(int x = 0; x<xmax; x++)
107 if (newstatus(x, y, z, w) == active)
108 count++;
109
110 printf("%d\n", count);
111
112 return 0;
113 }