Задать вопрос
@atsin4469

Как решить задачу правильно?

Задача
Есть список из слов "NORTH", "WEST", "SOUTH" и "EAST". Если рядом стоят WEST и EAST или SOUTH и NORTH, то такая пара удаляется из списка (т.к. сделать шаг вперед, а потом шаг назад — все равно, что стоять на месте). Необходимо вернуть список, очищенный от таких пар с сохранением исходной очередности слов. То есть [NORTH, EAST] не равно [EAST, NORTH]

Примеры вывода
["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"] >>> ['WEST']

["NORTH", "WEST", "SOUTH", "EAST"] >>> ["NORTH", "WEST", "SOUTH", "EAST"]


Мое неверное решение
def dirReduc(arr):
    x = 0
    y = 0
    l = []
    for i in arr:
    	if i == 'NORTH':
    		y += 1
    	elif i == 'SOUTH':
    		y -= 1
    	elif i == 'EAST':
    		x += 1
    	else:
    		x -= 1
    if x < 0:
    	l.append('WEST' * abs(x))
    elif x > 0:
    	l.append('EAST' * x)
    if y < 0:
    	l.append('SOUTH' * abs(y))
    elif y > 0:
    	l.append('NORTH' * y)
    return l

Решение не подходит, т.к. не сохраняет порядок слов и имеет другие проблемы
  • Вопрос задан
  • 329 просмотров
Подписаться 1 Простой 1 комментарий
Решения вопроса 1
@o5a
Подобная задача проще всего решается через стэк.
Перебираем постепенно элементы исходного списка.
Если последний элемент стэка равен противоположному (NORTH-SOUTH и т.п.) текущего элемента списка, то удаляем (stack.pop()) этот элемент из стэка. В противном случае добавляем к стэку. В конце цикла в стэке останется только неисключенные элементы (без пар). Для соответствия пар можно задать словарь.
Примерно так (спрячу под спойлер, на случай если захочется реализовать самостоятельно):
spoiler
def dirReduc(arr):
    dirs = {"NORTH": "SOUTH", "SOUTH": "NORTH", "EAST": "WEST", "WEST": "EAST"}
    stack = []
    for d in arr:
        if stack and dirs[d] == stack[-1]:
            stack.pop()
        else:
            stack.append(d)
    return stack
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@vutmuk123
S=["NORTH", "WEST", "SOUTH", "EAST"]
pair1={"WEST", "EAST" }
pair2={"NORTH", "SOUTH"}

for i in range(len(S)-1,-1,-1):
    if {S[i], S[i - 1]} ==pair1 or {S[i], S[i - 1]} ==pair2:
        S.pop(i)
        S.pop(i-1)

print(S)


не уверен на 100% что верно, но оба примера проходят..)
Ответ написан
@alegzz
def dirReduc(arr):
    DIRS = {'NORTH': 1, 'SOUTH': -1, 'WEST': 1, 'EAST': -1}
    dirs1 = ['WEST', 'EAST']
    dirs2 = ['NORTH', 'SOUTH']
    temparr = []
    previosdirs = []
    i = 0
    while i <= len(arr):
        if previosdirs == []:
            if arr[i] in dirs1:
                previosdirs = dirs1
            elif arr[i] in dirs2:
                previosdirs = dirs2
            steps = DIRS[arr[i]]
        else:
            if i < len(arr) and arr[i] in previosdirs:
                steps += DIRS[arr[i]]
            else:
                if steps > 0:
                    j = 0
                elif steps < 0:
                    j = 1
                temparr.extend([previosdirs[j]] * abs(steps))
                if i < len(arr):
                    if arr[i] in dirs1:
                        previosdirs = dirs1
                    else:
                        previosdirs = dirs2
                    steps = DIRS[arr[i]]
        i += 1

    return temparr

оптимизируй это
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы