#python #algorithm
#python #алгоритм
Вопрос:
у меня есть матрица, в которой есть только точка (.) или звезда (*). мне нужен алгоритм, который находит начала в форме буквы L. каждый L состоит из 5 звезд и может иметь общие звезды с другим L. какой-нибудь пример:
[['*', '*', '.', '*', '*'],
['*', '*', '.', '*', '*'],
['*', '*', '.', '*', '*'],
['*', '*', '.', '*', '*'],
['*', '*', '.', '*', '*'],
['*', '*', '.', '*', '*'],
['*', '*', '.', '*', '*']]
in this matrix we have 8 L.(here's two Ls:[(0,0), (1,0), (2,0), (3,0), (3,1)], [(1,0), (2,0), (3,0), (4,0), (4,1)])
[['*', '.', '.', '.', '.'],
['*', '.', '.', '.', '.'],
['*', '.', '.', '.', '.'],
['*', '*', '.', '.', '.'],
['*', '*', '.', '.', '.'],
]
in this matrix we have 2 L
[['*', '.', '.', '.', '.'],
['*', '.', '.', '.', '.'],
['*', '.', '.', '.', '.'],
['*', '*', '.', '.', '.'],
]
just 1 L
и вот мой код, но я думаю, что в нем есть ошибка.
L_counter = 0
def find_L(star_row, star_column):
global my_list
global L_counter
if my_list[star_row 1][star_column] == '*':
if my_list[star_row 2][star_column] == '*':
if my_list[star_row 3][star_column] == '*':
if my_list[star_row 3][star_column 1] == '*':
L_counter = 1
my_list = [['*', '*', '.', '*', '*'],
['*', '*', '.', '*', '*'],
['*', '*', '.', '*', '*'],
['*' ,'*', '.', '*', '*'],
['*', '*', '.', '*', '*'],
['*', '*', '.', '*', '*'],
['*', '*', '.', '*', '*']
]
for row, i in enumerate(my_list[:-3]):
for column, j in enumerate(i[:-1]):
if j == '*':
find_L(row, column)
print(L_counter)
Комментарии:
1. Итак, вы хотите определить прямые углы, начиная с ячейки и двигаясь вниз по соседям, а затем поперек? Пройдитесь по каждой ячейке, игнорируя последнюю строку и последние столбцы, спуститесь вниз и убедитесь, что у вас нет соседей слева, и если есть один под ним, проверьте, есть ли у него один под ним, иначе переместитесь вправо. Если вы разветвляетесь, вам придется учитывать каждую ветвь.
2. Что заставляет вас думать, что в нем есть ошибка? Была ли какая-то конкретная матрица, в которой произошел сбой?
3.
find_L
проверяет только четыре звезды, должно быть пять4. было бы намного чище с массивами numpy. Фактически, это сведется к однострочной свертке. Дайте мне знать, если вам нужен пример
5. @tylerstoney есть сайт, на который мы отправили код. они протестировали код и сказали, что это неправильно, не объясняя причины. 🙁
Ответ №1:
Не так элегантно, как должно быть, но лучшее, что я мог бы сделать без numpy:
# approach: look for the vertical 4-bar plus one star in the 'foot'
sum(foot=='*' and all(row[col_num]=='*' for row in rows)
for rows in zip(*(my_list[j:] for j in range(4)))
for col_num, foot in enumerate(rows[-1][1:])
)