9 #ifdef STANDALONE_LATIN_TEST
10 #define STANDALONE_SOLVER
15 /* --------------------------------------------------------
19 #ifdef STANDALONE_SOLVER
20 int solver_show_working
, solver_recurse_depth
;
24 * Function called when we are certain that a particular square has
25 * a particular number in it. The y-coordinate passed in here is
28 void latin_solver_place(struct latin_solver
*solver
, int x
, int y
, int n
)
36 * Rule out all other numbers in this square.
38 for (i
= 1; i
<= o
; i
++)
43 * Rule out this number in all other positions in the row.
45 for (i
= 0; i
< o
; i
++)
50 * Rule out this number in all other positions in the column.
52 for (i
= 0; i
< o
; i
++)
57 * Enter the number in the result grid.
59 solver
->grid
[YUNTRANS(y
)*o
+x
] = n
;
62 * Cross out this number from the list of numbers left to place
63 * in its row, its column and its block.
65 solver
->row
[y
*o
+n
-1] = solver
->col
[x
*o
+n
-1] = TRUE
;
68 int latin_solver_elim(struct latin_solver
*solver
, int start
, int step
69 #ifdef STANDALONE_SOLVER
78 * Count the number of set bits within this section of the
83 for (i
= 0; i
< o
; i
++)
84 if (solver
->cube
[start
+i
*step
]) {
98 if (!solver
->grid
[YUNTRANS(y
)*o
+x
]) {
99 #ifdef STANDALONE_SOLVER
100 if (solver_show_working
) {
102 printf("%*s", solver_recurse_depth
*4, "");
106 printf(":\n%*s placing %d at (%d,%d)\n",
107 solver_recurse_depth
*4, "", n
, x
+1, YUNTRANS(y
)+1);
110 latin_solver_place(solver
, x
, y
, n
);
114 #ifdef STANDALONE_SOLVER
115 if (solver_show_working
) {
117 printf("%*s", solver_recurse_depth
*4, "");
121 printf(":\n%*s no possibilities available\n",
122 solver_recurse_depth
*4, "");
131 struct latin_solver_scratch
{
132 unsigned char *grid
, *rowidx
, *colidx
, *set
;
133 int *neighbours
, *bfsqueue
;
134 #ifdef STANDALONE_SOLVER
139 int latin_solver_set(struct latin_solver
*solver
,
140 struct latin_solver_scratch
*scratch
,
141 int start
, int step1
, int step2
142 #ifdef STANDALONE_SOLVER
149 unsigned char *grid
= scratch
->grid
;
150 unsigned char *rowidx
= scratch
->rowidx
;
151 unsigned char *colidx
= scratch
->colidx
;
152 unsigned char *set
= scratch
->set
;
155 * We are passed a o-by-o matrix of booleans. Our first job
156 * is to winnow it by finding any definite placements - i.e.
157 * any row with a solitary 1 - and discarding that row and the
158 * column containing the 1.
160 memset(rowidx
, TRUE
, o
);
161 memset(colidx
, TRUE
, o
);
162 for (i
= 0; i
< o
; i
++) {
163 int count
= 0, first
= -1;
164 for (j
= 0; j
< o
; j
++)
165 if (solver
->cube
[start
+i
*step1
+j
*step2
])
168 if (count
== 0) return -1;
170 rowidx
[i
] = colidx
[first
] = FALSE
;
174 * Convert each of rowidx/colidx from a list of 0s and 1s to a
175 * list of the indices of the 1s.
177 for (i
= j
= 0; i
< o
; i
++)
181 for (i
= j
= 0; i
< o
; i
++)
187 * And create the smaller matrix.
189 for (i
= 0; i
< n
; i
++)
190 for (j
= 0; j
< n
; j
++)
191 grid
[i
*o
+j
] = solver
->cube
[start
+rowidx
[i
]*step1
+colidx
[j
]*step2
];
194 * Having done that, we now have a matrix in which every row
195 * has at least two 1s in. Now we search to see if we can find
196 * a rectangle of zeroes (in the set-theoretic sense of
197 * `rectangle', i.e. a subset of rows crossed with a subset of
198 * columns) whose width and height add up to n.
205 * We have a candidate set. If its size is <=1 or >=n-1
206 * then we move on immediately.
208 if (count
> 1 && count
< n
-1) {
210 * The number of rows we need is n-count. See if we can
211 * find that many rows which each have a zero in all
212 * the positions listed in `set'.
215 for (i
= 0; i
< n
; i
++) {
217 for (j
= 0; j
< n
; j
++)
218 if (set
[j
] && grid
[i
*o
+j
]) {
227 * We expect never to be able to get _more_ than
228 * n-count suitable rows: this would imply that (for
229 * example) there are four numbers which between them
230 * have at most three possible positions, and hence it
231 * indicates a faulty deduction before this point or
234 if (rows
> n
- count
) {
235 #ifdef STANDALONE_SOLVER
236 if (solver_show_working
) {
238 printf("%*s", solver_recurse_depth
*4,
243 printf(":\n%*s contradiction reached\n",
244 solver_recurse_depth
*4, "");
250 if (rows
>= n
- count
) {
251 int progress
= FALSE
;
254 * We've got one! Now, for each row which _doesn't_
255 * satisfy the criterion, eliminate all its set
256 * bits in the positions _not_ listed in `set'.
257 * Return +1 (meaning progress has been made) if we
258 * successfully eliminated anything at all.
260 * This involves referring back through
261 * rowidx/colidx in order to work out which actual
262 * positions in the cube to meddle with.
264 for (i
= 0; i
< n
; i
++) {
266 for (j
= 0; j
< n
; j
++)
267 if (set
[j
] && grid
[i
*o
+j
]) {
272 for (j
= 0; j
< n
; j
++)
273 if (!set
[j
] && grid
[i
*o
+j
]) {
274 int fpos
= (start
+rowidx
[i
]*step1
+
276 #ifdef STANDALONE_SOLVER
277 if (solver_show_working
) {
282 printf("%*s", solver_recurse_depth
*4,
295 printf("%*s ruling out %d at (%d,%d)\n",
296 solver_recurse_depth
*4, "",
297 pn
, px
+1, YUNTRANS(py
)+1);
301 solver
->cube
[fpos
] = FALSE
;
313 * Binary increment: change the rightmost 0 to a 1, and
314 * change all 1s to the right of it to 0s.
317 while (i
> 0 && set
[i
-1])
318 set
[--i
] = 0, count
--;
320 set
[--i
] = 1, count
++;
329 * Look for forcing chains. A forcing chain is a path of
330 * pairwise-exclusive squares (i.e. each pair of adjacent squares
331 * in the path are in the same row, column or block) with the
332 * following properties:
334 * (a) Each square on the path has precisely two possible numbers.
336 * (b) Each pair of squares which are adjacent on the path share
337 * at least one possible number in common.
339 * (c) Each square in the middle of the path shares _both_ of its
340 * numbers with at least one of its neighbours (not the same
341 * one with both neighbours).
343 * These together imply that at least one of the possible number
344 * choices at one end of the path forces _all_ the rest of the
345 * numbers along the path. In order to make real use of this, we
346 * need further properties:
348 * (c) Ruling out some number N from the square at one end
349 * of the path forces the square at the other end to
352 * (d) The two end squares are both in line with some third
355 * (e) That third square currently has N as a possibility.
357 * If we can find all of that lot, we can deduce that at least one
358 * of the two ends of the forcing chain has number N, and that
359 * therefore the mutually adjacent third square does not.
361 * To find forcing chains, we're going to start a bfs at each
362 * suitable square, once for each of its two possible numbers.
364 int latin_solver_forcing(struct latin_solver
*solver
,
365 struct latin_solver_scratch
*scratch
)
368 int *bfsqueue
= scratch
->bfsqueue
;
369 #ifdef STANDALONE_SOLVER
370 int *bfsprev
= scratch
->bfsprev
;
372 unsigned char *number
= scratch
->grid
;
373 int *neighbours
= scratch
->neighbours
;
376 for (y
= 0; y
< o
; y
++)
377 for (x
= 0; x
< o
; x
++) {
381 * If this square doesn't have exactly two candidate
382 * numbers, don't try it.
384 * In this loop we also sum the candidate numbers,
385 * which is a nasty hack to allow us to quickly find
386 * `the other one' (since we will shortly know there
389 for (count
= t
= 0, n
= 1; n
<= o
; n
++)
396 * Now attempt a bfs for each candidate.
398 for (n
= 1; n
<= o
; n
++)
400 int orign
, currn
, head
, tail
;
407 memset(number
, o
+1, o
*o
);
409 bfsqueue
[tail
++] = y
*o
+x
;
410 #ifdef STANDALONE_SOLVER
413 number
[y
*o
+x
] = t
- n
;
415 while (head
< tail
) {
416 int xx
, yy
, nneighbours
, xt
, yt
, i
;
418 xx
= bfsqueue
[head
++];
422 currn
= number
[yy
*o
+xx
];
425 * Find neighbours of yy,xx.
428 for (yt
= 0; yt
< o
; yt
++)
429 neighbours
[nneighbours
++] = yt
*o
+xx
;
430 for (xt
= 0; xt
< o
; xt
++)
431 neighbours
[nneighbours
++] = yy
*o
+xt
;
434 * Try visiting each of those neighbours.
436 for (i
= 0; i
< nneighbours
; i
++) {
439 xt
= neighbours
[i
] % o
;
440 yt
= neighbours
[i
] / o
;
443 * We need this square to not be
444 * already visited, and to include
445 * currn as a possible number.
447 if (number
[yt
*o
+xt
] <= o
)
449 if (!cube(xt
, yt
, currn
))
453 * Don't visit _this_ square a second
456 if (xt
== xx
&& yt
== yy
)
460 * To continue with the bfs, we need
461 * this square to have exactly two
464 for (cc
= tt
= 0, nn
= 1; nn
<= o
; nn
++)
465 if (cube(xt
, yt
, nn
))
468 bfsqueue
[tail
++] = yt
*o
+xt
;
469 #ifdef STANDALONE_SOLVER
470 bfsprev
[yt
*o
+xt
] = yy
*o
+xx
;
472 number
[yt
*o
+xt
] = tt
- currn
;
476 * One other possibility is that this
477 * might be the square in which we can
478 * make a real deduction: if it's
479 * adjacent to x,y, and currn is equal
480 * to the original number we ruled out.
482 if (currn
== orign
&&
483 (xt
== x
|| yt
== y
)) {
484 #ifdef STANDALONE_SOLVER
485 if (solver_show_working
) {
488 printf("%*sforcing chain, %d at ends of ",
489 solver_recurse_depth
*4, "", orign
);
493 printf("%s(%d,%d)", sep
, xl
+1,
495 xl
= bfsprev
[yl
*o
+xl
];
502 printf("\n%*s ruling out %d at (%d,%d)\n",
503 solver_recurse_depth
*4, "",
504 orign
, xt
+1, YUNTRANS(yt
)+1);
507 cube(xt
, yt
, orign
) = FALSE
;
518 struct latin_solver_scratch
*latin_solver_new_scratch(struct latin_solver
*solver
)
520 struct latin_solver_scratch
*scratch
= snew(struct latin_solver_scratch
);
522 scratch
->grid
= snewn(o
*o
, unsigned char);
523 scratch
->rowidx
= snewn(o
, unsigned char);
524 scratch
->colidx
= snewn(o
, unsigned char);
525 scratch
->set
= snewn(o
, unsigned char);
526 scratch
->neighbours
= snewn(3*o
, int);
527 scratch
->bfsqueue
= snewn(o
*o
, int);
528 #ifdef STANDALONE_SOLVER
529 scratch
->bfsprev
= snewn(o
*o
, int);
534 void latin_solver_free_scratch(struct latin_solver_scratch
*scratch
)
536 #ifdef STANDALONE_SOLVER
537 sfree(scratch
->bfsprev
);
539 sfree(scratch
->bfsqueue
);
540 sfree(scratch
->neighbours
);
542 sfree(scratch
->colidx
);
543 sfree(scratch
->rowidx
);
544 sfree(scratch
->grid
);
548 void latin_solver_alloc(struct latin_solver
*solver
, digit
*grid
, int o
)
553 solver
->cube
= snewn(o
*o
*o
, unsigned char);
554 solver
->grid
= grid
; /* write straight back to the input */
555 memset(solver
->cube
, TRUE
, o
*o
*o
);
557 solver
->row
= snewn(o
*o
, unsigned char);
558 solver
->col
= snewn(o
*o
, unsigned char);
559 memset(solver
->row
, FALSE
, o
*o
);
560 memset(solver
->col
, FALSE
, o
*o
);
562 for (x
= 0; x
< o
; x
++)
563 for (y
= 0; y
< o
; y
++)
565 latin_solver_place(solver
, x
, YTRANS(y
), grid
[y
*o
+x
]);
568 void latin_solver_free(struct latin_solver
*solver
)
575 int latin_solver_diff_simple(struct latin_solver
*solver
)
577 int x
, y
, n
, ret
, o
= solver
->o
;
579 * Row-wise positional elimination.
581 for (y
= 0; y
< o
; y
++)
582 for (n
= 1; n
<= o
; n
++)
583 if (!solver
->row
[y
*o
+n
-1]) {
584 ret
= latin_solver_elim(solver
, cubepos(0,y
,n
), o
*o
585 #ifdef STANDALONE_SOLVER
586 , "positional elimination,"
587 " %d in row %d", n
, YUNTRANS(y
)+1
590 if (ret
!= 0) return ret
;
593 * Column-wise positional elimination.
595 for (x
= 0; x
< o
; x
++)
596 for (n
= 1; n
<= o
; n
++)
597 if (!solver
->col
[x
*o
+n
-1]) {
598 ret
= latin_solver_elim(solver
, cubepos(x
,0,n
), o
599 #ifdef STANDALONE_SOLVER
600 , "positional elimination,"
601 " %d in column %d", n
, x
+1
604 if (ret
!= 0) return ret
;
608 * Numeric elimination.
610 for (x
= 0; x
< o
; x
++)
611 for (y
= 0; y
< o
; y
++)
612 if (!solver
->grid
[YUNTRANS(y
)*o
+x
]) {
613 ret
= latin_solver_elim(solver
, cubepos(x
,y
,1), 1
614 #ifdef STANDALONE_SOLVER
615 , "numeric elimination at (%d,%d)",
619 if (ret
!= 0) return ret
;
624 int latin_solver_diff_set(struct latin_solver
*solver
,
625 struct latin_solver_scratch
*scratch
,
628 int x
, y
, n
, ret
, o
= solver
->o
;
632 * Row-wise set elimination.
634 for (y
= 0; y
< o
; y
++) {
635 ret
= latin_solver_set(solver
, scratch
, cubepos(0,y
,1), o
*o
, 1
636 #ifdef STANDALONE_SOLVER
637 , "set elimination, row %d", YUNTRANS(y
)+1
640 if (ret
!= 0) return ret
;
643 * Column-wise set elimination.
645 for (x
= 0; x
< o
; x
++) {
646 ret
= latin_solver_set(solver
, scratch
, cubepos(x
,0,1), o
, 1
647 #ifdef STANDALONE_SOLVER
648 , "set elimination, column %d", x
+1
651 if (ret
!= 0) return ret
;
655 * Row-vs-column set elimination on a single number
656 * (much tricker for a human to do!)
658 for (n
= 1; n
<= o
; n
++) {
659 ret
= latin_solver_set(solver
, scratch
, cubepos(0,0,n
), o
*o
, o
660 #ifdef STANDALONE_SOLVER
661 , "positional set elimination, number %d", n
664 if (ret
!= 0) return ret
;
672 * 0 for 'didn't do anything' implying it was already solved.
673 * -1 for 'impossible' (no solution)
674 * 1 for 'single solution'
675 * >1 for 'multiple solutions' (you don't get to know how many, and
676 * the first such solution found will be set.
678 * and this function may well assert if given an impossible board.
680 static int latin_solver_recurse
681 (struct latin_solver
*solver
, int diff_simple
, int diff_set_0
,
682 int diff_set_1
, int diff_forcing
, int diff_recursive
,
683 usersolver_t
const *usersolvers
, void *ctx
,
684 ctxnew_t ctxnew
, ctxfree_t ctxfree
)
687 int o
= solver
->o
, x
, y
, n
;
692 for (y
= 0; y
< o
; y
++)
693 for (x
= 0; x
< o
; x
++)
694 if (!solver
->grid
[y
*o
+x
]) {
698 * An unfilled square. Count the number of
699 * possible digits in it.
702 for (n
= 1; n
<= o
; n
++)
703 if (cube(x
,YTRANS(y
),n
))
707 * We should have found any impossibilities
708 * already, so this can safely be an assert.
712 if (count
< bestcount
) {
719 /* we were complete already. */
723 digit
*list
, *ingrid
, *outgrid
;
724 int diff
= diff_impossible
; /* no solution found yet */
732 list
= snewn(o
, digit
);
733 ingrid
= snewn(o
*o
, digit
);
734 outgrid
= snewn(o
*o
, digit
);
735 memcpy(ingrid
, solver
->grid
, o
*o
);
737 /* Make a list of the possible digits. */
738 for (j
= 0, n
= 1; n
<= o
; n
++)
739 if (cube(x
,YTRANS(y
),n
))
742 #ifdef STANDALONE_SOLVER
743 if (solver_show_working
) {
745 printf("%*srecursing on (%d,%d) [",
746 solver_recurse_depth
*4, "", x
+1, y
+1);
747 for (i
= 0; i
< j
; i
++) {
748 printf("%s%d", sep
, list
[i
]);
756 * And step along the list, recursing back into the
757 * main solver at every stage.
759 for (i
= 0; i
< j
; i
++) {
763 memcpy(outgrid
, ingrid
, o
*o
);
764 outgrid
[y
*o
+x
] = list
[i
];
766 #ifdef STANDALONE_SOLVER
767 if (solver_show_working
)
768 printf("%*sguessing %d at (%d,%d)\n",
769 solver_recurse_depth
*4, "", list
[i
], x
+1, y
+1);
770 solver_recurse_depth
++;
774 newctx
= ctxnew(ctx
);
778 ret
= latin_solver(outgrid
, o
, diff_recursive
,
779 diff_simple
, diff_set_0
, diff_set_1
,
780 diff_forcing
, diff_recursive
,
781 usersolvers
, newctx
, ctxnew
, ctxfree
);
785 #ifdef STANDALONE_SOLVER
786 solver_recurse_depth
--;
787 if (solver_show_working
) {
788 printf("%*sretracting %d at (%d,%d)\n",
789 solver_recurse_depth
*4, "", list
[i
], x
+1, y
+1);
792 /* we recurse as deep as we can, so we should never find
793 * find ourselves giving up on a puzzle without declaring it
795 assert(ret
!= diff_unfinished
);
798 * If we have our first solution, copy it into the
799 * grid we will return.
801 if (diff
== diff_impossible
&& ret
!= diff_impossible
)
802 memcpy(solver
->grid
, outgrid
, o
*o
);
804 if (ret
== diff_ambiguous
)
805 diff
= diff_ambiguous
;
806 else if (ret
== diff_impossible
)
807 /* do not change our return value */;
809 /* the recursion turned up exactly one solution */
810 if (diff
== diff_impossible
)
811 diff
= diff_recursive
;
813 diff
= diff_ambiguous
;
817 * As soon as we've found more than one solution,
818 * give up immediately.
820 if (diff
== diff_ambiguous
)
828 if (diff
== diff_impossible
)
830 else if (diff
== diff_ambiguous
)
833 assert(diff
== diff_recursive
);
839 int latin_solver_main(struct latin_solver
*solver
, int maxdiff
,
840 int diff_simple
, int diff_set_0
, int diff_set_1
,
841 int diff_forcing
, int diff_recursive
,
842 usersolver_t
const *usersolvers
, void *ctx
,
843 ctxnew_t ctxnew
, ctxfree_t ctxfree
)
845 struct latin_solver_scratch
*scratch
= latin_solver_new_scratch(solver
);
846 int ret
, diff
= diff_simple
;
848 assert(maxdiff
<= diff_recursive
);
850 * Now loop over the grid repeatedly trying all permitted modes
851 * of reasoning. The loop terminates if we complete an
852 * iteration without making any progress; we then return
853 * failure or success depending on whether the grid is full or
861 latin_solver_debug(solver
->cube
, solver
->o
);
863 for (i
= 0; i
<= maxdiff
; i
++) {
865 ret
= usersolvers
[i
](solver
, ctx
);
868 if (ret
== 0 && i
== diff_simple
)
869 ret
= latin_solver_diff_simple(solver
);
870 if (ret
== 0 && i
== diff_set_0
)
871 ret
= latin_solver_diff_set(solver
, scratch
, 0);
872 if (ret
== 0 && i
== diff_set_1
)
873 ret
= latin_solver_diff_set(solver
, scratch
, 1);
874 if (ret
== 0 && i
== diff_forcing
)
875 ret
= latin_solver_forcing(solver
, scratch
);
878 diff
= diff_impossible
;
880 } else if (ret
> 0) {
887 * If we reach here, we have made no deductions in this
888 * iteration, so the algorithm terminates.
894 * Last chance: if we haven't fully solved the puzzle yet, try
895 * recursing based on guesses for a particular square. We pick
896 * one of the most constrained empty squares we can find, which
897 * has the effect of pruning the search tree as much as
900 if (maxdiff
== diff_recursive
) {
901 int nsol
= latin_solver_recurse(solver
,
902 diff_simple
, diff_set_0
, diff_set_1
,
903 diff_forcing
, diff_recursive
,
904 usersolvers
, ctx
, ctxnew
, ctxfree
);
905 if (nsol
< 0) diff
= diff_impossible
;
906 else if (nsol
== 1) diff
= diff_recursive
;
907 else if (nsol
> 1) diff
= diff_ambiguous
;
908 /* if nsol == 0 then we were complete anyway
909 * (and thus don't need to change diff) */
912 * We're forbidden to use recursion, so we just see whether
913 * our grid is fully solved, and return diff_unfinished
916 int x
, y
, o
= solver
->o
;
918 for (y
= 0; y
< o
; y
++)
919 for (x
= 0; x
< o
; x
++)
920 if (!solver
->grid
[y
*o
+x
])
921 diff
= diff_unfinished
;
926 #ifdef STANDALONE_SOLVER
927 if (solver_show_working
)
928 printf("%*s%s found\n",
929 solver_recurse_depth
*4, "",
930 diff
== diff_impossible ?
"no solution (impossible)" :
931 diff
== diff_unfinished ?
"no solution (unfinished)" :
932 diff
== diff_ambiguous ?
"multiple solutions" :
936 latin_solver_free_scratch(scratch
);
941 int latin_solver(digit
*grid
, int o
, int maxdiff
,
942 int diff_simple
, int diff_set_0
, int diff_set_1
,
943 int diff_forcing
, int diff_recursive
,
944 usersolver_t
const *usersolvers
, void *ctx
,
945 ctxnew_t ctxnew
, ctxfree_t ctxfree
)
947 struct latin_solver solver
;
950 latin_solver_alloc(&solver
, grid
, o
);
951 diff
= latin_solver_main(&solver
, maxdiff
,
952 diff_simple
, diff_set_0
, diff_set_1
,
953 diff_forcing
, diff_recursive
,
954 usersolvers
, ctx
, ctxnew
, ctxfree
);
955 latin_solver_free(&solver
);
959 void latin_solver_debug(unsigned char *cube
, int o
)
961 #ifdef STANDALONE_SOLVER
962 if (solver_show_working
> 1) {
963 struct latin_solver ls
, *solver
= &ls
;
967 ls
.cube
= cube
; ls
.o
= o
; /* for cube() to work */
969 dbg
= snewn(3*o
*o
*o
, char);
970 for (y
= 0; y
< o
; y
++) {
971 for (x
= 0; x
< o
; x
++) {
972 for (i
= 1; i
<= o
; i
++) {
991 void latin_debug(digit
*sq
, int o
)
993 #ifdef STANDALONE_SOLVER
994 if (solver_show_working
) {
997 for (y
= 0; y
< o
; y
++) {
998 for (x
= 0; x
< o
; x
++) {
999 printf("%2d ", sq
[y
*o
+x
]);
1008 /* --------------------------------------------------------
1012 digit
*latin_generate(int o
, random_state
*rs
)
1015 int *edges
, *backedges
, *capacity
, *flow
;
1017 int ne
, scratchsize
;
1019 digit
*row
, *col
, *numinv
, *num
;
1022 * To efficiently generate a latin square in such a way that
1023 * all possible squares are possible outputs from the function,
1024 * we make use of a theorem which states that any r x n latin
1025 * rectangle, with r < n, can be extended into an (r+1) x n
1026 * latin rectangle. In other words, we can reliably generate a
1027 * latin square row by row, by at every stage writing down any
1028 * row at all which doesn't conflict with previous rows, and
1029 * the theorem guarantees that we will never have to backtrack.
1031 * To find a viable row at each stage, we can make use of the
1032 * support functions in maxflow.c.
1035 sq
= snewn(o
*o
, digit
);
1038 * In case this method of generation introduces a really subtle
1039 * top-to-bottom directional bias, we'll generate the rows in
1042 row
= snewn(o
, digit
);
1043 col
= snewn(o
, digit
);
1044 numinv
= snewn(o
, digit
);
1045 num
= snewn(o
, digit
);
1046 for (i
= 0; i
< o
; i
++)
1048 shuffle(row
, i
, sizeof(*row
), rs
);
1051 * Set up the infrastructure for the maxflow algorithm.
1053 scratchsize
= maxflow_scratch_size(o
* 2 + 2);
1054 scratch
= smalloc(scratchsize
);
1055 backedges
= snewn(o
*o
+ 2*o
, int);
1056 edges
= snewn((o
*o
+ 2*o
) * 2, int);
1057 capacity
= snewn(o
*o
+ 2*o
, int);
1058 flow
= snewn(o
*o
+ 2*o
, int);
1059 /* Set up the edge array, and the initial capacities. */
1061 for (i
= 0; i
< o
; i
++) {
1062 /* Each LHS vertex is connected to all RHS vertices. */
1063 for (j
= 0; j
< o
; j
++) {
1065 edges
[ne
*2+1] = j
+o
;
1066 /* capacity for this edge is set later on */
1070 for (i
= 0; i
< o
; i
++) {
1071 /* Each RHS vertex is connected to the distinguished sink vertex. */
1073 edges
[ne
*2+1] = o
*2+1;
1077 for (i
= 0; i
< o
; i
++) {
1078 /* And the distinguished source vertex connects to each LHS vertex. */
1084 assert(ne
== o
*o
+ 2*o
);
1085 /* Now set up backedges. */
1086 maxflow_setup_backedges(ne
, edges
, backedges
);
1089 * Now generate each row of the latin square.
1091 for (i
= 0; i
< o
; i
++) {
1093 * To prevent maxflow from behaving deterministically, we
1094 * separately permute the columns and the digits for the
1095 * purposes of the algorithm, differently for every row.
1097 for (j
= 0; j
< o
; j
++)
1098 col
[j
] = num
[j
] = j
;
1099 shuffle(col
, j
, sizeof(*col
), rs
);
1100 shuffle(num
, j
, sizeof(*num
), rs
);
1101 /* We need the num permutation in both forward and inverse forms. */
1102 for (j
= 0; j
< o
; j
++)
1106 * Set up the capacities for the maxflow run, by examining
1107 * the existing latin square.
1109 for (j
= 0; j
< o
*o
; j
++)
1111 for (j
= 0; j
< i
; j
++)
1112 for (k
= 0; k
< o
; k
++) {
1113 int n
= num
[sq
[row
[j
]*o
+ col
[k
]] - 1];
1114 capacity
[k
*o
+n
] = 0;
1120 j
= maxflow_with_scratch(scratch
, o
*2+2, 2*o
, 2*o
+1, ne
,
1121 edges
, backedges
, capacity
, flow
, NULL
);
1122 assert(j
== o
); /* by the above theorem, this must have succeeded */
1125 * And examine the flow array to pick out the new row of
1128 for (j
= 0; j
< o
; j
++) {
1129 for (k
= 0; k
< o
; k
++) {
1134 sq
[row
[i
]*o
+ col
[j
]] = numinv
[k
] + 1;
1139 * Done. Free our internal workspaces...
1152 * ... and return our completed latin square.
1157 /* --------------------------------------------------------
1161 typedef struct lcparams
{
1166 static int latin_check_cmp(void *v1
, void *v2
)
1168 lcparams
*lc1
= (lcparams
*)v1
;
1169 lcparams
*lc2
= (lcparams
*)v2
;
1171 if (lc1
->elt
< lc2
->elt
) return -1;
1172 if (lc1
->elt
> lc2
->elt
) return 1;
1176 #define ELT(sq,x,y) (sq[((y)*order)+(x)])
1178 /* returns non-zero if sq is not a latin square. */
1179 int latin_check(digit
*sq
, int order
)
1181 tree234
*dict
= newtree234(latin_check_cmp
);
1184 lcparams
*lcp
, lc
, *aret
;
1186 /* Use a tree234 as a simple hash table, go through the square
1187 * adding elements as we go or incrementing their counts. */
1188 for (c
= 0; c
< order
; c
++) {
1189 for (r
= 0; r
< order
; r
++) {
1190 lc
.elt
= ELT(sq
, c
, r
); lc
.count
= 0;
1191 lcp
= find234(dict
, &lc
, NULL
);
1193 lcp
= snew(lcparams
);
1194 lcp
->elt
= ELT(sq
, c
, r
);
1196 aret
= add234(dict
, lcp
);
1197 assert(aret
== lcp
);
1204 /* There should be precisely 'order' letters in the alphabet,
1205 * each occurring 'order' times (making the OxO tree) */
1206 if (count234(dict
) != order
) ret
= 1;
1208 for (c
= 0; (lcp
= index234(dict
, c
)) != NULL
; c
++) {
1209 if (lcp
->count
!= order
) ret
= 1;
1212 for (c
= 0; (lcp
= index234(dict
, c
)) != NULL
; c
++)
1220 /* --------------------------------------------------------
1221 * Testing (and printing).
1224 #ifdef STANDALONE_LATIN_TEST
1231 static void latin_print(digit
*sq
, int order
)
1235 for (y
= 0; y
< order
; y
++) {
1236 for (x
= 0; x
< order
; x
++) {
1237 printf("%2u ", ELT(sq
, x
, y
));
1244 static void gen(int order
, random_state
*rs
, int debug
)
1248 solver_show_working
= debug
;
1250 sq
= latin_generate(order
, rs
);
1251 latin_print(sq
, order
);
1252 if (latin_check(sq
, order
)) {
1253 fprintf(stderr
, "Square is not a latin square!");
1260 void test_soak(int order
, random_state
*rs
)
1264 time_t tt_start
, tt_now
, tt_last
;
1266 solver_show_working
= 0;
1267 tt_now
= tt_start
= time(NULL
);
1270 sq
= latin_generate(order
, rs
);
1274 tt_last
= time(NULL
);
1275 if (tt_last
> tt_now
) {
1277 printf("%d total, %3.1f/s\n", n
,
1278 (double)n
/ (double)(tt_now
- tt_start
));
1283 void usage_exit(const char *msg
)
1286 fprintf(stderr
, "%s: %s\n", quis
, msg
);
1287 fprintf(stderr
, "Usage: %s [--seed SEED] --soak <params> | [game_id [game_id ...]]\n", quis
);
1291 int main(int argc
, char *argv
[])
1295 time_t seed
= time(NULL
);
1298 while (--argc
> 0) {
1299 const char *p
= *++argv
;
1300 if (!strcmp(p
, "--soak"))
1302 else if (!strcmp(p
, "--seed")) {
1304 usage_exit("--seed needs an argument");
1305 seed
= (time_t)atoi(*++argv
);
1307 } else if (*p
== '-')
1308 usage_exit("unrecognised option");
1310 break; /* finished options */
1313 rs
= random_new((void*)&seed
, sizeof(time_t));
1316 if (argc
!= 1) usage_exit("only one argument for --soak");
1317 test_soak(atoi(*argv
), rs
);
1320 for (i
= 0; i
< argc
; i
++) {
1321 gen(atoi(*argv
++), rs
, 1);
1325 i
= random_upto(rs
, 20) + 1;
1336 /* vim: set shiftwidth=4 tabstop=8: */