9 #ifdef STANDALONE_LATIN_TEST
10 #define STANDALONE_SOLVER
15 /* --------------------------------------------------------
19 static int latin_solver_top(struct latin_solver
*solver
, int maxdiff
,
20 int diff_simple
, int diff_set_0
, int diff_set_1
,
21 int diff_forcing
, int diff_recursive
,
22 usersolver_t
const *usersolvers
, void *ctx
,
23 ctxnew_t ctxnew
, ctxfree_t ctxfree
);
25 #ifdef STANDALONE_SOLVER
26 int solver_show_working
, solver_recurse_depth
;
30 * Function called when we are certain that a particular square has
31 * a particular number in it. The y-coordinate passed in here is
34 void latin_solver_place(struct latin_solver
*solver
, int x
, int y
, int n
)
42 * Rule out all other numbers in this square.
44 for (i
= 1; i
<= o
; i
++)
49 * Rule out this number in all other positions in the row.
51 for (i
= 0; i
< o
; i
++)
56 * Rule out this number in all other positions in the column.
58 for (i
= 0; i
< o
; i
++)
63 * Enter the number in the result grid.
65 solver
->grid
[y
*o
+x
] = n
;
68 * Cross out this number from the list of numbers left to place
69 * in its row, its column and its block.
71 solver
->row
[y
*o
+n
-1] = solver
->col
[x
*o
+n
-1] = TRUE
;
74 int latin_solver_elim(struct latin_solver
*solver
, int start
, int step
75 #ifdef STANDALONE_SOLVER
81 #ifdef STANDALONE_SOLVER
82 char **names
= solver
->names
;
87 * Count the number of set bits within this section of the
92 for (i
= 0; i
< o
; i
++)
93 if (solver
->cube
[start
+i
*step
]) {
107 if (!solver
->grid
[y
*o
+x
]) {
108 #ifdef STANDALONE_SOLVER
109 if (solver_show_working
) {
111 printf("%*s", solver_recurse_depth
*4, "");
115 printf(":\n%*s placing %s at (%d,%d)\n",
116 solver_recurse_depth
*4, "", names
[n
-1],
120 latin_solver_place(solver
, x
, y
, n
);
124 #ifdef STANDALONE_SOLVER
125 if (solver_show_working
) {
127 printf("%*s", solver_recurse_depth
*4, "");
131 printf(":\n%*s no possibilities available\n",
132 solver_recurse_depth
*4, "");
141 struct latin_solver_scratch
{
142 unsigned char *grid
, *rowidx
, *colidx
, *set
;
143 int *neighbours
, *bfsqueue
;
144 #ifdef STANDALONE_SOLVER
149 int latin_solver_set(struct latin_solver
*solver
,
150 struct latin_solver_scratch
*scratch
,
151 int start
, int step1
, int step2
152 #ifdef STANDALONE_SOLVER
158 #ifdef STANDALONE_SOLVER
159 char **names
= solver
->names
;
162 unsigned char *grid
= scratch
->grid
;
163 unsigned char *rowidx
= scratch
->rowidx
;
164 unsigned char *colidx
= scratch
->colidx
;
165 unsigned char *set
= scratch
->set
;
168 * We are passed a o-by-o matrix of booleans. Our first job
169 * is to winnow it by finding any definite placements - i.e.
170 * any row with a solitary 1 - and discarding that row and the
171 * column containing the 1.
173 memset(rowidx
, TRUE
, o
);
174 memset(colidx
, TRUE
, o
);
175 for (i
= 0; i
< o
; i
++) {
176 int count
= 0, first
= -1;
177 for (j
= 0; j
< o
; j
++)
178 if (solver
->cube
[start
+i
*step1
+j
*step2
])
181 if (count
== 0) return -1;
183 rowidx
[i
] = colidx
[first
] = FALSE
;
187 * Convert each of rowidx/colidx from a list of 0s and 1s to a
188 * list of the indices of the 1s.
190 for (i
= j
= 0; i
< o
; i
++)
194 for (i
= j
= 0; i
< o
; i
++)
200 * And create the smaller matrix.
202 for (i
= 0; i
< n
; i
++)
203 for (j
= 0; j
< n
; j
++)
204 grid
[i
*o
+j
] = solver
->cube
[start
+rowidx
[i
]*step1
+colidx
[j
]*step2
];
207 * Having done that, we now have a matrix in which every row
208 * has at least two 1s in. Now we search to see if we can find
209 * a rectangle of zeroes (in the set-theoretic sense of
210 * `rectangle', i.e. a subset of rows crossed with a subset of
211 * columns) whose width and height add up to n.
218 * We have a candidate set. If its size is <=1 or >=n-1
219 * then we move on immediately.
221 if (count
> 1 && count
< n
-1) {
223 * The number of rows we need is n-count. See if we can
224 * find that many rows which each have a zero in all
225 * the positions listed in `set'.
228 for (i
= 0; i
< n
; i
++) {
230 for (j
= 0; j
< n
; j
++)
231 if (set
[j
] && grid
[i
*o
+j
]) {
240 * We expect never to be able to get _more_ than
241 * n-count suitable rows: this would imply that (for
242 * example) there are four numbers which between them
243 * have at most three possible positions, and hence it
244 * indicates a faulty deduction before this point or
247 if (rows
> n
- count
) {
248 #ifdef STANDALONE_SOLVER
249 if (solver_show_working
) {
251 printf("%*s", solver_recurse_depth
*4,
256 printf(":\n%*s contradiction reached\n",
257 solver_recurse_depth
*4, "");
263 if (rows
>= n
- count
) {
264 int progress
= FALSE
;
267 * We've got one! Now, for each row which _doesn't_
268 * satisfy the criterion, eliminate all its set
269 * bits in the positions _not_ listed in `set'.
270 * Return +1 (meaning progress has been made) if we
271 * successfully eliminated anything at all.
273 * This involves referring back through
274 * rowidx/colidx in order to work out which actual
275 * positions in the cube to meddle with.
277 for (i
= 0; i
< n
; i
++) {
279 for (j
= 0; j
< n
; j
++)
280 if (set
[j
] && grid
[i
*o
+j
]) {
285 for (j
= 0; j
< n
; j
++)
286 if (!set
[j
] && grid
[i
*o
+j
]) {
287 int fpos
= (start
+rowidx
[i
]*step1
+
289 #ifdef STANDALONE_SOLVER
290 if (solver_show_working
) {
295 printf("%*s", solver_recurse_depth
*4,
308 printf("%*s ruling out %s at (%d,%d)\n",
309 solver_recurse_depth
*4, "",
310 names
[pn
-1], px
+1, py
+1);
314 solver
->cube
[fpos
] = FALSE
;
326 * Binary increment: change the rightmost 0 to a 1, and
327 * change all 1s to the right of it to 0s.
330 while (i
> 0 && set
[i
-1])
331 set
[--i
] = 0, count
--;
333 set
[--i
] = 1, count
++;
342 * Look for forcing chains. A forcing chain is a path of
343 * pairwise-exclusive squares (i.e. each pair of adjacent squares
344 * in the path are in the same row, column or block) with the
345 * following properties:
347 * (a) Each square on the path has precisely two possible numbers.
349 * (b) Each pair of squares which are adjacent on the path share
350 * at least one possible number in common.
352 * (c) Each square in the middle of the path shares _both_ of its
353 * numbers with at least one of its neighbours (not the same
354 * one with both neighbours).
356 * These together imply that at least one of the possible number
357 * choices at one end of the path forces _all_ the rest of the
358 * numbers along the path. In order to make real use of this, we
359 * need further properties:
361 * (c) Ruling out some number N from the square at one end
362 * of the path forces the square at the other end to
365 * (d) The two end squares are both in line with some third
368 * (e) That third square currently has N as a possibility.
370 * If we can find all of that lot, we can deduce that at least one
371 * of the two ends of the forcing chain has number N, and that
372 * therefore the mutually adjacent third square does not.
374 * To find forcing chains, we're going to start a bfs at each
375 * suitable square, once for each of its two possible numbers.
377 int latin_solver_forcing(struct latin_solver
*solver
,
378 struct latin_solver_scratch
*scratch
)
381 #ifdef STANDALONE_SOLVER
382 char **names
= solver
->names
;
384 int *bfsqueue
= scratch
->bfsqueue
;
385 #ifdef STANDALONE_SOLVER
386 int *bfsprev
= scratch
->bfsprev
;
388 unsigned char *number
= scratch
->grid
;
389 int *neighbours
= scratch
->neighbours
;
392 for (y
= 0; y
< o
; y
++)
393 for (x
= 0; x
< o
; x
++) {
397 * If this square doesn't have exactly two candidate
398 * numbers, don't try it.
400 * In this loop we also sum the candidate numbers,
401 * which is a nasty hack to allow us to quickly find
402 * `the other one' (since we will shortly know there
405 for (count
= t
= 0, n
= 1; n
<= o
; n
++)
412 * Now attempt a bfs for each candidate.
414 for (n
= 1; n
<= o
; n
++)
416 int orign
, currn
, head
, tail
;
423 memset(number
, o
+1, o
*o
);
425 bfsqueue
[tail
++] = y
*o
+x
;
426 #ifdef STANDALONE_SOLVER
429 number
[y
*o
+x
] = t
- n
;
431 while (head
< tail
) {
432 int xx
, yy
, nneighbours
, xt
, yt
, i
;
434 xx
= bfsqueue
[head
++];
438 currn
= number
[yy
*o
+xx
];
441 * Find neighbours of yy,xx.
444 for (yt
= 0; yt
< o
; yt
++)
445 neighbours
[nneighbours
++] = yt
*o
+xx
;
446 for (xt
= 0; xt
< o
; xt
++)
447 neighbours
[nneighbours
++] = yy
*o
+xt
;
450 * Try visiting each of those neighbours.
452 for (i
= 0; i
< nneighbours
; i
++) {
455 xt
= neighbours
[i
] % o
;
456 yt
= neighbours
[i
] / o
;
459 * We need this square to not be
460 * already visited, and to include
461 * currn as a possible number.
463 if (number
[yt
*o
+xt
] <= o
)
465 if (!cube(xt
, yt
, currn
))
469 * Don't visit _this_ square a second
472 if (xt
== xx
&& yt
== yy
)
476 * To continue with the bfs, we need
477 * this square to have exactly two
480 for (cc
= tt
= 0, nn
= 1; nn
<= o
; nn
++)
481 if (cube(xt
, yt
, nn
))
484 bfsqueue
[tail
++] = yt
*o
+xt
;
485 #ifdef STANDALONE_SOLVER
486 bfsprev
[yt
*o
+xt
] = yy
*o
+xx
;
488 number
[yt
*o
+xt
] = tt
- currn
;
492 * One other possibility is that this
493 * might be the square in which we can
494 * make a real deduction: if it's
495 * adjacent to x,y, and currn is equal
496 * to the original number we ruled out.
498 if (currn
== orign
&&
499 (xt
== x
|| yt
== y
)) {
500 #ifdef STANDALONE_SOLVER
501 if (solver_show_working
) {
504 printf("%*sforcing chain, %s at ends of ",
505 solver_recurse_depth
*4, "",
510 printf("%s(%d,%d)", sep
, xl
+1,
512 xl
= bfsprev
[yl
*o
+xl
];
519 printf("\n%*s ruling out %s at (%d,%d)\n",
520 solver_recurse_depth
*4, "",
525 cube(xt
, yt
, orign
) = FALSE
;
536 struct latin_solver_scratch
*latin_solver_new_scratch(struct latin_solver
*solver
)
538 struct latin_solver_scratch
*scratch
= snew(struct latin_solver_scratch
);
540 scratch
->grid
= snewn(o
*o
, unsigned char);
541 scratch
->rowidx
= snewn(o
, unsigned char);
542 scratch
->colidx
= snewn(o
, unsigned char);
543 scratch
->set
= snewn(o
, unsigned char);
544 scratch
->neighbours
= snewn(3*o
, int);
545 scratch
->bfsqueue
= snewn(o
*o
, int);
546 #ifdef STANDALONE_SOLVER
547 scratch
->bfsprev
= snewn(o
*o
, int);
552 void latin_solver_free_scratch(struct latin_solver_scratch
*scratch
)
554 #ifdef STANDALONE_SOLVER
555 sfree(scratch
->bfsprev
);
557 sfree(scratch
->bfsqueue
);
558 sfree(scratch
->neighbours
);
560 sfree(scratch
->colidx
);
561 sfree(scratch
->rowidx
);
562 sfree(scratch
->grid
);
566 void latin_solver_alloc(struct latin_solver
*solver
, digit
*grid
, int o
)
571 solver
->cube
= snewn(o
*o
*o
, unsigned char);
572 solver
->grid
= grid
; /* write straight back to the input */
573 memset(solver
->cube
, TRUE
, o
*o
*o
);
575 solver
->row
= snewn(o
*o
, unsigned char);
576 solver
->col
= snewn(o
*o
, unsigned char);
577 memset(solver
->row
, FALSE
, o
*o
);
578 memset(solver
->col
, FALSE
, o
*o
);
580 for (x
= 0; x
< o
; x
++)
581 for (y
= 0; y
< o
; y
++)
583 latin_solver_place(solver
, x
, y
, grid
[y
*o
+x
]);
585 #ifdef STANDALONE_SOLVER
586 solver
->names
= NULL
;
590 void latin_solver_free(struct latin_solver
*solver
)
597 int latin_solver_diff_simple(struct latin_solver
*solver
)
599 int x
, y
, n
, ret
, o
= solver
->o
;
600 #ifdef STANDALONE_SOLVER
601 char **names
= solver
->names
;
605 * Row-wise positional elimination.
607 for (y
= 0; y
< o
; y
++)
608 for (n
= 1; n
<= o
; n
++)
609 if (!solver
->row
[y
*o
+n
-1]) {
610 ret
= latin_solver_elim(solver
, cubepos(0,y
,n
), o
*o
611 #ifdef STANDALONE_SOLVER
612 , "positional elimination,"
613 " %s in row %d", names
[n
-1],
617 if (ret
!= 0) return ret
;
620 * Column-wise positional elimination.
622 for (x
= 0; x
< o
; x
++)
623 for (n
= 1; n
<= o
; n
++)
624 if (!solver
->col
[x
*o
+n
-1]) {
625 ret
= latin_solver_elim(solver
, cubepos(x
,0,n
), o
626 #ifdef STANDALONE_SOLVER
627 , "positional elimination,"
628 " %s in column %d", names
[n
-1], x
+1
631 if (ret
!= 0) return ret
;
635 * Numeric elimination.
637 for (x
= 0; x
< o
; x
++)
638 for (y
= 0; y
< o
; y
++)
639 if (!solver
->grid
[y
*o
+x
]) {
640 ret
= latin_solver_elim(solver
, cubepos(x
,y
,1), 1
641 #ifdef STANDALONE_SOLVER
642 , "numeric elimination at (%d,%d)",
646 if (ret
!= 0) return ret
;
651 int latin_solver_diff_set(struct latin_solver
*solver
,
652 struct latin_solver_scratch
*scratch
,
655 int x
, y
, n
, ret
, o
= solver
->o
;
656 #ifdef STANDALONE_SOLVER
657 char **names
= solver
->names
;
662 * Row-wise set elimination.
664 for (y
= 0; y
< o
; y
++) {
665 ret
= latin_solver_set(solver
, scratch
, cubepos(0,y
,1), o
*o
, 1
666 #ifdef STANDALONE_SOLVER
667 , "set elimination, row %d", y
+1
670 if (ret
!= 0) return ret
;
673 * Column-wise set elimination.
675 for (x
= 0; x
< o
; x
++) {
676 ret
= latin_solver_set(solver
, scratch
, cubepos(x
,0,1), o
, 1
677 #ifdef STANDALONE_SOLVER
678 , "set elimination, column %d", x
+1
681 if (ret
!= 0) return ret
;
685 * Row-vs-column set elimination on a single number
686 * (much tricker for a human to do!)
688 for (n
= 1; n
<= o
; n
++) {
689 ret
= latin_solver_set(solver
, scratch
, cubepos(0,0,n
), o
*o
, o
690 #ifdef STANDALONE_SOLVER
691 , "positional set elimination on %s",
695 if (ret
!= 0) return ret
;
703 * 0 for 'didn't do anything' implying it was already solved.
704 * -1 for 'impossible' (no solution)
705 * 1 for 'single solution'
706 * >1 for 'multiple solutions' (you don't get to know how many, and
707 * the first such solution found will be set.
709 * and this function may well assert if given an impossible board.
711 static int latin_solver_recurse
712 (struct latin_solver
*solver
, int diff_simple
, int diff_set_0
,
713 int diff_set_1
, int diff_forcing
, int diff_recursive
,
714 usersolver_t
const *usersolvers
, void *ctx
,
715 ctxnew_t ctxnew
, ctxfree_t ctxfree
)
718 int o
= solver
->o
, x
, y
, n
;
719 #ifdef STANDALONE_SOLVER
720 char **names
= solver
->names
;
726 for (y
= 0; y
< o
; y
++)
727 for (x
= 0; x
< o
; x
++)
728 if (!solver
->grid
[y
*o
+x
]) {
732 * An unfilled square. Count the number of
733 * possible digits in it.
736 for (n
= 1; n
<= o
; n
++)
741 * We should have found any impossibilities
742 * already, so this can safely be an assert.
746 if (count
< bestcount
) {
753 /* we were complete already. */
757 digit
*list
, *ingrid
, *outgrid
;
758 int diff
= diff_impossible
; /* no solution found yet */
766 list
= snewn(o
, digit
);
767 ingrid
= snewn(o
*o
, digit
);
768 outgrid
= snewn(o
*o
, digit
);
769 memcpy(ingrid
, solver
->grid
, o
*o
);
771 /* Make a list of the possible digits. */
772 for (j
= 0, n
= 1; n
<= o
; n
++)
776 #ifdef STANDALONE_SOLVER
777 if (solver_show_working
) {
779 printf("%*srecursing on (%d,%d) [",
780 solver_recurse_depth
*4, "", x
+1, y
+1);
781 for (i
= 0; i
< j
; i
++) {
782 printf("%s%s", sep
, names
[list
[i
]-1]);
790 * And step along the list, recursing back into the
791 * main solver at every stage.
793 for (i
= 0; i
< j
; i
++) {
796 struct latin_solver subsolver
;
798 memcpy(outgrid
, ingrid
, o
*o
);
799 outgrid
[y
*o
+x
] = list
[i
];
801 #ifdef STANDALONE_SOLVER
802 if (solver_show_working
)
803 printf("%*sguessing %s at (%d,%d)\n",
804 solver_recurse_depth
*4, "", names
[list
[i
]-1], x
+1, y
+1);
805 solver_recurse_depth
++;
809 newctx
= ctxnew(ctx
);
813 latin_solver_alloc(&subsolver
, outgrid
, o
);
814 #ifdef STANDALONE_SOLVER
815 subsolver
.names
= solver
->names
;
817 ret
= latin_solver_top(&subsolver
, diff_recursive
,
818 diff_simple
, diff_set_0
, diff_set_1
,
819 diff_forcing
, diff_recursive
,
820 usersolvers
, newctx
, ctxnew
, ctxfree
);
821 latin_solver_free(&subsolver
);
825 #ifdef STANDALONE_SOLVER
826 solver_recurse_depth
--;
827 if (solver_show_working
) {
828 printf("%*sretracting %s at (%d,%d)\n",
829 solver_recurse_depth
*4, "", names
[list
[i
]-1], x
+1, y
+1);
832 /* we recurse as deep as we can, so we should never find
833 * find ourselves giving up on a puzzle without declaring it
835 assert(ret
!= diff_unfinished
);
838 * If we have our first solution, copy it into the
839 * grid we will return.
841 if (diff
== diff_impossible
&& ret
!= diff_impossible
)
842 memcpy(solver
->grid
, outgrid
, o
*o
);
844 if (ret
== diff_ambiguous
)
845 diff
= diff_ambiguous
;
846 else if (ret
== diff_impossible
)
847 /* do not change our return value */;
849 /* the recursion turned up exactly one solution */
850 if (diff
== diff_impossible
)
851 diff
= diff_recursive
;
853 diff
= diff_ambiguous
;
857 * As soon as we've found more than one solution,
858 * give up immediately.
860 if (diff
== diff_ambiguous
)
868 if (diff
== diff_impossible
)
870 else if (diff
== diff_ambiguous
)
873 assert(diff
== diff_recursive
);
879 static int latin_solver_top(struct latin_solver
*solver
, int maxdiff
,
880 int diff_simple
, int diff_set_0
, int diff_set_1
,
881 int diff_forcing
, int diff_recursive
,
882 usersolver_t
const *usersolvers
, void *ctx
,
883 ctxnew_t ctxnew
, ctxfree_t ctxfree
)
885 struct latin_solver_scratch
*scratch
= latin_solver_new_scratch(solver
);
886 int ret
, diff
= diff_simple
;
888 assert(maxdiff
<= diff_recursive
);
890 * Now loop over the grid repeatedly trying all permitted modes
891 * of reasoning. The loop terminates if we complete an
892 * iteration without making any progress; we then return
893 * failure or success depending on whether the grid is full or
901 latin_solver_debug(solver
->cube
, solver
->o
);
903 for (i
= 0; i
<= maxdiff
; i
++) {
905 ret
= usersolvers
[i
](solver
, ctx
);
908 if (ret
== 0 && i
== diff_simple
)
909 ret
= latin_solver_diff_simple(solver
);
910 if (ret
== 0 && i
== diff_set_0
)
911 ret
= latin_solver_diff_set(solver
, scratch
, 0);
912 if (ret
== 0 && i
== diff_set_1
)
913 ret
= latin_solver_diff_set(solver
, scratch
, 1);
914 if (ret
== 0 && i
== diff_forcing
)
915 ret
= latin_solver_forcing(solver
, scratch
);
918 diff
= diff_impossible
;
920 } else if (ret
> 0) {
927 * If we reach here, we have made no deductions in this
928 * iteration, so the algorithm terminates.
934 * Last chance: if we haven't fully solved the puzzle yet, try
935 * recursing based on guesses for a particular square. We pick
936 * one of the most constrained empty squares we can find, which
937 * has the effect of pruning the search tree as much as
940 if (maxdiff
== diff_recursive
) {
941 int nsol
= latin_solver_recurse(solver
,
942 diff_simple
, diff_set_0
, diff_set_1
,
943 diff_forcing
, diff_recursive
,
944 usersolvers
, ctx
, ctxnew
, ctxfree
);
945 if (nsol
< 0) diff
= diff_impossible
;
946 else if (nsol
== 1) diff
= diff_recursive
;
947 else if (nsol
> 1) diff
= diff_ambiguous
;
948 /* if nsol == 0 then we were complete anyway
949 * (and thus don't need to change diff) */
952 * We're forbidden to use recursion, so we just see whether
953 * our grid is fully solved, and return diff_unfinished
956 int x
, y
, o
= solver
->o
;
958 for (y
= 0; y
< o
; y
++)
959 for (x
= 0; x
< o
; x
++)
960 if (!solver
->grid
[y
*o
+x
])
961 diff
= diff_unfinished
;
966 #ifdef STANDALONE_SOLVER
967 if (solver_show_working
)
968 printf("%*s%s found\n",
969 solver_recurse_depth
*4, "",
970 diff
== diff_impossible
? "no solution (impossible)" :
971 diff
== diff_unfinished
? "no solution (unfinished)" :
972 diff
== diff_ambiguous
? "multiple solutions" :
976 latin_solver_free_scratch(scratch
);
981 int latin_solver_main(struct latin_solver
*solver
, int maxdiff
,
982 int diff_simple
, int diff_set_0
, int diff_set_1
,
983 int diff_forcing
, int diff_recursive
,
984 usersolver_t
const *usersolvers
, void *ctx
,
985 ctxnew_t ctxnew
, ctxfree_t ctxfree
)
988 #ifdef STANDALONE_SOLVER
990 char *text
= NULL
, **names
= NULL
;
993 #ifdef STANDALONE_SOLVER
994 if (!solver
->names
) {
998 text
= snewn(40 * o
, char);
1001 solver
->names
= snewn(o
, char *);
1003 for (i
= 0; i
< o
; i
++) {
1004 solver
->names
[i
] = p
;
1005 p
+= 1 + sprintf(p
, "%d", i
+1);
1010 diff
= latin_solver_top(solver
, maxdiff
,
1011 diff_simple
, diff_set_0
, diff_set_1
,
1012 diff_forcing
, diff_recursive
,
1013 usersolvers
, ctx
, ctxnew
, ctxfree
);
1015 #ifdef STANDALONE_SOLVER
1023 int latin_solver(digit
*grid
, int o
, int maxdiff
,
1024 int diff_simple
, int diff_set_0
, int diff_set_1
,
1025 int diff_forcing
, int diff_recursive
,
1026 usersolver_t
const *usersolvers
, void *ctx
,
1027 ctxnew_t ctxnew
, ctxfree_t ctxfree
)
1029 struct latin_solver solver
;
1032 latin_solver_alloc(&solver
, grid
, o
);
1033 diff
= latin_solver_main(&solver
, maxdiff
,
1034 diff_simple
, diff_set_0
, diff_set_1
,
1035 diff_forcing
, diff_recursive
,
1036 usersolvers
, ctx
, ctxnew
, ctxfree
);
1037 latin_solver_free(&solver
);
1041 void latin_solver_debug(unsigned char *cube
, int o
)
1043 #ifdef STANDALONE_SOLVER
1044 if (solver_show_working
> 1) {
1045 struct latin_solver ls
, *solver
= &ls
;
1049 ls
.cube
= cube
; ls
.o
= o
; /* for cube() to work */
1051 dbg
= snewn(3*o
*o
*o
, char);
1052 for (y
= 0; y
< o
; y
++) {
1053 for (x
= 0; x
< o
; x
++) {
1054 for (i
= 1; i
<= o
; i
++) {
1073 void latin_debug(digit
*sq
, int o
)
1075 #ifdef STANDALONE_SOLVER
1076 if (solver_show_working
) {
1079 for (y
= 0; y
< o
; y
++) {
1080 for (x
= 0; x
< o
; x
++) {
1081 printf("%2d ", sq
[y
*o
+x
]);
1090 /* --------------------------------------------------------
1094 digit
*latin_generate(int o
, random_state
*rs
)
1097 int *edges
, *backedges
, *capacity
, *flow
;
1099 int ne
, scratchsize
;
1101 digit
*row
, *col
, *numinv
, *num
;
1104 * To efficiently generate a latin square in such a way that
1105 * all possible squares are possible outputs from the function,
1106 * we make use of a theorem which states that any r x n latin
1107 * rectangle, with r < n, can be extended into an (r+1) x n
1108 * latin rectangle. In other words, we can reliably generate a
1109 * latin square row by row, by at every stage writing down any
1110 * row at all which doesn't conflict with previous rows, and
1111 * the theorem guarantees that we will never have to backtrack.
1113 * To find a viable row at each stage, we can make use of the
1114 * support functions in maxflow.c.
1117 sq
= snewn(o
*o
, digit
);
1120 * In case this method of generation introduces a really subtle
1121 * top-to-bottom directional bias, we'll generate the rows in
1124 row
= snewn(o
, digit
);
1125 col
= snewn(o
, digit
);
1126 numinv
= snewn(o
, digit
);
1127 num
= snewn(o
, digit
);
1128 for (i
= 0; i
< o
; i
++)
1130 shuffle(row
, i
, sizeof(*row
), rs
);
1133 * Set up the infrastructure for the maxflow algorithm.
1135 scratchsize
= maxflow_scratch_size(o
* 2 + 2);
1136 scratch
= smalloc(scratchsize
);
1137 backedges
= snewn(o
*o
+ 2*o
, int);
1138 edges
= snewn((o
*o
+ 2*o
) * 2, int);
1139 capacity
= snewn(o
*o
+ 2*o
, int);
1140 flow
= snewn(o
*o
+ 2*o
, int);
1141 /* Set up the edge array, and the initial capacities. */
1143 for (i
= 0; i
< o
; i
++) {
1144 /* Each LHS vertex is connected to all RHS vertices. */
1145 for (j
= 0; j
< o
; j
++) {
1147 edges
[ne
*2+1] = j
+o
;
1148 /* capacity for this edge is set later on */
1152 for (i
= 0; i
< o
; i
++) {
1153 /* Each RHS vertex is connected to the distinguished sink vertex. */
1155 edges
[ne
*2+1] = o
*2+1;
1159 for (i
= 0; i
< o
; i
++) {
1160 /* And the distinguished source vertex connects to each LHS vertex. */
1166 assert(ne
== o
*o
+ 2*o
);
1167 /* Now set up backedges. */
1168 maxflow_setup_backedges(ne
, edges
, backedges
);
1171 * Now generate each row of the latin square.
1173 for (i
= 0; i
< o
; i
++) {
1175 * To prevent maxflow from behaving deterministically, we
1176 * separately permute the columns and the digits for the
1177 * purposes of the algorithm, differently for every row.
1179 for (j
= 0; j
< o
; j
++)
1180 col
[j
] = num
[j
] = j
;
1181 shuffle(col
, j
, sizeof(*col
), rs
);
1182 shuffle(num
, j
, sizeof(*num
), rs
);
1183 /* We need the num permutation in both forward and inverse forms. */
1184 for (j
= 0; j
< o
; j
++)
1188 * Set up the capacities for the maxflow run, by examining
1189 * the existing latin square.
1191 for (j
= 0; j
< o
*o
; j
++)
1193 for (j
= 0; j
< i
; j
++)
1194 for (k
= 0; k
< o
; k
++) {
1195 int n
= num
[sq
[row
[j
]*o
+ col
[k
]] - 1];
1196 capacity
[k
*o
+n
] = 0;
1202 j
= maxflow_with_scratch(scratch
, o
*2+2, 2*o
, 2*o
+1, ne
,
1203 edges
, backedges
, capacity
, flow
, NULL
);
1204 assert(j
== o
); /* by the above theorem, this must have succeeded */
1207 * And examine the flow array to pick out the new row of
1210 for (j
= 0; j
< o
; j
++) {
1211 for (k
= 0; k
< o
; k
++) {
1216 sq
[row
[i
]*o
+ col
[j
]] = numinv
[k
] + 1;
1221 * Done. Free our internal workspaces...
1234 * ... and return our completed latin square.
1239 digit
*latin_generate_rect(int w
, int h
, random_state
*rs
)
1241 int o
= max(w
, h
), x
, y
;
1242 digit
*latin
, *latin_rect
;
1244 latin
= latin_generate(o
, rs
);
1245 latin_rect
= snewn(w
*h
, digit
);
1247 for (x
= 0; x
< w
; x
++) {
1248 for (y
= 0; y
< h
; y
++) {
1249 latin_rect
[y
*w
+ x
] = latin
[y
*o
+ x
];
1257 /* --------------------------------------------------------
1261 typedef struct lcparams
{
1266 static int latin_check_cmp(void *v1
, void *v2
)
1268 lcparams
*lc1
= (lcparams
*)v1
;
1269 lcparams
*lc2
= (lcparams
*)v2
;
1271 if (lc1
->elt
< lc2
->elt
) return -1;
1272 if (lc1
->elt
> lc2
->elt
) return 1;
1276 #define ELT(sq,x,y) (sq[((y)*order)+(x)])
1278 /* returns non-zero if sq is not a latin square. */
1279 int latin_check(digit
*sq
, int order
)
1281 tree234
*dict
= newtree234(latin_check_cmp
);
1284 lcparams
*lcp
, lc
, *aret
;
1286 /* Use a tree234 as a simple hash table, go through the square
1287 * adding elements as we go or incrementing their counts. */
1288 for (c
= 0; c
< order
; c
++) {
1289 for (r
= 0; r
< order
; r
++) {
1290 lc
.elt
= ELT(sq
, c
, r
); lc
.count
= 0;
1291 lcp
= find234(dict
, &lc
, NULL
);
1293 lcp
= snew(lcparams
);
1294 lcp
->elt
= ELT(sq
, c
, r
);
1296 aret
= add234(dict
, lcp
);
1297 assert(aret
== lcp
);
1304 /* There should be precisely 'order' letters in the alphabet,
1305 * each occurring 'order' times (making the OxO tree) */
1306 if (count234(dict
) != order
) ret
= 1;
1308 for (c
= 0; (lcp
= index234(dict
, c
)) != NULL
; c
++) {
1309 if (lcp
->count
!= order
) ret
= 1;
1312 for (c
= 0; (lcp
= index234(dict
, c
)) != NULL
; c
++)
1320 /* --------------------------------------------------------
1321 * Testing (and printing).
1324 #ifdef STANDALONE_LATIN_TEST
1331 static void latin_print(digit
*sq
, int order
)
1335 for (y
= 0; y
< order
; y
++) {
1336 for (x
= 0; x
< order
; x
++) {
1337 printf("%2u ", ELT(sq
, x
, y
));
1344 static void gen(int order
, random_state
*rs
, int debug
)
1348 solver_show_working
= debug
;
1350 sq
= latin_generate(order
, rs
);
1351 latin_print(sq
, order
);
1352 if (latin_check(sq
, order
)) {
1353 fprintf(stderr
, "Square is not a latin square!");
1360 void test_soak(int order
, random_state
*rs
)
1364 time_t tt_start
, tt_now
, tt_last
;
1366 solver_show_working
= 0;
1367 tt_now
= tt_start
= time(NULL
);
1370 sq
= latin_generate(order
, rs
);
1374 tt_last
= time(NULL
);
1375 if (tt_last
> tt_now
) {
1377 printf("%d total, %3.1f/s\n", n
,
1378 (double)n
/ (double)(tt_now
- tt_start
));
1383 void usage_exit(const char *msg
)
1386 fprintf(stderr
, "%s: %s\n", quis
, msg
);
1387 fprintf(stderr
, "Usage: %s [--seed SEED] --soak <params> | [game_id [game_id ...]]\n", quis
);
1391 int main(int argc
, char *argv
[])
1395 time_t seed
= time(NULL
);
1398 while (--argc
> 0) {
1399 const char *p
= *++argv
;
1400 if (!strcmp(p
, "--soak"))
1402 else if (!strcmp(p
, "--seed")) {
1404 usage_exit("--seed needs an argument");
1405 seed
= (time_t)atoi(*++argv
);
1407 } else if (*p
== '-')
1408 usage_exit("unrecognised option");
1410 break; /* finished options */
1413 rs
= random_new((void*)&seed
, sizeof(time_t));
1416 if (argc
!= 1) usage_exit("only one argument for --soak");
1417 test_soak(atoi(*argv
), rs
);
1420 for (i
= 0; i
< argc
; i
++) {
1421 gen(atoi(*argv
++), rs
, 1);
1425 i
= random_upto(rs
, 20) + 1;
1436 /* vim: set shiftwidth=4 tabstop=8: */