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