- Notifications
You must be signed in to change notification settings - Fork 46.7k
/
Copy pathknight_tour.py
101 lines (73 loc) · 2.39 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
99
100
101
# Knight Tour Intro: https://www.youtube.com/watch?v=ab_dY3dZFHM
from __future__ importannotations
defget_valid_pos(position: tuple[int, int], n: int) ->list[tuple[int, 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= []
forinner_positioninpositions:
y_test, x_test=inner_position
if0<=y_test<nand0<=x_test<n:
permissible_positions.append(inner_position)
returnpermissible_positions
defis_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
"""
returnnotany(elem==0forrowinboardforeleminrow)
defopen_knight_tour_helper(
board: list[list[int]], pos: tuple[int, int], curr: int
) ->bool:
"""
Helper function to solve knight tour problem.
"""
ifis_complete(board):
returnTrue
forpositioninget_valid_pos(pos, len(board)):
y, x=position
ifboard[y][x] ==0:
board[y][x] =curr+1
ifopen_knight_tour_helper(board, position, curr+1):
returnTrue
board[y][x] =0
returnFalse
defopen_knight_tour(n: int) ->list[list[int]]:
"""
Find the solution for the knight tour problem for a board of size n. Raises
ValueError if the tour cannot be performed for the given size.
>>> open_knight_tour(1)
[[1]]
>>> open_knight_tour(2)
Traceback (most recent call last):
...
ValueError: Open Knight Tour cannot be performed on a board of size 2
"""
board= [[0foriinrange(n)] forjinrange(n)]
foriinrange(n):
forjinrange(n):
board[i][j] =1
ifopen_knight_tour_helper(board, (i, j), 1):
returnboard
board[i][j] =0
msg=f"Open Knight Tour cannot be performed on a board of size {n}"
raiseValueError(msg)
if__name__=="__main__":
importdoctest
doctest.testmod()