Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
        }
    }
}