10 bool debug(const char *fmt
, ...) {
12 if (getenv("DEBUG")) {
14 vfprintf(stderr
, fmt
, ap
);
22 static char grida
[2][LIMIT
+ 2][LIMIT
+ 2]; /* slow */
23 static char gridb
[2][LIMIT
+ 2][LIMIT
+ 2]; /* fast */
25 static void dump(int ticks
, int max
) {
26 if (!debug("time %d\n", ticks
))
28 for (int i
= 1; i
<= max
; i
++)
29 debug("%s\n", &grida
[ticks
% 2][i
][1]);
33 static char compute(char grid
[LIMIT
+ 2][LIMIT
+ 2], int x
, int y
,
34 int *wooded
, int *lumber
) {
35 int o
= 0, w
= 0, l
= 0;
36 switch (grid
[y
- 1][x
- 1]) {
41 switch (grid
[y
- 1][x
]) {
46 switch (grid
[y
- 1][x
+ 1]) {
51 switch (grid
[y
][x
- 1]) {
56 switch (grid
[y
][x
+ 1]) {
61 switch (grid
[y
+ 1][x
- 1]) {
66 switch (grid
[y
+ 1][x
]) {
71 switch (grid
[y
+ 1][x
+ 1]) {
105 int main(int argc
, char **argv
) {
106 size_t len
= 0, count
= 0;
113 /* Part 1 - read in initial map */
114 if (argc
> 1 && !(stdin
= freopen(argv
[1], "r", stdin
))) {
119 while (getline(&line
, &len
, stdin
) >= 0) {
120 p
= stpcpy(&grida
[0][++count
][1], line
);
122 if (p
- &grida
[0][count
][1] >= LIMIT
+ 1) {
123 fprintf(stderr
, "LIMIT too small\n");
127 printf("Read %zu lines\n", count
);
128 if(p
- &grida
[0][count
][1] != count
) {
129 fprintf(stderr
, "non-square grid read in\n");
132 memcpy(gridb
, grida
, sizeof grida
);
135 /* Part 2 - first 10 mintes */
136 for (ticks
= 0; ticks
< 10; ticks
++) {
138 for (y
= 1; y
<= count
; y
++)
139 for (x
= 1; x
<= count
; x
++) {
140 grida
[(ticks
+ 1) % 2][y
][x
] = compute(grida
[ticks
% 2], x
, y
,
142 gridb
[1][y
][x
] = compute(gridb
[0], x
, y
, NULL
, NULL
);
144 for (y
= 1; y
<= count
; y
++)
145 for (x
= 1; x
<= count
; x
++)
146 gridb
[0][y
][x
] = compute(gridb
[1], x
, y
, NULL
, NULL
);
147 dump(ticks
+ 1, count
);
148 printf("After %d minutes, resource value %d*%d = %d\n", ticks
+ 1,
149 wooded
, lumber
, wooded
* lumber
);
152 /* Part 3 - iterate until cycle detected */
153 while (memcmp(grida
[ticks
% 2], gridb
[0], sizeof gridb
[0])) {
155 printf("%5d\n", ticks
);
156 for (y
= 1; y
<= count
; y
++)
157 for (x
= 1; x
<= count
; x
++) {
158 grida
[(ticks
+ 1) % 2][y
][x
] = compute(grida
[ticks
% 2], x
, y
,
160 gridb
[1][y
][x
] = compute(gridb
[0], x
, y
, NULL
, NULL
);
162 for (y
= 1; y
<= count
; y
++)
163 for (x
= 1; x
<= count
; x
++)
164 gridb
[0][y
][x
] = compute(gridb
[1], x
, y
, NULL
, NULL
);
167 printf("detected cycle at minute %d\n", ticks
);
169 /* Part 4 - fast forward, then finish the task */
170 memcpy(gridb
[1], gridb
[0], sizeof gridb
[0]);
171 for (ticks
= 1000000000 - 1000000000 % ticks
; ticks
< 1000000000; ticks
++) {
173 for (y
= 1; y
<= count
; y
++)
174 for (x
= 1; x
<= count
; x
++)
175 gridb
[(ticks
+ 1) % 2][y
][x
] = compute(gridb
[ticks
% 2], x
, y
,
177 printf("After %d minutes, resource value %d*%d = %d\n", ticks
+ 1,
178 wooded
, lumber
, wooded
* lumber
);