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