Skip to content

Commit b9e7c89

Browse files
authored
Added (Open) Knight Tour Algorithm (TheAlgorithms#2132)
* Added (Open) Knight Tour Algorithm * Implemented Suggestions
1 parent 19b713a commit b9e7c89

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed

backtracking/knight_tour.py

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Knight Tour Intro: https://www.youtube.com/watch?v=ab_dY3dZFHM
2+
3+
from typing import List, Tuple
4+
5+
6+
def get_valid_pos(position: Tuple[int], n: int) -> List[Tuple[int]]:
7+
'''
8+
Find all the valid positions a knight can move to from the current position.
9+
10+
>>> get_valid_pos((1, 3), 4)
11+
[(2, 1), (0, 1), (3, 2)]
12+
'''
13+
14+
y, x = position
15+
positions = [
16+
(y + 1, x + 2),
17+
(y - 1, x + 2),
18+
(y + 1, x - 2),
19+
(y - 1, x - 2),
20+
(y + 2, x + 1),
21+
(y + 2, x - 1),
22+
(y - 2, x + 1),
23+
(y - 2, x - 1)
24+
]
25+
permissible_positions = []
26+
27+
for position in positions:
28+
y_test, x_test = position
29+
if 0 <= y_test < n and 0 <= x_test < n:
30+
permissible_positions.append(position)
31+
32+
return permissible_positions
33+
34+
35+
def is_complete(board: List[List[int]]) -> bool:
36+
'''
37+
Check if the board (matrix) has been completely filled with non-zero values.
38+
39+
>>> is_complete([[1]])
40+
True
41+
42+
>>> is_complete([[1, 2], [3, 0]])
43+
False
44+
'''
45+
46+
return not any(elem == 0 for row in board for elem in row)
47+
48+
49+
def open_knight_tour_helper(board: List[List[int]], pos: Tuple[int], curr: int) -> bool:
50+
'''
51+
Helper function to solve knight tour problem.
52+
'''
53+
54+
if is_complete(board):
55+
return True
56+
57+
for position in get_valid_pos(pos, len(board)):
58+
y, x = position
59+
60+
if board[y][x] == 0:
61+
board[y][x] = curr + 1
62+
if open_knight_tour_helper(board, position, curr + 1):
63+
return True
64+
board[y][x] = 0
65+
66+
return False
67+
68+
69+
def open_knight_tour(n: int) -> List[List[int]]:
70+
'''
71+
Find the solution for the knight tour problem for a board of size n. Raises
72+
ValueError if the tour cannot be performed for the given size.
73+
74+
>>> open_knight_tour(1)
75+
[[1]]
76+
77+
>>> open_knight_tour(2)
78+
Traceback (most recent call last):
79+
...
80+
ValueError: Open Kight Tour cannot be performed on a board of size 2
81+
'''
82+
83+
board = [[0 for i in range(n)] for j in range(n)]
84+
85+
for i in range(n):
86+
for j in range(n):
87+
board[i][j] = 1
88+
if open_knight_tour_helper(board, (i, j), 1):
89+
return board
90+
board[i][j] = 0
91+
92+
raise ValueError(f"Open Kight Tour cannot be performed on a board of size {n}")
93+
94+
95+
if __name__ == "__main__":
96+
import doctest
97+
98+
doctest.testmod()

0 commit comments

Comments
 (0)