0

I did the same question a while ago, but It got closed. I'll try to express myself better this time.

I want to make an algorithm that can solve a sudoku puzzle, looks like It is working, but in the backtracking part(where I need to go back to a previous recursion to test a different value), It doesn't, showing a "segment fault" error.

Also, I use "0" as a blank space, so that's why "if (!board[i][j]) //do something"

// Solves the game
vector<vector<int>> sudokuSolver(vector<vector<int>> board) {
    if (isFull(board)) {
        return board;
    }
    bool found = false;
    int line = 0;
    int col = 0;
    for (int i = 0; i <= 8; i++) {
        for (int j = 0; j <= 8; j++) {
            if (!board[i][j]) {
                line = i;
                col = j;
                found = true;
                break;
            }
        }
        if (found) break;
    }
    vector<int> possibleNumbers = possibilities(board, line, col);
    cout << '\n';
    printBoard(board);
    cout << '\n';
    cout << line << ' ' << col << '\n';
    cout << '\n';
    printVector(possibleNumbers);
    int size = possibleNumbers.size();
    for (int k = 0; k < size; k++) {
        board[line][col] = possibleNumbers[k];
        cout << k << '\n';
        sudokuSolver(board);
        // the code doesn't pass to the next cout. Why?
        cout << "it doesn't reach here :/" << '\n';
    }
    cout << "backtracking!!" << '\n';
    board[line][col] = 0;
    cout << "agora:" << '\n';
    printBoard(board);
}

I put some "couts" to help me visualize the problem. The "backtracking!!" cout is working properly, but the "it doesn't reach here" cout is not. I thought that, after the code realize It doesn't have possible solutions, It would simply go back to the last recursion, but It's not, giving "segmento fault" error. I don't understand

for (int k = 0; k < size; k++) {
        board[line][col] = possibleNumbers[k];
        cout << k << '\n';
        sudokuSolver(board);
        // the code doesn't pass to the next cout. Why?
        cout << "it doesn't reach here :/" << '\n';
    }

Am I not getting something?

Also, if It's not clear, "isFull" checks if the board is full (base case, game is complete), and possibilities checks the number possibilities of a single cell

Thanks in advance. I guess the details are way better this time, hope I did It right

Edit: The extra couts are ways of showing me where the code is. They are not important for the algorithm itself

Final edit: I did it! Thanks you all. For anyone who wants the full code, here it is:

#include <bits/stdc++.h>
using namespace std;

bool gameRunning = true;

void printBoard(vector<vector<int>> board) {
    for (int i = 0; i <= 8; i++) {
        for (int j = 0; j <= 8; j++) {
            cout << board[i][j] << ' ';
        }
        cout << '\n';
    }
    cout << '\n';
}

void printVector(vector<int> v) {
    for (auto x : v) {
        cout << x << ' ';
    }
    cout << '\n';
    cout << '\n';
}
// Checks if the board is full, deciding if the game is already won
bool isFull(vector<vector<int>> board) {
    for (int i = 0; i <= 8; i++) {
        for (int j = 0; j <= 8; j++) {
            if (!board[i][j]) return false;
        }
    }
    return true;
}

// Generates all number possibilites for a given cell on the board
vector<int> possibilities(vector<vector<int>> board, int i, int j) {
    bitset<9> p;
    for (int i = 1; i <= 9; i++) {
        p[i] = 1;
    }
    //horizontal check
    for (int col = 0; col <= 8; col++) {
        if (board[i][col]) {
            p[board[i][col]] = 0;
        }
    }
    //vertical check
    for (int line = 0; line <= 8; line++) {
        if (board[line][j]) {
            p[board[line][j]] = 0;
        }
    }
    //mini-square check
    int linesquare = (i / 3) * 3;
    int colsquare = (j / 3) * 3;
    for (int l = linesquare; l <= linesquare + 2; l++) {
        for (int c = colsquare; c <= colsquare + 2; c++) {
            if (board[l][c]) {
                p[board[l][c]] = 0;
            }
        }
    }
    vector<int> numberPossibilities;
    for (int k = 1; k <= 9; k++) {
        if (p[k]) numberPossibilities.push_back(k);
    }
    return numberPossibilities;
}

// Solves the game
void sudokuSolver(vector<vector<int>> board) {
    if (isFull(board)) {
        printBoard(board);
        gameRunning = false;
    }
    if (gameRunning) {
        bool found = false;
        int line = 0;
        int col = 0;
        for (int i = 0; i <= 8; i++) {
            for (int j = 0; j <= 8; j++) {
                if (!board[i][j]) {
                    line = i;
                    col = j;
                    found = true;
                    break;
                }
            }
            if (found) break;
        }
        vector<int> possibleNumbers = possibilities(board, line, col);
        int size = possibleNumbers.size();
        for (int k = 0; k < size; k++) {
            board[line][col] = possibleNumbers[k];
            sudokuSolver(board);
        }
        board[line][col] = 0;
    }
}

int main() {
    /*
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    */
    vector<vector<int>> v;
    for (int i = 0; i < 9; i++) {
        vector<int> hold;
        for (int j = 0; j < 9; j++) {
            int a;
            cin >> a;
            hold.push_back(a);
        }
        v.push_back(hold);
    }
    cout << '\n';
    sudokuSolver(v);
    return 0;
}

Bye, have a great day

lvalenca
  • 51
  • 6
  • add a `return` statement at the end of the function. It has a return type different from `void`, so each path should return something. – mch Jun 10 '20 at 07:36
  • Read [*How to debug small programs*](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). If you use [GCC](http://gcc.gnu.org/) compile your C++ code with `g++ -Wall -Wextra -g` then use [GDB](https://sourceware.org/gdb/current/onlinedocs/gdb/). Read [more about C++](https://en.cppreference.com/w/cpp) and the documentation of your C++ compiler and your debugger. Read a good [C++ programming](https://stroustrup.com/programming.html) book and about [the call stack](https://en.wikipedia.org/wiki/Call_stack) – Basile Starynkevitch Jun 10 '20 at 07:39
  • It worked! It's still not right, but the segment fault error is over. Thank you a lot – lvalenca Jun 10 '20 at 07:40
  • I'm almost there, now. Thank you a lot, community of Stack Overflow. I'll try to use this site more often, as I wouldn't be able to realize that if It weren't for you. Also, about "how to debug small programs". I will read it, thank you for the suggestion – lvalenca Jun 10 '20 at 07:46
  • Note: when calling functions, pass the parameters by reference and not by copy. You code will be more efficient – Damien Jun 10 '20 at 17:05
  • wait, for real?! Awesome, I thought they had the same efficiency. Thank you, I'm gonna do that in future projects – lvalenca Jun 11 '20 at 19:59

0 Answers0