Упрощение прямолинейных перемещений в списке пошаговых (x, y) координат

#python #algorithm #logic

#python #алгоритм #Логические

Вопрос:

В моей игре у меня есть список кортежей (x, y) :

 solution = [(36, 37), (36, 36), (36, 35), (37, 35), (38, 35),  (38, 34),  (38, 33), (38, 32)]
 

Этот список описывает движения, которые игрок должен выполнить, чтобы перейти от точки (36, 37) к точке (38, 32).

Я хочу упростить этот список до следующего :

 opti = [(36, 37), (36, 35), (38, 35), (38, 32)]
 

Это означает, что я хочу сократить любую серию шагов, где x фиксировано (или y фиксировано), только до первого и последнего шага.

Я изо всех сил пытаюсь найти алгоритм для этого. Я пытаюсь уже более двух часов, и вот над чем я сейчас пытаюсь работать:

 solution = [(36, 37), (36, 36), (36, 35), (37, 35), (38, 35),  (38, 34),  (38, 33), (38, 32)]
opti = [solution[0]]
for i in range(len(solution)):
    if opti[-1][0] == solution[i][0]:
        pass
    elif opti[-1][1] == solution[i][1]:
        pass
    else:
        opti.append(solution[i])
 

В конце opti равно [(36, 37), (37, 35), (38, 34)] , что не то, что я хочу.. Может кто-нибудь указать мне правильный способ сделать это?

Комментарии:

1. Мне это I want to reduce any series of steps where x is fixed (or y is fixed) to only the first and the last step непонятно. Почему (36, 36) удаляется, но (36, 35) нет?

2. (36, 35) не удаляется, потому что это последний элемент, где x фиксируется на 36. В то же время (36, 35) также отмечает начало второй прямой (где y фиксируется на 35). Это означает: первая прямая линия: (36, 37) — (36, 35), вторая прямая линия: (36, 35) — (38, 35), третья прямая линия: (38, 35) — (38, 32)

3. @Gabriel OP хочет первый и последний шаг в фиксированном движении x или фиксированном y

Ответ №1:

Вы можете попробовать это: сравните предыдущее и следующее местоположение с текущим местоположением при переборе списка (решения), чтобы проверить, находятся ли все точки в одной строке, передайте, если они находятся в одной строке, иначе добавьте в окончательный (opti) список.

 solution = [(36, 37), (36, 36), (36, 35), (37, 35), (38, 35),  (38, 34),  (38, 33), (38, 32)]
opti = [solution[0]]
for i in range(1, len(solution) -1 ):
    if solution[i-1][0] == solution[i][0] and solution[i][0] == solution[i 1][0]:
        pass
    elif solution[i-1][1] == solution[i][1] and solution[i][1] == solution[i 1][1]:
        pass
    else:
        opti.append(solution[i])
opti.append(solution[-1])

print(opti)
 

вывод:

 [(36, 37), (36, 35), (38, 35), (38, 32)]
 

Я надеюсь, что это поможет, не стесняйтесь обращаться в случае каких-либо сомнений.

Комментарии:

1. Отлично сработано, спасибо! Я бы не подумал о opti.append(решение [-1]) в конце. Во время моей попытки я также попытался протестировать i-1 и i 1, но я пропустил диапазон, который я использовал для i в диапазоне (len(решение)), что привело к ошибке index out of range .

2. Добро пожаловать. Я могу полностью связать, это происходит со всеми. Удачи.

Ответ №2:

Сохраняйте точки, если они не находятся на прямой линии.

 pad = [(None, None)]
opti = [(x, y)
        for (x0, y0), (x, y), (x1, y1)
            in zip(pad   solution, solution, solution[1:]   pad)
        if not (x0 == x == x1 or y0 == y == y1)]