|
81 | 81 |
|
82 | 82 | def depth_first_search(
|
83 | 83 | possible_board: list[int],
|
84 |
| - diagonal_right_collisions: list[int], |
85 |
| - diagonal_left_collisions: list[int], |
| 84 | + diagonal_right_collisions: set[int], |
| 85 | + diagonal_left_collisions: set[int], |
86 | 86 | boards: list[list[str]],
|
87 | 87 | n: int,
|
88 | 88 | ) -> None:
|
89 | 89 | """
|
90 | 90 | >>> boards = []
|
91 |
| - >>> depth_first_search([], [], [], boards, 4) |
| 91 | + >>> depth_first_search([], set(), set(), boards, 4) |
92 | 92 | >>> for board in boards:
|
93 | 93 | ... print(board)
|
94 |
| - ['. Q . . ', '. . . Q ', 'Q . . . ', '. . Q . '] |
95 |
| - ['. . Q . ', 'Q . . . ', '. . . Q ', '. Q . . '] |
| 94 | + ['. Q . .', '. . . Q', 'Q . . .', '. . Q .'] |
| 95 | + ['. . Q .', 'Q . . .', '. . . Q', '. Q . .'] |
96 | 96 | """
|
97 | 97 |
|
98 |
| - # Get next row in the current board (possible_board) to fill it with a queen |
99 | 98 | row = len(possible_board)
|
100 | 99 |
|
101 |
| - # If row is equal to the size of the board it means there are a queen in each row in |
102 |
| - # the current board (possible_board) |
103 | 100 | if row == n:
|
104 |
| - # We convert the variable possible_board that looks like this: [1, 3, 0, 2] to |
105 |
| - # this: ['. Q . . ', '. . . Q ', 'Q . . . ', '. . Q . '] |
106 | 101 | boards.append([". " * i + "Q " + ". " * (n - 1 - i) for i in possible_board])
|
107 | 102 | return
|
108 | 103 |
|
109 |
| - # We iterate each column in the row to find all possible results in each row |
110 | 104 | for col in range(n):
|
111 |
| - # We apply that we learned previously. First we check that in the current board |
112 |
| - # (possible_board) there are not other same value because if there is it means |
113 |
| - # that there are a collision in vertical. Then we apply the two formulas we |
114 |
| - # learned before: |
115 |
| - # |
116 |
| - # 45º: y - x = b or 45: row - col = b |
117 |
| - # 135º: y + x = b or row + col = b. |
118 |
| - # |
119 |
| - # And we verify if the results of this two formulas not exist in their variables |
120 |
| - # respectively. (diagonal_right_collisions, diagonal_left_collisions) |
121 |
| - # |
122 |
| - # If any or these are True it means there is a collision so we continue to the |
123 |
| - # next value in the for loop. |
124 |
| - if ( |
125 |
| - col in possible_board |
126 |
| - or row - col in diagonal_right_collisions |
127 |
| - or row + col in diagonal_left_collisions |
128 |
| - ): |
| 105 | + if col in possible_board or (row - col) in diagonal_right_collisions or (row + col) in diagonal_left_collisions: |
129 | 106 | continue
|
130 | 107 |
|
131 |
| - # If it is False we call dfs function again and we update the inputs |
132 |
| - depth_first_search( |
133 |
| - [*possible_board, col], |
134 |
| - [*diagonal_right_collisions, row - col], |
135 |
| - [*diagonal_left_collisions, row + col], |
136 |
| - boards, |
137 |
| - n, |
138 |
| - ) |
| 108 | + possible_board.append(col) |
| 109 | + diagonal_right_collisions.add(row - col) |
| 110 | + diagonal_left_collisions.add(row + col) |
| 111 | + |
| 112 | + depth_first_search(possible_board, diagonal_right_collisions, diagonal_left_collisions, boards, n) |
| 113 | + |
| 114 | + # Backtracking |
| 115 | + possible_board.pop() |
| 116 | + diagonal_right_collisions.remove(row - col) |
| 117 | + diagonal_left_collisions.remove(row + col) |
139 | 118 |
|
140 | 119 |
|
141 | 120 | def n_queens_solution(n: int) -> None:
|
142 | 121 | boards: list[list[str]] = []
|
143 |
| - depth_first_search([], [], [], boards, n) |
| 122 | + depth_first_search([], set(), set(), boards, n) |
144 | 123 |
|
145 |
| - # Print all the boards |
146 | 124 | for board in boards:
|
147 | 125 | for column in board:
|
148 | 126 | print(column)
|
|
0 commit comments