int solve_sudoku(int sudoku[9][9], const int guess_in_progress) { int i, j, guess, solution[9][9], temp_sudoku[9][9]; int success_status = 0; copy_sudoku(solution, sudoku); do { copy_sudoku(temp_sudoku, solution); for(i = 0; i < 9; ++i) { for(j = 0; j < 9; ++j) { if(solution[i][j] == 0) { solution[i][j] = solve_at_xy(solution, i, j); } } } } while (match_sudoku(solution, temp_sudoku) != 0); for(i = 0; i < 9; ++i) { for(j = 0; j < 9; ++j) { if(solution[i][j] == 0) { if(guess_in_progress == TRUE) { return ERROR; } success_status = 1; for(guess = 1; guess <= 9; ++guess) { if (check_conflict(solution, guess, i, j)) { continue; } copy_sudoku(temp_sudoku, solution); temp_sudoku[i][j] = guess; if (solve_sudoku(temp_sudoku, TRUE) != 0) { continue; } copy_sudoku(solution, temp_sudoku); success_status = 0; } } } } copy_sudoku(sudoku, solution); return success_status; }
void solveSudokuRec(int sudoku[SUDOKU_SIZE][SUDOKU_SIZE], char *hasResult) { int cellToSolve = countCellToSolve(sudoku); while (cellToSolve > 0) { // Create the array which will contain solutions int solutions[SUDOKU_SIZE][SUDOKU_SIZE]; int i; for (i = 0; i < SUDOKU_SIZE; i++) { initArray(solutions[i], SUDOKU_SIZE, 0); } // Search for solutions for this sudoku int count = searchSolutions(sudoku, solutions); // Put solutions in the sudoku int j; for (i = 0; i < SUDOKU_SIZE; i++) { for (j = 0; j < SUDOKU_SIZE; j++) { if (solutions[i][j] != 0 && isPowerOfTwo(solutions[i][j])) sudoku[i][j] = own_log2(solutions[i][j]); } } // Check if we have solved something int cellToSolveBefore = cellToSolve; cellToSolve = countCellToSolve(sudoku); if (cellToSolve == cellToSolveBefore && count > 0) { // If sudoku is not simple, create branch on each solution // If one branch has successful solution, return it, unless set a dead flag ! char goOut = 0; for (i = 0; i < SUDOKU_SIZE && !goOut; i++) { for (j = 0; j < SUDOKU_SIZE && !goOut; j++) { if (solutions[i][j] != 0) { int k; for (k = 1; k < 10 && !goOut; k++) { if (solutions[i][j] & (1 << k)) { #if SUDOKU_DEBUG printf("%d est une solution en %d,%d\n", k, i, j); #endif int sudokuChild[SUDOKU_SIZE][SUDOKU_SIZE]; copy_sudoku(sudoku, sudokuChild); sudokuChild[i][j] = k; char value = 0; solveSudokuRec(sudokuChild, &value); if (value == 1 && sudokuValide(sudokuChild)) { copy_sudoku(sudokuChild, sudoku); goOut = 1; } else { #if SUDOKU_DEBUG printf("Impossible de le faire !\n"); #endif } } } } } } #if SUDOKU_DEBUG printf("Sudoku is not simple !\n"); #endif break; } else if (count == 0) { break; } } if (hasResult != NULL && sudokuValide(sudoku)) *hasResult = 1; }
int solve_sudoku(char** sudoku) { // create a copy of the original sudoku - replace 'x' with '0' char** copy = allocate_sudoku(); copy_sudoku(sudoku, copy); for (int i = 0; i < 9; ++i) for (int j = 0; j < 9; ++j) if (copy[i][j] == 'x') copy[i][j] = '0'; unsigned int nx = 0; unsigned int ny = 0; unsigned int state = sudoku[nx][ny] == EMPTY_SQUARE ? STATE_SOLVE : STATE_STEP_FORWARD; while (1) { switch (state) { case STATE_SOLVE: if (copy[nx][ny] == '9') { // reset current square and go back copy[nx][ny] = '0'; state = STATE_STEP_BACKWARD; } else { // assign a value and check if there is a conflict ++copy[nx][ny]; if (sudoku_correct(copy, nx, ny)) { state = STATE_STEP_FORWARD; } } break; case STATE_STEP_FORWARD: if (EOS(nx, ny)) { // the end of the sudoku was reached without a conflict state = STATE_SOLVED; } else { // go forward until a non-empty square was reached INC_COORD(nx, ny) if (sudoku[nx][ny] == EMPTY_SQUARE) state = STATE_SOLVE; } break; case STATE_STEP_BACKWARD: if (BOS(nx, ny)) { // the beginning of the Sudoku was reached therefore it is irresolvable state = STATE_IRRESOLVABLE; } else { // go backward until a non-empty square was reached DEC_COORD(nx, ny) if (sudoku[nx][ny] == EMPTY_SQUARE) state = STATE_SOLVE; } break; case STATE_SOLVED: copy_sudoku(copy, sudoku); unallocate_sudoku(copy); return 0; case STATE_IRRESOLVABLE: copy_sudoku(copy, sudoku); unallocate_sudoku(copy); return 1; } } }