9 #ifdef STANDALONE_LATIN_TEST
10 #define STANDALONE_SOLVER
15 /* --------------------------------------------------------
20 * Function called when we are certain that a particular square has
21 * a particular number in it. The y-coordinate passed in here is
24 void latin_solver_place(struct latin_solver *solver, int x, int y, int n)
32 * Rule out all other numbers in this square.
34 for (i = 1; i <= o; i++)
39 * Rule out this number in all other positions in the row.
41 for (i = 0; i < o; i++)
46 * Rule out this number in all other positions in the column.
48 for (i = 0; i < o; i++)
53 * Enter the number in the result grid.
55 solver->grid[YUNTRANS(y)*o+x] = n;
58 * Cross out this number from the list of numbers left to place
59 * in its row, its column and its block.
61 solver->row[y*o+n-1] = solver->col[x*o+n-1] = TRUE;
64 int latin_solver_elim(struct latin_solver *solver, int start, int step
65 #ifdef STANDALONE_SOLVER
74 * Count the number of set bits within this section of the
79 for (i = 0; i < o; i++)
80 if (solver->cube[start+i*step]) {
94 if (!solver->grid[YUNTRANS(y)*o+x]) {
95 #ifdef STANDALONE_SOLVER
96 if (solver_show_working) {
98 printf("%*s", solver_recurse_depth*4, "");
102 printf(":\n%*s placing %d at (%d,%d)\n",
103 solver_recurse_depth*4, "", n, x, YUNTRANS(y));
106 latin_solver_place(solver, x, y, n);
110 #ifdef STANDALONE_SOLVER
111 if (solver_show_working) {
113 printf("%*s", solver_recurse_depth*4, "");
117 printf(":\n%*s no possibilities available\n",
118 solver_recurse_depth*4, "");
127 struct latin_solver_scratch {
128 unsigned char *grid, *rowidx, *colidx, *set;
129 int *neighbours, *bfsqueue;
130 #ifdef STANDALONE_SOLVER
135 int latin_solver_set(struct latin_solver *solver,
136 struct latin_solver_scratch *scratch,
137 int start, int step1, int step2
138 #ifdef STANDALONE_SOLVER
145 unsigned char *grid = scratch->grid;
146 unsigned char *rowidx = scratch->rowidx;
147 unsigned char *colidx = scratch->colidx;
148 unsigned char *set = scratch->set;
151 * We are passed a o-by-o matrix of booleans. Our first job
152 * is to winnow it by finding any definite placements - i.e.
153 * any row with a solitary 1 - and discarding that row and the
154 * column containing the 1.
156 memset(rowidx, TRUE, o);
157 memset(colidx, TRUE, o);
158 for (i = 0; i < o; i++) {
159 int count = 0, first = -1;
160 for (j = 0; j < o; j++)
161 if (solver->cube[start+i*step1+j*step2])
164 if (count == 0) return -1;
166 rowidx[i] = colidx[first] = FALSE;
170 * Convert each of rowidx/colidx from a list of 0s and 1s to a
171 * list of the indices of the 1s.
173 for (i = j = 0; i < o; i++)
177 for (i = j = 0; i < o; i++)
183 * And create the smaller matrix.
185 for (i = 0; i < n; i++)
186 for (j = 0; j < n; j++)
187 grid[i*o+j] = solver->cube[start+rowidx[i]*step1+colidx[j]*step2];
190 * Having done that, we now have a matrix in which every row
191 * has at least two 1s in. Now we search to see if we can find
192 * a rectangle of zeroes (in the set-theoretic sense of
193 * `rectangle', i.e. a subset of rows crossed with a subset of
194 * columns) whose width and height add up to n.
201 * We have a candidate set. If its size is <=1 or >=n-1
202 * then we move on immediately.
204 if (count > 1 && count < n-1) {
206 * The number of rows we need is n-count. See if we can
207 * find that many rows which each have a zero in all
208 * the positions listed in `set'.
211 for (i = 0; i < n; i++) {
213 for (j = 0; j < n; j++)
214 if (set[j] && grid[i*o+j]) {
223 * We expect never to be able to get _more_ than
224 * n-count suitable rows: this would imply that (for
225 * example) there are four numbers which between them
226 * have at most three possible positions, and hence it
227 * indicates a faulty deduction before this point or
230 if (rows > n - count) {
231 #ifdef STANDALONE_SOLVER
232 if (solver_show_working) {
234 printf("%*s", solver_recurse_depth*4,
239 printf(":\n%*s contradiction reached\n",
240 solver_recurse_depth*4, "");
246 if (rows >= n - count) {
247 int progress = FALSE;
250 * We've got one! Now, for each row which _doesn't_
251 * satisfy the criterion, eliminate all its set
252 * bits in the positions _not_ listed in `set'.
253 * Return +1 (meaning progress has been made) if we
254 * successfully eliminated anything at all.
256 * This involves referring back through
257 * rowidx/colidx in order to work out which actual
258 * positions in the cube to meddle with.
260 for (i = 0; i < n; i++) {
262 for (j = 0; j < n; j++)
263 if (set[j] && grid[i*o+j]) {
268 for (j = 0; j < n; j++)
269 if (!set[j] && grid[i*o+j]) {
270 int fpos = (start+rowidx[i]*step1+
272 #ifdef STANDALONE_SOLVER
273 if (solver_show_working) {
278 printf("%*s", solver_recurse_depth*4,
291 printf("%*s ruling out %d at (%d,%d)\n",
292 solver_recurse_depth*4, "",
293 pn, px, YUNTRANS(py));
297 solver->cube[fpos] = FALSE;
309 * Binary increment: change the rightmost 0 to a 1, and
310 * change all 1s to the right of it to 0s.
313 while (i > 0 && set[i-1])
314 set[--i] = 0, count--;
316 set[--i] = 1, count++;
325 * Look for forcing chains. A forcing chain is a path of
326 * pairwise-exclusive squares (i.e. each pair of adjacent squares
327 * in the path are in the same row, column or block) with the
328 * following properties:
330 * (a) Each square on the path has precisely two possible numbers.
332 * (b) Each pair of squares which are adjacent on the path share
333 * at least one possible number in common.
335 * (c) Each square in the middle of the path shares _both_ of its
336 * numbers with at least one of its neighbours (not the same
337 * one with both neighbours).
339 * These together imply that at least one of the possible number
340 * choices at one end of the path forces _all_ the rest of the
341 * numbers along the path. In order to make real use of this, we
342 * need further properties:
344 * (c) Ruling out some number N from the square at one end
345 * of the path forces the square at the other end to
348 * (d) The two end squares are both in line with some third
351 * (e) That third square currently has N as a possibility.
353 * If we can find all of that lot, we can deduce that at least one
354 * of the two ends of the forcing chain has number N, and that
355 * therefore the mutually adjacent third square does not.
357 * To find forcing chains, we're going to start a bfs at each
358 * suitable square, once for each of its two possible numbers.
360 int latin_solver_forcing(struct latin_solver *solver,
361 struct latin_solver_scratch *scratch)
364 int *bfsqueue = scratch->bfsqueue;
365 #ifdef STANDALONE_SOLVER
366 int *bfsprev = scratch->bfsprev;
368 unsigned char *number = scratch->grid;
369 int *neighbours = scratch->neighbours;
372 for (y = 0; y < o; y++)
373 for (x = 0; x < o; x++) {
377 * If this square doesn't have exactly two candidate
378 * numbers, don't try it.
380 * In this loop we also sum the candidate numbers,
381 * which is a nasty hack to allow us to quickly find
382 * `the other one' (since we will shortly know there
385 for (count = t = 0, n = 1; n <= o; n++)
392 * Now attempt a bfs for each candidate.
394 for (n = 1; n <= o; n++)
396 int orign, currn, head, tail;
403 memset(number, o+1, o*o);
405 bfsqueue[tail++] = y*o+x;
406 #ifdef STANDALONE_SOLVER
409 number[y*o+x] = t - n;
411 while (head < tail) {
412 int xx, yy, nneighbours, xt, yt, i;
414 xx = bfsqueue[head++];
418 currn = number[yy*o+xx];
421 * Find neighbours of yy,xx.
424 for (yt = 0; yt < o; yt++)
425 neighbours[nneighbours++] = yt*o+xx;
426 for (xt = 0; xt < o; xt++)
427 neighbours[nneighbours++] = yy*o+xt;
430 * Try visiting each of those neighbours.
432 for (i = 0; i < nneighbours; i++) {
435 xt = neighbours[i] % o;
436 yt = neighbours[i] / o;
439 * We need this square to not be
440 * already visited, and to include
441 * currn as a possible number.
443 if (number[yt*o+xt] <= o)
445 if (!cube(xt, yt, currn))
449 * Don't visit _this_ square a second
452 if (xt == xx && yt == yy)
456 * To continue with the bfs, we need
457 * this square to have exactly two
460 for (cc = tt = 0, nn = 1; nn <= o; nn++)
461 if (cube(xt, yt, nn))
464 bfsqueue[tail++] = yt*o+xt;
465 #ifdef STANDALONE_SOLVER
466 bfsprev[yt*o+xt] = yy*o+xx;
468 number[yt*o+xt] = tt - currn;
472 * One other possibility is that this
473 * might be the square in which we can
474 * make a real deduction: if it's
475 * adjacent to x,y, and currn is equal
476 * to the original number we ruled out.
478 if (currn == orign &&
479 (xt == x || yt == y)) {
480 #ifdef STANDALONE_SOLVER
481 if (solver_show_working) {
484 printf("%*sforcing chain, %d at ends of ",
485 solver_recurse_depth*4, "", orign);
489 printf("%s(%d,%d)", sep, xl,
491 xl = bfsprev[yl*o+xl];
498 printf("\n%*s ruling out %d at (%d,%d)\n",
499 solver_recurse_depth*4, "",
500 orign, xt, YUNTRANS(yt));
503 cube(xt, yt, orign) = FALSE;
514 struct latin_solver_scratch *latin_solver_new_scratch(struct latin_solver *solver)
516 struct latin_solver_scratch *scratch = snew(struct latin_solver_scratch);
518 scratch->grid = snewn(o*o, unsigned char);
519 scratch->rowidx = snewn(o, unsigned char);
520 scratch->colidx = snewn(o, unsigned char);
521 scratch->set = snewn(o, unsigned char);
522 scratch->neighbours = snewn(3*o, int);
523 scratch->bfsqueue = snewn(o*o, int);
524 #ifdef STANDALONE_SOLVER
525 scratch->bfsprev = snewn(o*o, int);
530 void latin_solver_free_scratch(struct latin_solver_scratch *scratch)
532 #ifdef STANDALONE_SOLVER
533 sfree(scratch->bfsprev);
535 sfree(scratch->bfsqueue);
536 sfree(scratch->neighbours);
538 sfree(scratch->colidx);
539 sfree(scratch->rowidx);
540 sfree(scratch->grid);
544 void latin_solver_alloc(struct latin_solver *solver, digit *grid, int o)
549 solver->cube = snewn(o*o*o, unsigned char);
550 solver->grid = grid; /* write straight back to the input */
551 memset(solver->cube, TRUE, o*o*o);
553 solver->row = snewn(o*o, unsigned char);
554 solver->col = snewn(o*o, unsigned char);
555 memset(solver->row, FALSE, o*o);
556 memset(solver->col, FALSE, o*o);
558 for (x = 0; x < o; x++)
559 for (y = 0; y < o; y++)
561 latin_solver_place(solver, x, YTRANS(y), grid[y*o+x]);
564 void latin_solver_free(struct latin_solver *solver)
571 int latin_solver_diff_simple(struct latin_solver *solver)
573 int x, y, n, ret, o = solver->o;
575 * Row-wise positional elimination.
577 for (y = 0; y < o; y++)
578 for (n = 1; n <= o; n++)
579 if (!solver->row[y*o+n-1]) {
580 ret = latin_solver_elim(solver, cubepos(0,y,n), o*o
581 #ifdef STANDALONE_SOLVER
582 , "positional elimination,"
583 " %d in row %d", n, YUNTRANS(y)
586 if (ret != 0) return ret;
589 * Column-wise positional elimination.
591 for (x = 0; x < o; x++)
592 for (n = 1; n <= o; n++)
593 if (!solver->col[x*o+n-1]) {
594 ret = latin_solver_elim(solver, cubepos(x,0,n), o
595 #ifdef STANDALONE_SOLVER
596 , "positional elimination,"
597 " %d in column %d", n, x
600 if (ret != 0) return ret;
604 * Numeric elimination.
606 for (x = 0; x < o; x++)
607 for (y = 0; y < o; y++)
608 if (!solver->grid[YUNTRANS(y)*o+x]) {
609 ret = latin_solver_elim(solver, cubepos(x,y,1), 1
610 #ifdef STANDALONE_SOLVER
611 , "numeric elimination at (%d,%d)", x,
615 if (ret != 0) return ret;
620 int latin_solver_diff_set(struct latin_solver *solver,
621 struct latin_solver_scratch *scratch,
624 int x, y, n, ret, o = solver->o;
626 * Row-wise set elimination.
628 for (y = 0; y < o; y++) {
629 ret = latin_solver_set(solver, scratch, cubepos(0,y,1), o*o, 1
630 #ifdef STANDALONE_SOLVER
631 , "set elimination, row %d", YUNTRANS(y)
634 if (ret > 0) *extreme = 0;
635 if (ret != 0) return ret;
639 * Column-wise set elimination.
641 for (x = 0; x < o; x++) {
642 ret = latin_solver_set(solver, scratch, cubepos(x,0,1), o, 1
643 #ifdef STANDALONE_SOLVER
644 , "set elimination, column %d", x
647 if (ret > 0) *extreme = 0;
648 if (ret != 0) return ret;
652 * Row-vs-column set elimination on a single number.
654 for (n = 1; n <= o; n++) {
655 ret = latin_solver_set(solver, scratch, cubepos(0,0,n), o*o, o
656 #ifdef STANDALONE_SOLVER
657 , "positional set elimination, number %d", n
660 if (ret > 0) *extreme = 1;
661 if (ret != 0) return ret;
666 /* This uses our own diff_* internally, but doesn't require callers
667 * to; this is so it can be used by games that want to rewrite
668 * the solver so as to use a different set of difficulties.
671 * 0 for 'didn't do anything' implying it was already solved.
672 * -1 for 'impossible' (no solution)
673 * 1 for 'single solution'
674 * >1 for 'multiple solutions' (you don't get to know how many, and
675 * the first such solution found will be set.
677 * and this function may well assert if given an impossible board.
679 int latin_solver_recurse(struct latin_solver *solver, int recdiff,
680 latin_solver_callback cb, void *ctx)
683 int o = solver->o, x, y, n;
688 for (y = 0; y < o; y++)
689 for (x = 0; x < o; x++)
690 if (!solver->grid[y*o+x]) {
694 * An unfilled square. Count the number of
695 * possible digits in it.
698 for (n = 1; n <= o; n++)
699 if (cube(x,YTRANS(y),n))
703 * We should have found any impossibilities
704 * already, so this can safely be an assert.
708 if (count < bestcount) {
715 /* we were complete already. */
719 digit *list, *ingrid, *outgrid;
720 int diff = diff_impossible; /* no solution found yet */
728 list = snewn(o, digit);
729 ingrid = snewn(o*o, digit);
730 outgrid = snewn(o*o, digit);
731 memcpy(ingrid, solver->grid, o*o);
733 /* Make a list of the possible digits. */
734 for (j = 0, n = 1; n <= o; n++)
735 if (cube(x,YTRANS(y),n))
738 #ifdef STANDALONE_SOLVER
739 if (solver_show_working) {
741 printf("%*srecursing on (%d,%d) [",
742 solver_recurse_depth*4, "", x, y);
743 for (i = 0; i < j; i++) {
744 printf("%s%d", sep, list[i]);
752 * And step along the list, recursing back into the
753 * main solver at every stage.
755 for (i = 0; i < j; i++) {
758 memcpy(outgrid, ingrid, o*o);
759 outgrid[y*o+x] = list[i];
761 #ifdef STANDALONE_SOLVER
762 if (solver_show_working)
763 printf("%*sguessing %d at (%d,%d)\n",
764 solver_recurse_depth*4, "", list[i], x, y);
765 solver_recurse_depth++;
768 ret = cb(outgrid, o, recdiff, ctx);
770 #ifdef STANDALONE_SOLVER
771 solver_recurse_depth--;
772 if (solver_show_working) {
773 printf("%*sretracting %d at (%d,%d)\n",
774 solver_recurse_depth*4, "", list[i], x, y);
777 /* we recurse as deep as we can, so we should never find
778 * find ourselves giving up on a puzzle without declaring it
780 assert(ret != diff_unfinished);
783 * If we have our first solution, copy it into the
784 * grid we will return.
786 if (diff == diff_impossible && ret != diff_impossible)
787 memcpy(solver->grid, outgrid, o*o);
789 if (ret == diff_ambiguous)
790 diff = diff_ambiguous;
791 else if (ret == diff_impossible)
792 /* do not change our return value */;
794 /* the recursion turned up exactly one solution */
795 if (diff == diff_impossible)
798 diff = diff_ambiguous;
802 * As soon as we've found more than one solution,
803 * give up immediately.
805 if (diff == diff_ambiguous)
813 if (diff == diff_impossible)
815 else if (diff == diff_ambiguous)
818 assert(diff == recdiff);
824 enum { diff_simple = 1, diff_set, diff_extreme, diff_recursive };
826 static int latin_solver_sub(struct latin_solver *solver, int maxdiff, void *ctx)
828 struct latin_solver_scratch *scratch = latin_solver_new_scratch(solver);
829 int ret, diff = diff_simple, extreme;
831 assert(maxdiff <= diff_recursive);
833 * Now loop over the grid repeatedly trying all permitted modes
834 * of reasoning. The loop terminates if we complete an
835 * iteration without making any progress; we then return
836 * failure or success depending on whether the grid is full or
841 * I'd like to write `continue;' inside each of the
842 * following loops, so that the solver returns here after
843 * making some progress. However, I can't specify that I
844 * want to continue an outer loop rather than the innermost
845 * one, so I'm apologetically resorting to a goto.
848 latin_solver_debug(solver->cube, solver->o);
850 ret = latin_solver_diff_simple(solver);
852 diff = diff_impossible;
854 } else if (ret > 0) {
855 diff = max(diff, diff_simple);
859 if (maxdiff <= diff_simple)
862 ret = latin_solver_diff_set(solver, scratch, &extreme);
864 diff = diff_impossible;
866 } else if (ret > 0) {
867 diff = max(diff, extreme ? diff_extreme : diff_set);
871 if (maxdiff <= diff_set)
877 if (latin_solver_forcing(solver, scratch)) {
878 diff = max(diff, diff_extreme);
883 * If we reach here, we have made no deductions in this
884 * iteration, so the algorithm terminates.
890 * Last chance: if we haven't fully solved the puzzle yet, try
891 * recursing based on guesses for a particular square. We pick
892 * one of the most constrained empty squares we can find, which
893 * has the effect of pruning the search tree as much as
896 if (maxdiff == diff_recursive) {
897 int nsol = latin_solver_recurse(solver, diff_recursive, latin_solver, ctx);
898 if (nsol < 0) diff = diff_impossible;
899 else if (nsol == 1) diff = diff_recursive;
900 else if (nsol > 1) diff = diff_ambiguous;
901 /* if nsol == 0 then we were complete anyway
902 * (and thus don't need to change diff) */
905 * We're forbidden to use recursion, so we just see whether
906 * our grid is fully solved, and return diff_unfinished
909 int x, y, o = solver->o;
911 for (y = 0; y < o; y++)
912 for (x = 0; x < o; x++)
913 if (!solver->grid[y*o+x])
914 diff = diff_unfinished;
919 #ifdef STANDALONE_SOLVER
920 if (solver_show_working)
921 printf("%*s%s found\n",
922 solver_recurse_depth*4, "",
923 diff == diff_impossible ? "no solution (impossible)" :
924 diff == diff_unfinished ? "no solution (unfinished)" :
925 diff == diff_ambiguous ? "multiple solutions" :
929 latin_solver_free_scratch(scratch);
934 int latin_solver(digit *grid, int o, int maxdiff, void *ctx)
936 struct latin_solver solver;
939 latin_solver_alloc(&solver, grid, o);
940 diff = latin_solver_sub(&solver, maxdiff, ctx);
941 latin_solver_free(&solver);
945 void latin_solver_debug(unsigned char *cube, int o)
947 #ifdef STANDALONE_SOLVER
948 if (solver_show_working) {
949 struct latin_solver ls, *solver = &ls;
953 ls.cube = cube; ls.o = o; /* for cube() to work */
955 dbg = snewn(3*o*o*o, unsigned char);
956 for (y = 0; y < o; y++) {
957 for (x = 0; x < o; x++) {
958 for (i = 1; i <= o; i++) {
977 void latin_debug(digit *sq, int o)
979 #ifdef STANDALONE_SOLVER
980 if (solver_show_working) {
983 for (y = 0; y < o; y++) {
984 for (x = 0; x < o; x++) {
985 printf("%2d ", sq[y*o+x]);
994 /* --------------------------------------------------------
998 digit *latin_generate(int o, random_state *rs)
1001 int *edges, *backedges, *capacity, *flow;
1003 int ne, scratchsize;
1005 digit *row, *col, *numinv, *num;
1008 * To efficiently generate a latin square in such a way that
1009 * all possible squares are possible outputs from the function,
1010 * we make use of a theorem which states that any r x n latin
1011 * rectangle, with r < n, can be extended into an (r+1) x n
1012 * latin rectangle. In other words, we can reliably generate a
1013 * latin square row by row, by at every stage writing down any
1014 * row at all which doesn't conflict with previous rows, and
1015 * the theorem guarantees that we will never have to backtrack.
1017 * To find a viable row at each stage, we can make use of the
1018 * support functions in maxflow.c.
1021 sq = snewn(o*o, digit);
1024 * In case this method of generation introduces a really subtle
1025 * top-to-bottom directional bias, we'll generate the rows in
1028 row = snewn(o, digit);
1029 col = snewn(o, digit);
1030 numinv = snewn(o, digit);
1031 num = snewn(o, digit);
1032 for (i = 0; i < o; i++)
1034 shuffle(row, i, sizeof(*row), rs);
1037 * Set up the infrastructure for the maxflow algorithm.
1039 scratchsize = maxflow_scratch_size(o * 2 + 2);
1040 scratch = smalloc(scratchsize);
1041 backedges = snewn(o*o + 2*o, int);
1042 edges = snewn((o*o + 2*o) * 2, int);
1043 capacity = snewn(o*o + 2*o, int);
1044 flow = snewn(o*o + 2*o, int);
1045 /* Set up the edge array, and the initial capacities. */
1047 for (i = 0; i < o; i++) {
1048 /* Each LHS vertex is connected to all RHS vertices. */
1049 for (j = 0; j < o; j++) {
1051 edges[ne*2+1] = j+o;
1052 /* capacity for this edge is set later on */
1056 for (i = 0; i < o; i++) {
1057 /* Each RHS vertex is connected to the distinguished sink vertex. */
1059 edges[ne*2+1] = o*2+1;
1063 for (i = 0; i < o; i++) {
1064 /* And the distinguished source vertex connects to each LHS vertex. */
1070 assert(ne == o*o + 2*o);
1071 /* Now set up backedges. */
1072 maxflow_setup_backedges(ne, edges, backedges);
1075 * Now generate each row of the latin square.
1077 for (i = 0; i < o; i++) {
1079 * To prevent maxflow from behaving deterministically, we
1080 * separately permute the columns and the digits for the
1081 * purposes of the algorithm, differently for every row.
1083 for (j = 0; j < o; j++)
1084 col[j] = num[j] = j;
1085 shuffle(col, j, sizeof(*col), rs);
1086 /* We need the num permutation in both forward and inverse forms. */
1087 for (j = 0; j < o; j++)
1091 * Set up the capacities for the maxflow run, by examining
1092 * the existing latin square.
1094 for (j = 0; j < o*o; j++)
1096 for (j = 0; j < i; j++)
1097 for (k = 0; k < o; k++) {
1098 int n = num[sq[row[j]*o + col[k]] - 1];
1099 capacity[k*o+n] = 0;
1105 j = maxflow_with_scratch(scratch, o*2+2, 2*o, 2*o+1, ne,
1106 edges, backedges, capacity, flow, NULL);
1107 assert(j == o); /* by the above theorem, this must have succeeded */
1110 * And examine the flow array to pick out the new row of
1113 for (j = 0; j < o; j++) {
1114 for (k = 0; k < o; k++) {
1119 sq[row[i]*o + col[j]] = numinv[k] + 1;
1124 * Done. Free our internal workspaces...
1137 * ... and return our completed latin square.
1142 /* --------------------------------------------------------
1146 typedef struct lcparams {
1151 static int latin_check_cmp(void *v1, void *v2)
1153 lcparams *lc1 = (lcparams *)v1;
1154 lcparams *lc2 = (lcparams *)v2;
1156 if (lc1->elt < lc2->elt) return -1;
1157 if (lc1->elt > lc2->elt) return 1;
1161 #define ELT(sq,x,y) (sq[((y)*order)+(x)])
1163 /* returns non-zero if sq is not a latin square. */
1164 int latin_check(digit *sq, int order)
1166 tree234 *dict = newtree234(latin_check_cmp);
1171 /* Use a tree234 as a simple hash table, go through the square
1172 * adding elements as we go or incrementing their counts. */
1173 for (c = 0; c < order; c++) {
1174 for (r = 0; r < order; r++) {
1175 lc.elt = ELT(sq, c, r); lc.count = 0;
1176 lcp = find234(dict, &lc, NULL);
1178 lcp = snew(lcparams);
1179 lcp->elt = ELT(sq, c, r);
1181 assert(add234(dict, lcp) == lcp);
1188 /* There should be precisely 'order' letters in the alphabet,
1189 * each occurring 'order' times (making the OxO tree) */
1190 if (count234(dict) != order) ret = 1;
1192 for (c = 0; (lcp = index234(dict, c)) != NULL; c++) {
1193 if (lcp->count != order) ret = 1;
1196 for (c = 0; (lcp = index234(dict, c)) != NULL; c++)
1204 /* --------------------------------------------------------
1205 * Testing (and printing).
1208 #ifdef STANDALONE_LATIN_TEST
1215 static void latin_print(digit *sq, int order)
1219 for (y = 0; y < order; y++) {
1220 for (x = 0; x < order; x++) {
1221 printf("%2u ", ELT(sq, x, y));
1228 static void gen(int order, random_state *rs, int debug)
1232 solver_show_working = debug;
1234 sq = latin_generate(order, rs);
1235 latin_print(sq, order);
1236 if (latin_check(sq, order)) {
1237 fprintf(stderr, "Square is not a latin square!");
1244 void test_soak(int order, random_state *rs)
1248 time_t tt_start, tt_now, tt_last;
1250 solver_show_working = 0;
1251 tt_now = tt_start = time(NULL);
1254 sq = latin_generate(order, rs);
1258 tt_last = time(NULL);
1259 if (tt_last > tt_now) {
1261 printf("%d total, %3.1f/s\n", n,
1262 (double)n / (double)(tt_now - tt_start));
1267 void usage_exit(const char *msg)
1270 fprintf(stderr, "%s: %s\n", quis, msg);
1271 fprintf(stderr, "Usage: %s [--seed SEED] --soak <params> | [game_id [game_id ...]]\n", quis);
1275 int main(int argc, char *argv[])
1279 time_t seed = time(NULL);
1282 while (--argc > 0) {
1283 const char *p = *++argv;
1284 if (!strcmp(p, "--soak"))
1286 else if (!strcmp(p, "--seed")) {
1288 usage_exit("--seed needs an argument");
1289 seed = (time_t)atoi(*++argv);
1291 } else if (*p == '-')
1292 usage_exit("unrecognised option");
1294 break; /* finished options */
1297 rs = random_new((void*)&seed, sizeof(time_t));
1300 if (argc != 1) usage_exit("only one argument for --soak");
1301 test_soak(atoi(*argv), rs);
1304 for (i = 0; i < argc; i++) {
1305 gen(atoi(*argv++), rs, 1);
1309 i = random_upto(rs, 20) + 1;
1320 /* vim: set shiftwidth=4 tabstop=8: */