Minor documentation edits.
[zddfun.git] / loop.c
blob4707ab5c21e1a7d9e78d814d5168452c26ed58f2
1 // Solve a Slither Link puzzle.
2 #include <stdint.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include "memo.h"
7 #include "zdd.h"
8 #include <stdarg.h>
9 #include "io.h"
11 int main() {
12 zdd_init();
14 int max;
15 if (!scanf("%d\n", &max)) die("input error");
16 int board[max][max];
17 for(int i = 0; i < max; i++) {
18 int c;
19 for(int j = 0; j < max; j++) {
20 c = getchar();
21 if (c == EOF || c == '\n') die("input error");
22 switch(c) {
23 case '.':
24 board[i][j] = -1;
25 break;
26 case '0' ... '4':
27 board[i][j] = c - '0';
28 break;
29 default:
30 die("input error");
33 c = getchar();
34 if (c != '\n') die("input error");
37 // The size of a puzzle is the squares, but we really care about the edges
38 // between their corners. If there are n^2 squares, then there are (n + 1)^2
39 // corners.
40 max++;
42 // Label nodes and edges of grid graph. For example, when max = 3 we have
43 // 1 2 4
44 // 3 5 7
45 // 6 8 9
46 int vtab[max][max];
47 int rtab[max * max + 1], ctab[max * max + 1];
48 int v = 1;
49 int i = 0, j = 0;
50 for(;;) {
51 rtab[v] = i;
52 ctab[v] = j;
53 vtab[i][j] = v++;
54 if (i == max - 1) {
55 if (j == max - 1) break;
56 i = j + 1;
57 j = max - 1;
58 } else if (!j) {
59 j = i + 1;
60 i = 0;
61 } else {
62 i++, j--;
66 zdd_set_vmax(max * (max - 1) * 2);
67 // Arcs go from u to v.
68 int au[zdd_vmax() + 1], av[zdd_vmax() + 1];
69 i = 1;
70 for(v = 1; v <= max * max; v++) {
71 if (ctab[v] != max - 1) {
72 au[i] = v;
73 av[i] = vtab[rtab[v]][ctab[v] + 1];
74 i++;
76 if (rtab[v] != max - 1) {
77 au[i] = v;
78 av[i] = vtab[rtab[v] + 1][ctab[v]];
79 i++;
83 // Add in clues.
84 int done = 0, todo = -1;
85 for(int i = 0; i < max - 1; i++) for(int j = 0; j < max - 1; j++) {
86 int n = board[i][j];
87 if (n != -1) {
88 int a[4];
89 int e = 1;
90 // Top left corner should have two outedges: one right, one down.
91 while(au[e] != vtab[i][j]) e++;
92 a[0] = e;
93 a[1] = e + 1;
94 EXPECT(au[e + 1] == vtab[i][j]);
95 // One more from the top right corner going down.
96 while(au[e] != vtab[i][j + 1]) e++;
97 if (av[e] != vtab[i + 1][j + 1]) e++;
98 a[2] = e;
99 // One more from the bottom left corner going right.
100 while(au[e] != vtab[i + 1][j]) e++;
101 a[3] = e;
102 zdd_contains_exactly_n(n, a, 4);
104 todo++;
105 int n = todo + 1;
106 while (!(n & 1)) {
107 n >>= 1;
108 zdd_intersection();
109 done++;
113 while (done < todo) {
114 zdd_intersection();
115 done++;
118 uint32_t p = zdd_root();
119 uint32_t clue_size = zdd_last_node();
120 // Construct ZDD of all simple loops constrained by the clues.
121 memo_t node_tab[zdd_vmax() + 1];
122 for(uint16_t v = 1; v <= zdd_vmax(); v++) memo_init(node_tab[v]);
124 uint32_t unique(uint16_t v, uint32_t lo, uint32_t hi) {
125 // Create or return existing node representing !v ? lo : hi.
126 uint32_t key[2] = { lo, hi };
127 memo_it it;
128 int just_created = memo_it_insert_u(&it, node_tab[v], (void *) key, 8);
129 if (just_created) {
130 uint32_t r;
131 memo_it_put(it, (void *) (r = zdd_abs_node(v, lo, hi)));
132 if (!(r << 15)) printf("node #%x\n", r);
133 return r;
135 return (uint32_t) memo_it_data(it);
138 // Similar to the routine in cycle_test.c, but at the same time we respect
139 // the clues. The node p in the clue ZDD therefore is part of the state.
140 memo_t cache[clue_size + 1];
141 for(int i = 0; i <= clue_size; i++) memo_init(cache[i]);
142 uint32_t recurse(uint32_t p, char *state, int start, int count) {
143 if (p <= 1) return p;
144 int e = zdd_v(p);
145 char newstate[max + 1];
146 int newcount = 0;
147 memo_it it = NULL;
148 uint32_t memoize(uint32_t n) {
149 if (it) return (uint32_t) memo_it_put(it, (void *) n);
150 return n;
152 // state == NULL is a special case that we use during the first call.
153 if (!state) {
154 for(int j = au[e]; j <= av[e]; j++) {
155 newstate[j - au[e]] = j - au[e] + 1;
157 newcount = av[e] - au[e] + 1;
158 } else {
159 // The crit-bit tree uses NULL to terminate keys, so we must
160 // do a sort of variable-length encoding.
161 int hack = start, hacki = 0;
162 state[count] = hack;
163 while(hack & ~0x7f) {
164 state[count + hacki] |= 0x80;
165 hack >>= 7;
166 hacki++;
167 state[count + hacki] = hack;
169 state[count + ++hacki] = 0;
170 int just_created = memo_it_insert(&it, cache[p], state);
171 if (!just_created && p <= 29) return (uint32_t) memo_it_data(it);
172 // Examine part of state that cannot be affected by future choices,
173 // including whether we include the current edge.
174 // Return false node if it's impossible to continue, otherwise
175 // remove them from the state and continue.
176 int j = au[e] - start;
177 if (j > count - 1) {
178 // Future choices cannot change any dangling edges.
179 for (int i = 0; i < j; i++) {
180 int otherend = state[i];
181 if (otherend - 1 != i) {
182 // Vertex start + i is dangling, and we can no longer connect it
183 // to our loop.
184 return memoize(0);
187 return memoize(1);
189 for (int i = 0; i < j; i++) {
190 int otherend = state[i];
191 if (otherend != -1 && otherend - 1 != i) {
192 // Vertex start + i is dangling, and we can no longer connect it
193 // to our loop.
194 return memoize(0);
197 // Copy over the part of the state that is still relevant.
198 while(j < count) {
199 int n = state[j];
200 newstate[newcount++] = n < 0 ? -1 : n + start - au[e];
201 j++;
203 // Add vertices that now matter to our state.
204 j += start;
205 while(j <= av[e]) {
206 newstate[newcount++] = j++ - au[e] + 1;
208 // By now newcount == av[e] - au[e].
211 // If we've come to the last edge...
212 if (e == zdd_vmax()) {
213 if (newstate[0] == 1) {
214 // ...we have the empty graph:
215 if (zdd_lo(p)) return memoize(1);
216 } else {
217 // ...or must need the last edge to finish the
218 // loop: we want !V ? FALSE : TRUE. (An elementary family.)
219 return memoize(unique(e, 0, 1));
223 // First, the case where we don't pick the current edge.
224 // If the clues force us to leave every other element out then we cannot
225 // complete a loop (since we have not completed a loop yet). Similarly
226 // we must use the current edge, we cannot complete a loop. Otherwise
227 // recurse.
228 uint32_t lo = 1 >= zdd_lo(p) ? 0 :
229 recurse(zdd_lo(p), newstate, au[e], newcount);
231 // Before we recurse the other case, we must check a couple of things.
232 // Let's initially assume we are done if we pick the current edge!
233 uint32_t hi = 1;
234 // Examine the other ends of au[e] and av[e], conveniently located at
235 // the ends of newstate[].
236 int u = newstate[0];
237 int v = newstate[newcount - 1];
238 if (u == -1 || v == -1) {
239 // At least one of the endpoints of the current edge is already busy.
240 hi = 0;
241 } else if (u + au[e] - 1 == av[e]) {
242 // We have a closed a loop. We're good as long as nothing is dangling...
243 for (int i = 1; i < newcount - 1; i++) {
244 if (newstate[i] != -1 && newstate[i] != i + 1) {
245 // Dangling link starting at i + au[e] - 1.
246 hi = 0;
247 break;
250 // ...and the clues allow us to pick no higher edges.
251 if (1 == hi) {
252 uint32_t q = zdd_hi(p);
253 while(q > 1) q = zdd_lo(q);
254 hi = q;
256 } else if (1 == zdd_hi(p)) {
257 // The clues allow no future edges, so we cannot complete our loop.
258 hi = 0;
259 } else {
260 // Recurse the case when we do pick the current edge. Modify the
261 // state accordingly for the call.
262 newstate[0] = -1;
263 newstate[newcount - 1] = -1;
264 newstate[v - 1] = u;
265 newstate[u - 1] = v;
266 hi = recurse(zdd_hi(p), newstate, au[e], newcount);
268 // Compress HI -> FALSE nodes.
269 if (!hi) return memoize(lo);
270 return memoize(unique(e, lo, hi));
272 zdd_push();
273 zdd_set_root(recurse(p, NULL, 0, 0));
274 for(int i = 0; i <= clue_size; i++) memo_clear(cache[i]);
275 for(uint16_t v = 1; v <= zdd_vmax(); v++) memo_clear(node_tab[v]);
276 zdd_intersection();
278 void printsol(int *v, int vcount) {
279 char pic[2 * max][2 * max];
280 for(int i = 0; i < max; i++) {
281 for(int j = 0; j < max; j++) {
282 pic[2 * i][2 * j] = '.';
283 pic[2 * i][2 * j + 1] = ' ';
284 pic[2 * i + 1][2 * j] = ' ';
285 pic[2 * i + 1][2 * j + 1] = ' ';
287 pic[2 * i][2 * max - 1] = '\0';
288 pic[2 * i + 1][2 * max - 1] = '\0';
290 for(int i = 0; i < max - 1; i++) {
291 for(int j = 0; j < max - 1; j++) {
292 if (board[i][j] != -1) {
293 pic[2 * i + 1][2 * j + 1] = '0' + board[i][j];
298 for(int i = 0; i < vcount; i++) {
299 int e = v[i];
300 int r = rtab[au[e]] + rtab[av[e]];
301 int c = ctab[au[e]] + ctab[av[e]];
302 pic[r][c] = r & 1 ? '|' : '-';
305 /* Plain ASCII output:
306 for(int i = 0; i < 2 * max; i++) puts(pic[i]);
309 for(int i = 0; i < 2 * max - 1; i++) {
310 for(int j = 0; j < 2 * max; j++) {
311 int analyse() {
312 int n = 0;
313 int filled(int x, int y) {
314 if (x >= 0 && x < 2 * max - 1 && y >= 0 && y < 2 * max - 1 &&
315 pic[x][y] != ' ') return 1;
316 return 0;
318 if (filled(i - 1, j)) n += 1;
319 if (filled(i, j - 1)) n += 2;
320 if (filled(i + 1, j)) n += 4;
321 if (filled(i, j + 1)) n += 8;
322 return n;
324 switch(pic[i][j]) {
325 case '|':
326 printf("\u2502");
327 break;
328 case '-':
329 printf("\u2500");
330 break;
331 case '.':
332 switch(analyse()) {
333 case 0:
334 printf("\u00b7");
335 break;
336 case 3:
337 printf("\u2518");
338 break;
339 case 5:
340 printf("\u2502");
341 break;
342 case 6:
343 printf("\u2510");
344 break;
345 case 9:
346 printf("\u2514");
347 break;
348 case 10:
349 printf("\u2500");
350 break;
351 case 12:
352 printf("\u250c");
353 break;
354 default:
355 printf("*");
356 break;
358 break;
359 case '\0':
360 putchar('\n');
361 break;
362 default:
363 putchar(pic[i][j]);
364 break;
368 putchar('\n');
370 zdd_forall(printsol);