141 #include "allheaders.h" 148 l_int32 quads, l_int32 *psame);
152 static const char valid_solution[] =
"3 8 7 2 6 4 1 9 5 " 160 "6 5 8 4 2 3 9 7 1 ";
185 l_int32 i, j, nlines, val, index, error;
188 SARRAY *saline, *sa1, *sa2;
190 PROCNAME(
"sudokuReadFile");
193 return (l_int32 *)ERROR_PTR(
"filename not defined", procName, NULL);
200 for (i = 0; i < nlines; i++) {
210 L_ERROR(
"file has %d lines\n", procName, nlines);
211 return (l_int32 *)ERROR_PTR(
"invalid file", procName, NULL);
217 array = (l_int32 *)LEPT_CALLOC(81,
sizeof(l_int32));
218 for (i = 0, index = 0; i < 9; i++) {
226 for (j = 0; j < 9; j++) {
228 if (sscanf(strj,
"%d", &val) != 1)
231 array[index++] = val;
240 return (l_int32 *)ERROR_PTR(
"invalid data", procName, NULL);
265 PROCNAME(
"sudokuReadString");
268 return (l_int32 *)ERROR_PTR(
"str not defined", procName, NULL);
271 array = (l_int32 *)LEPT_CALLOC(81,
sizeof(l_int32));
272 for (i = 0; i < 81; i++) {
273 if (sscanf(str + 2 * i,
"%d ", &array[i]) != 1) {
275 return (l_int32 *)ERROR_PTR(
"invalid format", procName, NULL);
303 l_int32 i, val, locs_index;
306 PROCNAME(
"sudokuCreate");
309 return (
L_SUDOKU *)ERROR_PTR(
"array not defined", procName, NULL);
313 sud->
locs = (l_int32 *)LEPT_CALLOC(81,
sizeof(l_int32));
314 sud->
init = (l_int32 *)LEPT_CALLOC(81,
sizeof(l_int32));
315 sud->
state = (l_int32 *)LEPT_CALLOC(81,
sizeof(l_int32));
316 for (i = 0; i < 81; i++) {
321 sud->
locs[locs_index++] = i;
323 sud->
num = locs_index;
341 PROCNAME(
"sudokuDestroy");
344 L_WARNING(
"ptr address is NULL\n", procName);
347 if ((sud = *psud) == NULL)
350 LEPT_FREE(sud->
locs);
351 LEPT_FREE(sud->
init);
352 LEPT_FREE(sud->
state);
373 PROCNAME(
"sudokuSolve");
376 return ERROR_INT(
"sud not defined", procName, 0);
379 return ERROR_INT(
"initial state not valid", procName, 0);
389 fprintf(stderr,
"Failure after %d guesses\n", sud->
nguess);
393 fprintf(stderr,
"Solved after %d guesses\n", sud->
nguess);
416 PROCNAME(
"sudokuValidState");
419 return ERROR_INT(
"state not defined", procName, 0);
421 for (i = 0; i < 81; i++) {
451 l_int32 index, val, valid;
452 l_int32 *locs, *state;
494 l_int32 i, j, val, row, rowstart, rowend, col;
495 l_int32 blockrow, blockcol, blockstart, rowindex, locindex;
497 if ((val = state[index]) == 0)
503 for (i = rowstart; i < index; i++) {
507 rowend = rowstart + 9;
508 for (i = index + 1; i < rowend; i++) {
515 for (j = col; j < index; j += 9) {
519 for (j = index + 9; j < 81; j += 9) {
525 blockrow = 3 * (row / 3);
526 blockcol = 3 * (col / 3);
527 blockstart = 9 * blockrow + blockcol;
528 for (i = 0; i < 3; i++) {
529 rowindex = blockstart + 9 * i;
530 for (j = 0; j < 3; j++) {
531 locindex = rowindex + j;
532 if (index == locindex)
continue;
533 if (state[locindex] == val)
565 l_int32 same1, same2, same3;
566 l_int32 *array1, *array2, *array3;
569 PROCNAME(
"sudokuTestUniqueness");
572 return ERROR_INT(
"&unique not defined", procName, 1);
575 return ERROR_INT(
"array not defined", procName, 1);
592 *punique = (same1 && same2 && same3);
631 PROCNAME(
"sudokuCompareState");
634 return ERROR_INT(
"&same not defined", procName, 1);
637 return ERROR_INT(
"sud1 not defined", procName, 1);
639 return ERROR_INT(
"sud1 not defined", procName, 1);
640 if (quads < 1 || quads > 3)
641 return ERROR_INT(
"valid quads in {1,2,3}", procName, 1);
645 return ERROR_INT(
"array not made", procName, 1);
646 for (i = 0; i < 81; i++) {
647 if (array[i] != sud2->
state[i]) {
669 l_int32 i, j, sindex, dindex;
672 PROCNAME(
"sudokuRotateArray");
675 return (l_int32 *)ERROR_PTR(
"array not defined", procName, NULL);
676 if (quads < 1 || quads > 3)
677 return (l_int32 *)ERROR_PTR(
"valid quads in {1,2,3}", procName, NULL);
679 rarray = (l_int32 *)LEPT_CALLOC(81,
sizeof(l_int32));
681 for (j = 0, dindex = 0; j < 9; j++) {
682 for (i = 8; i >= 0; i--) {
684 rarray[dindex++] = array[sindex];
687 }
else if (quads == 2) {
688 for (i = 8, dindex = 0; i >= 0; i--) {
689 for (j = 8; j >= 0; j--) {
691 rarray[dindex++] = array[sindex];
695 for (j = 8, dindex = 0; j >= 0; j--) {
696 for (i = 0; i < 9; i++) {
698 rarray[dindex++] = array[sindex];
736 l_int32 index, sector, nzeros, removefirst, tries, val, oldval, unique;
739 PROCNAME(
"sudokuGenerate");
742 return (
L_SUDOKU *)ERROR_PTR(
"array not defined", procName, NULL);
744 return (
L_SUDOKU *)ERROR_PTR(
"minelems must be < 81", procName, NULL);
753 removefirst = L_MIN(30, 81 - minelems);
754 while (nzeros < removefirst) {
756 index = 27 * (sector / 3) + 3 * (sector % 3) +
757 9 * (val / 3) + (val % 3);
758 if (array[index] == 0)
continue;
768 L_ERROR(
"invalid initial solution\n", procName);
774 L_ERROR(
"non-unique result with 30 zeroes\n", procName);
782 if (tries > maxtries)
break;
783 if (81 - nzeros <= minelems)
break;
786 fprintf(stderr,
"Trying %d zeros\n", nzeros);
793 index = 27 * (sector / 3) + 3 * (sector % 3) +
794 9 * (val / 3) + (val % 3);
797 if (array[index] == 0)
continue;
800 oldval = array[index];
806 if (testsud->
failure == TRUE) {
808 array[index] = oldval;
817 array[index] = oldval;
821 fprintf(stderr,
"Have %d zeros\n", nzeros);
825 fprintf(stderr,
"Final: nelems = %d\n", 81 - nzeros);
860 PROCNAME(
"sudokuOutput");
863 return ERROR_INT(
"sud not defined", procName, 1);
864 if (arraytype == L_SUDOKU_INIT)
866 else if (arraytype == L_SUDOKU_STATE)
869 return ERROR_INT(
"invalid arraytype", procName, 1);
871 for (i = 0; i < 9; i++) {
872 for (j = 0; j < 9; j++)
873 fprintf(stderr,
"%d ", array[9 * i + j]);
874 fprintf(stderr,
"\n");
static l_int32 sudokuCompareState(L_SUDOKU *sud1, L_SUDOKU *sud2, l_int32 quads, l_int32 *psame)
sudokuCompareState()
l_ok genRandomIntegerInRange(l_int32 range, l_int32 seed, l_int32 *pval)
genRandomIntegerInRange()
static l_int32 sudokuNewGuess(L_SUDOKU *sud)
sudokuNewGuess()
SARRAY * sarrayCreate(l_int32 n)
sarrayCreate()
l_uint8 * l_binaryRead(const char *filename, size_t *pnbytes)
l_binaryRead()
L_SUDOKU * sudokuGenerate(l_int32 *array, l_int32 seed, l_int32 minelems, l_int32 maxtries)
sudokuGenerate()
l_int32 sudokuSolve(L_SUDOKU *sud)
sudokuSolve()
l_ok sarrayAddString(SARRAY *sa, const char *string, l_int32 copyflag)
sarrayAddString()
char * sarrayGetString(SARRAY *sa, l_int32 index, l_int32 copyflag)
sarrayGetString()
l_ok sudokuTestUniqueness(l_int32 *array, l_int32 *punique)
sudokuTestUniqueness()
SARRAY * sarrayCreateLinesFromString(const char *string, l_int32 blankflag)
sarrayCreateLinesFromString()
static l_int32 sudokuValidState(l_int32 *state)
sudokuValidState()
static l_int32 * sudokuRotateArray(l_int32 *array, l_int32 quads)
sudokuRotateArray()
l_int32 * sudokuReadFile(const char *filename)
sudokuReadFile()
l_int32 sudokuOutput(L_SUDOKU *sud, l_int32 arraytype)
sudokuOutput()
l_int32 sarrayGetCount(SARRAY *sa)
sarrayGetCount()
static l_int32 sudokuTestState(l_int32 *state, l_int32 index)
sudokuTestState()
l_int32 * sudokuReadString(const char *str)
sudokuReadString()
void sudokuDestroy(L_SUDOKU **psud)
sudokuDestroy()
L_SUDOKU * sudokuCreate(l_int32 *array)
sudokuCreate()
SARRAY * sarrayCreateWordsFromString(const char *string)
sarrayCreateWordsFromString()
void sarrayDestroy(SARRAY **psa)
sarrayDestroy()