11 bool __attribute__((format(printf
, 1, 2)))
12 debug(const char *fmt
, ...) {
14 if (getenv("DEBUG")) {
16 vfprintf(stderr
, fmt
, ap
);
29 char type
; /* '.', '=', or '|'; thanks to ASCII, risk is (type/4+1)%3 */
37 static char lookup(int i
) {
45 return 'A' + i
- 10 - 26;
49 static void dump(int level
) {
51 if (!debug("\niter %d:\n", level
))
53 for (j
= 0; j
<= maxy
; j
++) {
54 for (i
= 0; i
<= maxx
; i
++)
55 debug("%c%c%c%c ", grid
[j
][i
].type
, lookup(grid
[j
][i
].t
),
56 lookup(grid
[j
][i
].c
), lookup(grid
[j
][i
].n
));
61 static bool try(int *p
, int other
, int add
) {
64 if (*p
== -1 || other
+ add
< *p
) {
71 static bool process(int x
, int y
) {
74 switch (grid
[y
][x
].type
) {
77 ret
|= try(p
, grid
[y
][x
].c
, 7);
79 ret
|= try(p
, grid
[y
- 1][x
].t
, 1);
81 ret
|= try(p
, grid
[y
][x
- 1].t
, 1);
83 ret
|= try(p
, grid
[y
][x
+ 1].t
, 1);
85 ret
|= try(p
, grid
[y
+ 1][x
].t
, 1);
87 ret
|= try(p
, grid
[y
][x
].t
, 7);
89 ret
|= try(p
, grid
[y
- 1][x
].c
, 1);
91 ret
|= try(p
, grid
[y
][x
- 1].c
, 1);
93 ret
|= try(p
, grid
[y
][x
+ 1].c
, 1);
95 ret
|= try(p
, grid
[y
+ 1][x
].c
, 1);
99 ret
|= try(p
, grid
[y
][x
].n
, 7);
101 ret
|= try(p
, grid
[y
- 1][x
].c
, 1);
103 ret
|= try(p
, grid
[y
][x
- 1].c
, 1);
105 ret
|= try(p
, grid
[y
][x
+ 1].c
, 1);
107 ret
|= try(p
, grid
[y
+ 1][x
].c
, 1);
109 ret
|= try(p
, grid
[y
][x
].c
, 7);
111 ret
|= try(p
, grid
[y
- 1][x
].n
, 1);
113 ret
|= try(p
, grid
[y
][x
- 1].n
, 1);
115 ret
|= try(p
, grid
[y
][x
+ 1].n
, 1);
117 ret
|= try(p
, grid
[y
+ 1][x
].n
, 1);
121 ret
|= try(p
, grid
[y
][x
].t
, 7);
123 ret
|= try(p
, grid
[y
- 1][x
].n
, 1);
125 ret
|= try(p
, grid
[y
][x
- 1].n
, 1);
127 ret
|= try(p
, grid
[y
][x
+ 1].n
, 1);
129 ret
|= try(p
, grid
[y
+ 1][x
].n
, 1);
131 ret
|= try(p
, grid
[y
][x
].n
, 7);
133 ret
|= try(p
, grid
[y
- 1][x
].t
, 1);
135 ret
|= try(p
, grid
[y
][x
- 1].t
, 1);
137 ret
|= try(p
, grid
[y
][x
+ 1].t
, 1);
139 ret
|= try(p
, grid
[y
+ 1][x
].t
, 1);
147 int main(int argc
, char **argv
) {
154 /* Part 1 - populate grid */
156 depth
= atoi(argv
[1]);
159 } else if (argc
> 1 &&
160 (!(stdin
= freopen(argv
[1], "r", stdin
)) ||
161 scanf("depth: %d\ntarget: %d,%d\n", &depth
, &x
, &y
) != 3)) {
162 fprintf(stderr
, "bad input\n");
167 if (maxx
>= MAXX
|| maxy
>= MAXY
) {
168 fprintf(stderr
, "bad input\n");
172 for (j
= 0; j
<= maxy
; j
++)
173 for (i
= 0; i
<= maxx
; i
++) {
174 if (i
== 0 && j
== 0)
176 else if (i
== x
&& j
== y
)
179 grid
[j
][i
].idx
= i
* 16807;
181 grid
[j
][i
].idx
= j
* 48271;
183 grid
[j
][i
].idx
= grid
[j
][i
- 1].ero
* grid
[j
- 1][i
].ero
;
184 grid
[j
][i
].ero
= (grid
[j
][i
].idx
+ depth
) % 20183;
185 if (grid
[j
][i
].ero
% 3 == 0)
186 grid
[j
][i
].type
= '.';
187 else if (grid
[j
][i
].ero
% 3 == 1)
188 grid
[j
][i
].type
= '=';
190 grid
[j
][i
].type
= '|';
191 if (i
<= x
&& j
<= y
)
192 risk
+= (grid
[j
][i
].type
/ 4 + 1) % 3;
198 printf("resulting risk %d\n", risk
);
205 for (j
= 0; j
<= maxy
; j
++)
206 for (i
= 0; i
<= maxx
; i
++)
211 printf("after %d cycles to settle, shortest path to %d,%d torch is %d\n",
212 iter
, x
, y
, grid
[y
][x
].t
);