-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsolution.py
176 lines (131 loc) · 5.34 KB
/
solution.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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
import unittest
def solution(src, dest):
"""
Solve a movement puzzle in order to cross the floor.
The function returns an integer representing the smallest number of moves it will take for you to travel from
the source square to the destination square using a chess knight's moves (that is, two squares in any direction
immediately followed by one square perpendicular to that direction, or vice versa, in an "L" shape).
Both the source and destination squares will be an integer between 0 and 63, inclusive.
:param src: the source square, on which you start
:param dest: the destination square, which is where you need to land to solve the puzzle
:return: an integer representing the smallest number of moves it will take to travel from the source square to the destination square using a chess knight's moves
"""
if src < 0 or src > 63:
return 0
if dest < 0 or dest > 63:
return 0
board = []
row_size = 8
col_size = 8
# initialise the board
for move in range(row_size):
row = []
for j in range(col_size):
row.append(None)
board.append(row)
# Get the x and y coordinates of the src and dest, respectively
source_x = src / row_size
source_y = src % col_size
destination_x = dest / row_size
destination_y = dest % col_size
# initialize 'board' with the coordinates of the src square
board[source_x][source_y] = 0
# Define the legal moves for a chess knight
knight_moves = [
[1, 2], [1, -2],
[-1, 2], [-1, -2],
[2, 1], [2, -1],
[-2, 1], [-2, -1]
]
# Number of reachable_squares_coords from source_x to source_y is 0
reachable_squares_coords = [(source_x, source_y)]
while reachable_squares_coords:
# get the coords of the top square
x, y = reachable_squares_coords.pop(0)
# for each legal move
for move in knight_moves:
row, col = x + move[0], y + move[1]
# if row and col are both within the defined boundaries of the board
if 0 <= row < row_size and 0 <= col < col_size:
# if we have not yet visited this square
if board[row][col] is None:
# set the value of the square
board[row][col] = board[x][y] + 1
# record the coordinate of this square, which is reachable from the src square
reachable_squares_coords.append((row, col))
# the number of moves is the value stored in the destination square
num_moves = board[destination_x][destination_y]
return num_moves
class ChessMoveTests(unittest.TestCase):
def test_from_0_to_1(self):
source_square = 0
destination_square = 1
expected_moves = 3
moves = solution(source_square, destination_square)
self.assertEqual(expected_moves, moves)
def test_from_19_to_36(self):
source_square = 19
destination_square = 36
expected_moves = 1
moves = solution(source_square, destination_square)
self.assertEqual(expected_moves, moves)
def test_from_63_to_53(self):
source_square = 63
destination_square = 53
expected_moves = 1
moves = solution(source_square, destination_square)
self.assertEqual(expected_moves, moves)
def test_from_63_to_36(self):
source_square = 63
destination_square = 36
expected_moves = 2
moves = solution(source_square, destination_square)
self.assertEqual(expected_moves, moves)
def test_from_7_to_55(self):
source_square = 7
destination_square = 55
expected_moves = 4
moves = solution(source_square, destination_square)
self.assertEqual(expected_moves, moves)
def test_from_12_to_22(self):
source_square = 12
destination_square = 22
expected_moves = 1
moves = solution(source_square, destination_square)
self.assertEqual(expected_moves, moves)
def test_from_13_to_23(self):
source_square = 13
destination_square = 23
expected_moves = 1
moves = solution(source_square, destination_square)
self.assertEqual(expected_moves, moves)
def test_from_14_to_24(self):
source_square = 14
destination_square = 24
expected_moves = 4
moves = solution(source_square, destination_square)
self.assertEqual(expected_moves, moves)
def test_negative_src(self):
source_square = -7
destination_square = 55
expected_moves = 0
moves = solution(source_square, destination_square)
self.assertEqual(expected_moves, moves)
def test_negative_dest(self):
source_square = 7
destination_square = -55
expected_moves = 0
moves = solution(source_square, destination_square)
self.assertEqual(expected_moves, moves)
def test_src_too_large(self):
source_square = 75
destination_square = 55
expected_moves = 0
moves = solution(source_square, destination_square)
self.assertEqual(expected_moves, moves)
def test_dest_too_large(self):
source_square = 7
destination_square = 65
expected_moves = 0
moves = solution(source_square, destination_square)
self.assertEqual(expected_moves, moves)