diff --git a/backtracking/n_queens.cpp b/backtracking/n_queens.cpp index 8aab5df7b9c871396363a482b12d056e2a35ff76..89d907750ba5282b6e2d844bbcd92175c9af8de0 100644 --- a/backtracking/n_queens.cpp +++ b/backtracking/n_queens.cpp @@ -1,63 +1,129 @@ +/** + * @file + * @brief [Eight Queens](https://en.wikipedia.org/wiki/Eight_queens_puzzle) + * puzzle + * + * @details + * The **eight queens puzzle** is the problem of placing eight chess queens on + * an 8×8 chessboard so that no two queens threaten each other; thus, a solution + * requires that no two queens share the same row, column, or diagonal. The + * eight queens puzzle is an example of the more general **n queens problem** of + * placing n non-attacking queens on an n×n chessboard, for which solutions + * exist for all natural numbers n with the exception of n = 2 and n = 3. + * + * @author Unknown author + * @author [David Leal](https://github.com/Panquesito7) + * + */ #include -#define N 4 -using namespace std; - -void printSolution(int board[N][N]) { - cout << "\n"; - for (int i = 0; i < N; i++) { - for (int j = 0; j < N; j++) cout << "" << board[i][j]; - cout << "\n"; - } -} - -bool isSafe(int board[N][N], int row, int col) { - int i, j; +#include - /* Check this row on left side */ - for (i = 0; i < col; i++) - if (board[row][i]) - return false; +/** + * @namespace backtracking + * @brief Backtracking algorithms + */ +namespace backtracking { + /** + * @namespace n_queens + * @brief Functions for [Eight Queens](https://en.wikipedia.org/wiki/Eight_queens_puzzle) puzzle. + */ + namespace n_queens { + /** + * Utility function to print matrix + * @tparam n number of matrix size + * @param board matrix where numbers are saved + */ + template + void printSolution(const std::array, n> &board) { + std::cout << "\n"; + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + std::cout << "" << board[i][j] << " "; + } + std::cout << "\n"; + } + } - /* Check upper diagonal on left side */ - for (i = row, j = col; i >= 0 && j >= 0; i--, j--) - if (board[i][j]) - return false; + /** + * Check if a queen can be placed on matrix + * @tparam n number of matrix size + * @param board matrix where numbers are saved + * @param row current index in rows + * @param col current index in columns + * @returns `true` if queen can be placed on matrix + * @returns `false` if queen can't be placed on matrix + */ + template + bool isSafe(const std::array, n> &board, const int &row, + const int &col) { + int i = 0, j = 0; - /* Check lower diagonal on left side */ - for (i = row, j = col; j >= 0 && i < N; i++, j--) - if (board[i][j]) - return false; + // Check this row on left side + for (i = 0; i < col; i++) { + if (board[row][i]) { + return false; + } + } - return true; -} + // Check upper diagonal on left side + for (i = row, j = col; i >= 0 && j >= 0; i--, j--) { + if (board[i][j]) { + return false; + } + } + // Check lower diagonal on left side + for (i = row, j = col; j >= 0 && i < n; i++, j--) { + if (board[i][j]) { + return false; + } + } + return true; + } -void solveNQ(int board[N][N], int col) { - if (col >= N) { - printSolution(board); + /** + * Solve n queens problem + * @tparam n number of matrix size + * @param board matrix where numbers are saved + * @param col current index in columns + */ + template + void solveNQ(std::array, n> board, const int &col) { + if (col >= n) { + printSolution(board); return; - } + } - /* Consider this column and try placing - this queen in all rows one by one */ - for (int i = 0; i < N; i++) { - /* Check if queen can be placed on - board[i][col] */ - if (isSafe(board, i, col)) { - /* Place this queen in board[i][col] */ - // cout<<"\n"<(board, i, col)) { + // Place this queen in matrix + board[i][col] = 1; - /* recur to place rest of the queens */ - solveNQ(board, col + 1); + // Recursive to place rest of the queens + solveNQ(board, col + 1); - board[i][col] = 0; // BACKTRACK + board[i][col] = 0; // backtrack } + } } -} + } // namespace n_queens +} // namespace backtracking +/** + * Main function + */ int main() { - int board[N][N] = {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}; + const int n = 4; + std::array, n> board = { + std::array({0, 0, 0, 0}), + std::array({0, 0, 0, 0}), + std::array({0, 0, 0, 0}), + std::array({0, 0, 0, 0}) + }; - solveNQ(board, 0); - return 0; + backtracking::n_queens::solveNQ(board, 0); + return 0; }