-
-
Notifications
You must be signed in to change notification settings - Fork 46.8k
N queens math #2175
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
N queens math #2175
Changes from 13 commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
1483887
add new file for another solution to the n queens problem
DavidBanda 105d9ee
Add the code for the algorithm, add comments and add at the top a gen…
DavidBanda 5222388
Update backtracking/n_queens_math.py
DavidBanda e65b5a7
Update backtracking/n_queens_math.py
DavidBanda 6692361
Update backtracking/n_queens_math.py
DavidBanda 9e6d572
Update backtracking/n_queens_math.py
DavidBanda 2af2536
No newline at the end of the file
DavidBanda 42a5cfb
Type hints
DavidBanda c821598
whitespaces fixed
DavidBanda b62b637
Fixed whitespaces
DavidBanda 2bd7aee
Add type hints
DavidBanda 0f96b60
CodeSpell fixed
DavidBanda af938a0
update
DavidBanda 6989f83
All changes made except changing the board variable to local
DavidBanda 7c63b77
Add doctest
DavidBanda 68b573d
Update
DavidBanda de33d23
Update
DavidBanda 26eb205
Update
DavidBanda 6fbceb5
Update n_queens_math.py
cclauss File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
r""" | ||
Problem: | ||
|
||
The n queens problem is of placing N queens on a N * N | ||
chess board such that no queen can attack any other queens placed | ||
on that chess board. | ||
This means that one queen cannot have any other queen on its horizontal, vertical and | ||
diagonal lines. | ||
|
||
Solution: | ||
|
||
To solve this problem we will use simple math. First we know | ||
the queen can move in all the possible ways, we can | ||
simplify it in this: vertical, horizontal, diagonal left and | ||
diagonal right. | ||
|
||
We can visualize it like this: | ||
|
||
left diagonal = \ | ||
right diagonal = / | ||
|
||
On a chessboard vertical movement could be the rows | ||
and horizontal movement could be the columns. | ||
|
||
In programming we can use an array, and in this | ||
array each index could be the rows and each value in | ||
the array could be the column. For example: | ||
|
||
. Q . . We have this chessboard with one queen in each column and each queen | ||
. . . Q can't attack to each other. | ||
Q . . . The array for this example would look like this: [1, 3, 0, 2] | ||
. . Q . | ||
|
||
So if we use an array and we verify that each | ||
value in the array is different to each other we | ||
know that at least the queens can't attack each other | ||
in horizontal and vertical. | ||
|
||
At this point we have that halfway completed and we will treat | ||
the chessboard as a Cartesian plane. | ||
Hereinafter we are going to remember basic math, | ||
so in the school we learned this formula: | ||
|
||
Slope of a line: | ||
|
||
y2 - y1 | ||
m = ---------- | ||
x2 - x1 | ||
|
||
This formula allow us to get the slope. For the angles 45º ( | ||
right diagonal) and 135º (left diagonal) this formula gives us | ||
m = 1, and m = -1 respectively | ||
(here a lit more information: | ||
https://www.enotes.com/homework-help/write-equation-line-that-hits-origin-45-degree-1474860). | ||
|
||
Then we have this another formula: | ||
|
||
Slope intercept: | ||
|
||
y = mx + b | ||
|
||
b is where the line crosses the Y axis (to get | ||
more information see here: https://www.mathsisfun.com/y_intercept.html), | ||
if we change the formula to solve for b we would have: | ||
|
||
y - mx = b | ||
|
||
And like we already have the m values for the angles | ||
45º and 135º, this formula would look like this: | ||
|
||
45º: y - (1)x = b | ||
45º: y - x = b | ||
|
||
135º: y - (-1)x = b | ||
135º: y + x = b | ||
|
||
y = row | ||
x = column | ||
|
||
Applying this two formulas we can check | ||
if a queen in some position is being attacked | ||
for another one or vice versa. | ||
|
||
""" | ||
|
||
|
||
def n_queens_solution(n): | ||
DavidBanda marked this conversation as resolved.
Show resolved
Hide resolved
|
||
boards = [] | ||
|
||
DavidBanda marked this conversation as resolved.
Show resolved
Hide resolved
|
||
""" dfs is the function in where we found all the boards. | ||
- First paramether: we pass the possible current board | ||
to add to our variable boards | ||
- Second paramether: Is a variable to store diagonal right | ||
collisions for the queens in the First paramether (possible_board). | ||
- Third paramether: Same as Second paramether but | ||
for diagonal left collisions. | ||
""" | ||
dfs([], [], [], boards, n) | ||
DavidBanda marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
""" Print all the boards """ | ||
for board in boards: | ||
for column in board: | ||
print(column) | ||
print('') | ||
|
||
print("The total no. of solutions are :", len(boards)) | ||
|
||
|
||
def dfs(possible_board, diagonal_right_collisions, diagonal_left_collisions, boards, n): | ||
""" | ||
:type possible_board: list | ||
:type diagonal_right_collisions: list | ||
:type diagonal_left_collisions: list | ||
:type boards: list | ||
:type n: int | ||
""" | ||
DavidBanda marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
DavidBanda marked this conversation as resolved.
Show resolved
Hide resolved
|
||
""" Get next row in the current board (possible_board) to | ||
fill it with a queen """ | ||
row = len(possible_board) | ||
|
||
""" If row is equal to the size of the board it | ||
means there are a queen in each row | ||
in the current board (possible_board) """ | ||
if row == n: | ||
""" We convert the variable possible_board that | ||
looks like this: [1, 3, 0, 2] | ||
to this: ['. Q . . ', '. . . Q ', 'Q . . . ', '. . Q . '] """ | ||
possible_board = ['. ' * i + 'Q ' + '. ' * (n - 1 - i) for i in possible_board] | ||
|
||
""" Then we add it to the 'boards' global variable """ | ||
DavidBanda marked this conversation as resolved.
Show resolved
Hide resolved
|
||
boards.append(possible_board) | ||
return | ||
|
||
""" We iterate each column in the row to find all | ||
possible results in each row """ | ||
for col in range(n): | ||
|
||
""" We apply that we learned previously. First we check | ||
that in the current board (possible_board) there are | ||
not other same value because if there is it means that there | ||
are a collision in vertical. Then we apply the two formulas | ||
we learned before: | ||
|
||
45º: y - x = b or 45: row - col = b | ||
135º: y + x = b or row + col = b. | ||
|
||
And we verify if the results of this two formulas not | ||
exist in their variables respectively. | ||
(diagonal_right_collisions, diagonal_left_collisions) | ||
|
||
If some of this is True we continue to the other value in | ||
the for loop because it means there are a collision """ | ||
if col in possible_board or row - col in diagonal_right_collisions \ | ||
or row + col in diagonal_left_collisions: | ||
DavidBanda marked this conversation as resolved.
Show resolved
Hide resolved
|
||
continue | ||
|
||
""" If it is False we call dfs function again and | ||
we update the inputs """ | ||
dfs(possible_board + [col], | ||
diagonal_right_collisions + [row - col], | ||
diagonal_left_collisions + [row + col], | ||
boards, n) | ||
DavidBanda marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
|
||
n_queens_solution(4) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.