Search code examples
c++loopsn-queens

nqueens - checking with the board, instead of previous queens


There are so many questions regarding Nqueens problem here. However, my implementation is different. My code checks with the board if queen placement is possible, instead of checking with the position of the previous queen.

It goes like this:

initially, the board has all zeros filled. The algorithm starts with the position (0,0). Then, it checks 
row-wise per column to find the first 0. After finding the first zero, it changes the zero to one. 
From this point onward, my logic differs. Instead of going to the next column, it first disables all the 
positions, which the currently placed queen attacks, i.e. writes -1 on those places, i.e., row, column,
upper diagonal and lower diagonal. Now, the column value increments, and instead of check with the previous queen,
it simply has to find the first zero. Then again, relative positions get disabled.... you get the idea.

The code:

#include <iostream>

int board[8][8];

void printBoard() {
    for (int i = 0; i < 8; i++) {
        for (int j = 0; j < 8; j++) {
            std::cout << board[i][j] << " ";
        }
        std::cout << "\n";
    }
}

void disablePositions(int row, int col) {
    //disable row
    for (int j = col + 1; j < 8; j++) {
        board[row][j] = 2;
    }

    //disable column
    for (int i = 0; i < 8; i++) {
        if (board[i][col] == 1) {
            continue;
        }
        board[i][col] = 2;
    }

    //disable upper diagonal
    for (int i = row - 1, j = col + 1; i >= 0 || j < 8; i--, j++) {
        board[i][j] = 2;
    }

    for (int i = row + 1, j = col + 1; i < 8 || j < 8; i++, j++) {
        board[i][j] = 2;
    }
}

void solve(int initial_row) {
    int init = initial_row;
    int row = 0;
    int col = 0;
    while (col != 8) {
        for (row = init; row < 8; row++) {
            if (board[row][col] == 0) {
                board[row][col] = 1;
                break;
            }
        }
        if (row == 8) {
            col = 0;
            initial_row++;
            init = initial_row; 
            for (int i = 0; i < 8; i++) {
                for (int j = 0; j < 8; j++) {
                    board[i][j] = 0;
                }
            }
        }
        else {
            init = 0;
            disablePositions(row, col);
            col++;
        }
        printBoard();
        std::cout << std::endl;
    }
}

int main() {
    solve(0);
    std::cout << std::endl;
}

This code is for 8-queens. The problem is, after it reaches the stage where it starts from [5][0], it just crashes. What is causing the issue?

Also, as it tries to make an optimal choice at every stage, would we call it greedy algorithm?


Solution

  • In your disable upper diagonal loops, you have the condition wrong. Using an || operation, the looping continues when either condition is true, which will lead to out-of-bounds access to the array.

    Change the conditions in both for loops to be && (and).