108 lines
2.7 KiB
Python
108 lines
2.7 KiB
Python
# neighbors = {
|
|
# 1: [6, 8],
|
|
# 2: [7, 9],
|
|
# 3: [8, 4],
|
|
# 4: [9, 3, 0],
|
|
# 5: [],
|
|
# 6: [0, 7, 1],
|
|
# 7: [2, 6],
|
|
# 8: [1, 3],
|
|
# 9: [4, 2],
|
|
# 0: [4, 6]
|
|
# }
|
|
|
|
# cache = {}
|
|
|
|
# def count_numbers(current_number, number_of_hops):
|
|
# cache_value = (current_number, number_of_hops)
|
|
# if cache_value in cache:
|
|
# return cache[cache_value]
|
|
|
|
# if number_of_hops == 1:
|
|
# return 1
|
|
# number_count = 0
|
|
# for neighbor in neighbors[current_number]:
|
|
# number_count += count_numbers(neighbor, number_of_hops - 1)
|
|
|
|
# cache[cache_value] = number_count
|
|
# return number_count
|
|
|
|
|
|
class DialpadCounter(object):
|
|
|
|
knight_deltas = [
|
|
(2, 1),
|
|
(-2, -1),
|
|
(-2, 1),
|
|
(2, -1),
|
|
(1, 2),
|
|
(-1, -2),
|
|
(-1, 2),
|
|
(1, -2)
|
|
]
|
|
|
|
def __init__(self, dialpad_matrix):
|
|
self._matrix = dialpad_matrix
|
|
self._row_size = len(dialpad_matrix[0])
|
|
self._row_count = len(dialpad_matrix)
|
|
self._cache = {}
|
|
|
|
def neighbors(self, y, x):
|
|
result = []
|
|
for delta_y, delta_x in self.knight_deltas:
|
|
neighbor_y = delta_y + y
|
|
neighbor_x = delta_x + x
|
|
neighbor = (neighbor_y, neighbor_x)
|
|
if (self.inbounds(neighbor_y, neighbor_x) and
|
|
self._matrix[neighbor_y][neighbor_x]):
|
|
result.append(neighbor)
|
|
return result
|
|
|
|
def inbounds(self, y, x):
|
|
return 0 <= x < self._row_size and 0 <= y < self._row_count
|
|
|
|
def count_numbers(self, coordinate, number_of_hops):
|
|
y, x = coordinate
|
|
if not self._matrix[y][x]:
|
|
raise Exception()
|
|
|
|
cache_value = (coordinate, number_of_hops)
|
|
|
|
if cache_value in self._cache:
|
|
return self._cache[cache_value]
|
|
|
|
if number_of_hops == 1:
|
|
return 1
|
|
|
|
number_count = 0
|
|
for neighbor in self.neighbors(y, x):
|
|
number_count += self.count_numbers(neighbor, number_of_hops - 1)
|
|
|
|
self._cache[cache_value] = number_count
|
|
|
|
return number_count
|
|
|
|
def count_numbers(number, number_of_hops):
|
|
matrix = [
|
|
[True, True, True],
|
|
[True, True, True],
|
|
[True, True, True],
|
|
[False, True, False]
|
|
]
|
|
if number == 0:
|
|
coordinate = 3, 1
|
|
else:
|
|
row = (number - 1) // 3
|
|
column = (number - 1) % 3
|
|
coordinate = (row, column)
|
|
counter = DialpadCounter(matrix)
|
|
return counter.count_numbers(coordinate, number_of_hops)
|
|
|
|
if __name__ == '__main__':
|
|
print(count_numbers(1, 1))
|
|
print(count_numbers(1, 2))
|
|
print(count_numbers(1, 3))
|
|
print(count_numbers(1, 4))
|
|
print(count_numbers(1, 10))
|
|
print(count_numbers(1, 30))
|