10 void debug(const char *fmt
, ...) {
12 if (getenv("DEBUG")) {
14 vfprintf(stderr
, fmt
, ap
);
21 #define MIN(a,b) ((a)<(b)?(a):(b))
22 #define MAX(a,b) ((a)>(b)?(a):(b))
24 static char grid
[MAXY
][MAXX
];
28 static void dump(int minx
, int miny
, int maxx
, int maxy
) {
32 debug("%4d: % *c\n", 0, 500 - minx
+ 1, '+');
33 for (i
= miny
; i
<= maxy
; i
++)
34 debug("%4d: %.*s\n", i
, maxx
- minx
+ 1, &grid
[i
][minx
]);
37 static void fill(int x
, int y
, int minx
, int miny
, int maxx
, int maxy
) {
40 debug("fill(%d,%d) at %c above %c\n", x
, y
, grid
[y
][x
], grid
[y
+ 1][x
]);
43 if (grid
[y
+ 1][x
] == '|') {
44 debug("point %d,%d already being filled elsewhere\n", x
, y
+ 1);
45 dump(MAX(minx
, x
- 5), MAX(0, y
- 5), MIN(maxx
, x
+ 5), y
+ 2);
48 if (grid
[y
+ 1][x
] == '.') {
49 if (y
+ 1 >= miny
&& y
+ 1 <= maxy
)
52 fill(x
, y
+ 1, minx
, miny
, maxx
, maxy
);
55 assert(y
>= miny
&& y
<= maxy
);
56 for (l
= x
; l
>= minx
; l
--) {
57 if (grid
[y
][l
- 1] == '#' ||
58 grid
[y
+ 1][l
- 1] == '.' || grid
[y
+ 1][l
- 1] == '|')
61 for (r
= x
; r
<= maxx
; r
++) {
62 if (grid
[y
][r
+ 1] == '#' ||
63 grid
[y
+ 1][r
+ 1] == '.' || grid
[y
+ 1][r
+ 1] == '|')
66 debug("found bounds %d to %d\n", l
, r
);
67 if (grid
[y
][l
- 1] == '#' && grid
[y
][r
+ 1] == '#') {
68 for (i
= l
; i
<= r
; i
++) {
69 if (grid
[y
][i
] == '.')
73 dump(MAX(minx
, l
- 2), MAX(0, y
- 5), MIN(maxx
, r
+ 2), y
+ 2);
74 fill(x
, y
- 1, minx
, miny
, maxx
, maxy
);
77 for (i
= l
; i
<= r
; i
++) {
78 if (grid
[y
][i
] == '.')
82 if (grid
[y
][l
- 1] == '.') {
85 debug("spilling left from %d,%d\n", x
, y
);
86 dump(MAX(minx
, l
- 2), MAX(0, y
- 5), MIN(maxx
, r
+ 2), y
+ 2);
87 fill(l
- 1, y
, minx
, miny
, maxx
, maxy
);
89 if (grid
[y
][r
+ 1] == '.') {
92 debug("spilling right from %d,%d\n", x
, y
);
93 dump(MAX(minx
, l
- 2), MAX(0, y
- 5), MIN(maxx
, r
+ 2), y
+ 2);
94 fill(r
+ 1, y
, minx
, miny
, maxx
, maxy
);
98 int main(int argc
, char **argv
) {
99 size_t len
= 0, count
= 0;
102 int minx
= 500, maxx
= 500, miny
= 10000, maxy
= 0;
106 /* Part 0 - read in map */
107 if (argc
> 1 && !(stdin
= freopen(argv
[1], "r", stdin
))) {
112 memset(grid
, '.', sizeof grid
);
113 while (getline(&line
, &len
, stdin
) >= 0) {
115 if (sscanf(line
, "%c=%d, %c=%d..%d\n", &a
, &q
, &b
, &r
, &s
) != 5
116 || a
== b
|| r
>= s
) {
117 fprintf(stderr
, "bad input: %s\n", line
);
124 for (q
= y1
; q
<= y2
; q
++)
131 for (q
= x1
; q
<= x2
; q
++)
134 debug("clay at %d,%d to %d,%d\n", x1
, y1
, x2
, y2
);
143 if (minx
< 1 || maxx
> MAXX
- 1 || miny
< 1 || maxy
> MAXY
- 1) {
144 fprintf(stderr
, "recompile with larger limit\n");
150 printf("read %zu lines, bounds: %d,%d to %d,%d\n",
151 count
, minx
, miny
, maxx
, maxy
);
152 dump(minx
, miny
, maxx
, maxy
);
154 /* Part 2 - fill grid */
156 maxy
= atoi(argv
[2]);
158 fill(500, 0, minx
, miny
, maxx
, maxy
);
159 dump(minx
, miny
, maxx
, maxy
);
160 printf("completed %d calls, change %d tiles\n", calls
, tiles
);
162 for (s
= miny
; s
<= maxy
; s
++)
163 for (r
= minx
; r
<= maxx
; r
++) {
164 if (grid
[s
][r
] == '~' || grid
[s
][r
] == '|')
166 if (grid
[s
][r
] == '~')
169 printf("found %zu points touched by water, %d retained\n", count
, q
);