├── .gitignore ├── README.md ├── main.py └── n_queens.py /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | __pycache__ 3 | venv 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # N-Queens 2 | 3 | Solving N-Queens problem by Backtracking (DFS+BFS) in Python. 4 | 5 | [Eight queens puzzle](https://en.wikipedia.org/wiki/Eight_queens_puzzle) 6 | 7 | ## Related 8 | 9 | Another implementaiotn with time/bord plotting, state tracking and benchmarks: 10 | 11 | [https://github.com/jaya-shankar/n_queens](https://github.com/jaya-shankar/n_queens) 12 | 13 | Thanks to Jaya Shankar! 14 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | from n_queens import NQueens 2 | 3 | 4 | def main(): 5 | print('.: N-Queens Problem :.') 6 | size = int(input('Please enter the size of board: ')) 7 | print_solutions = input('Do you want the solutions to be printed (Y/N): ').lower() == 'y' 8 | n_queens = NQueens(size) 9 | dfs_solutions = n_queens.solve_dfs() 10 | bfs_solutions = n_queens.solve_bfs() 11 | if print_solutions: 12 | for i, solution in enumerate(dfs_solutions): 13 | print('DFS Solution %d:' % (i + 1)) 14 | n_queens.print(solution) 15 | for i, solution in enumerate(bfs_solutions): 16 | print('BFS Solution %d:' % (i + 1)) 17 | n_queens.print(solution) 18 | print('Total DFS solutions: %d' % len(dfs_solutions)) 19 | print('Total BFS solutions: %d' % len(bfs_solutions)) 20 | 21 | 22 | if __name__ == '__main__': 23 | main() 24 | -------------------------------------------------------------------------------- /n_queens.py: -------------------------------------------------------------------------------- 1 | from queue import Queue 2 | 3 | 4 | class NQueens: 5 | 6 | def __init__(self, size): 7 | self.size = size 8 | 9 | def solve_dfs(self): 10 | if self.size < 1: 11 | return [] 12 | solutions = [] 13 | stack = [[]] 14 | while stack: 15 | solution = stack.pop() 16 | if self.conflict(solution): 17 | continue 18 | row = len(solution) 19 | if row == self.size: 20 | solutions.append(solution) 21 | continue 22 | for col in range(self.size): 23 | queen = (row, col) 24 | queens = solution.copy() 25 | queens.append(queen) 26 | stack.append(queens) 27 | return solutions 28 | 29 | def solve_bfs(self): 30 | if self.size < 1: 31 | return [] 32 | solutions = [] 33 | queue = Queue() 34 | queue.put([]) 35 | while not queue.empty(): 36 | solution = queue.get() 37 | if self.conflict(solution): 38 | continue 39 | row = len(solution) 40 | if row == self.size: 41 | solutions.append(solution) 42 | continue 43 | for col in range(self.size): 44 | queen = (row, col) 45 | queens = solution.copy() 46 | queens.append(queen) 47 | queue.put(queens) 48 | return solutions 49 | 50 | def conflict(self, queens): 51 | for i in range(1, len(queens)): 52 | for j in range(0, i): 53 | a, b = queens[i] 54 | c, d = queens[j] 55 | if a == c or b == d or abs(a - c) == abs(b - d): 56 | return True 57 | return False 58 | 59 | def print(self, queens): 60 | for i in range(self.size): 61 | print(' ---' * self.size) 62 | for j in range(self.size): 63 | p = 'Q' if (i, j) in queens else ' ' 64 | print('| %s ' % p, end='') 65 | print('|') 66 | print(' ---' * self.size) 67 | --------------------------------------------------------------------------------