Как найти индексы ВСЕХ элементов во всех восьми направлениях (влево, вправо, вверх, вниз, влево-вверх, вправо-вверх, влево-вниз, вправо-вниз) заданной 2D-матрицы/массива?
Например, в приведенной ниже матрице я пытаюсь извлечь элементы, помеченные X, для ввода 0 и т. д.:
X**X**X
*X*X*X*
**XXX**
XXX0XXX
**XXX**
X0XXXXX
XXX****
*X*X***
*X**X**
*X***X*
Я использовал эту лямбда-функцию, чтобы получить список всех соседних элементов во всех восьми направлениях.
X = len(grid)
Y = len(grid[0])
neighbors = lambda x, y : [(x2, y2) for x2 in range(x-1, x+2)
for y2 in range(y-1, y+2)
if (-1 < x < X and
-1 < y < Y and
(x != x2 or y != y2) and
(0 <= x2 < X) and
(0 <= y2 < Y))]
**XXX**
**X0X**
**XXX**
*******
Я хочу иметь возможность расширить вышеизложенное, чтобы получить вышеуказанное.
Вы можете создать функцию, которая «стреляет» во всех направлениях от нужной точки до тех пор, пока не будет достигнут конец сетки. Возврат всех найденных точек:
def direction_points(g_len_x, g_len_y, point_x, point_y):
result = []
directions = [
[0, -1], # up
[1, -1], # up right
[1, 0], # right
[1, 1], # down right
[0, 1], # down
[-1, 1], # down left
[-1, 0], # left
[-1, -1], # left up
]
for direction in directions:
x = point_x
y = point_y
end_reached = False
while not end_reached:
x = x + direction[0]
y = y + direction[1]
if (0 <= x < g_len_x) and not end_reached:
if (0 <= y < g_len_y) and not end_reached:
result.append([x, y])
else:
end_reached = True
else:
end_reached = True
return result
При этом вы можете создать линии или сетку:
grid_len_x = 10
grid_len_y = 12
mid_point_x = 4
mid_point_y = 6
points = direction_points(grid_len_x, grid_len_y, mid_point_x, mid_point_y)
lines = []
for y in range(grid_len_y):
line = ''
for x in range(grid_len_x):
if [x, y] in points:
line += 'X'
else:
if x == mid_point_x and y == mid_point_y:
line += '0'
else:
line += '*'
lines.append(line)
for line in lines:
print(line)
Результат
****X*****
****X****X
X***X***X*
*X**X**X**
**X*X*X***
***XXX****
XXXX0XXXXX
***XXX****
**X*X*X***
*X**X**X**
X***X***X*
****X****X
Следующее предоставит индексы во всех восьми направлениях:
from itertools import product
def valid_indexes(lst, row, col):
return row in range(len(lst)) and col in range(len(lst[0]))
# Queen's view since it's the same as what a queen in chess can 'view'
def queens_view(lst, row, col, dr=0, dc=0):
if dr or dc:
yield (row, col)
if valid_indexes(lst, row+dr, col+dc):
yield from queens_view(lst, row+dr, col+dc, dr, dc)
else:
for dr, dc in product([-1, 0, 1], [-1, 0, 1]):
if dr or dc and valid_indexes(lst, row+dr, col+dc):
yield from queens_view(lst, row+dr, col+dc, dr, dc)
start_row, start_col = 3, 4 # Index of the '0' in your list
for row, col in queens_view(lst, start_row, start_col):
print(row, col)
# Do what you like with the index
Каков ожидаемый результат для двух матриц? для первого должно быть восемь пар индексов (т.е. индексов соседних «X»?)