Как запустить цикл for с начальной итерации списка после соответствия условию с использованием python - PullRequest
0 голосов
/ 08 января 2019

Пытаясь выполнить следующую задачу:

for element in list:
    if condition is true:
        remove element from list
        start the for loop again with element removed list

Чтобы добиться этого, я пытался, как,

def func(list, p1, p2):
    for element in list:
        if condition is true:
            new_list = remove element from list
        func(new_list, p1, p2)
#Here p1, p2 are used in condition.

Я получаю сообщение об ошибке, поскольку максимальная глубина рекурсии превышена.

Обновлен полный код:

def winner(array, current_player, a, b):
    bob = alice = 0

    def winner_recursive(array, current_player, a, b):
        nonlocal bob, alice

        for cn in array:
            if cn % current_player == 0:
                array.remove(cn)

                if current_player == a:
                    bob += 1
                    current_player = b
                else:
                    alice += 1
                    current_player = a

                return winner_recursive(array, current_player, a, b)

    winner_recursive(array, current_player, a, b)
    if bob > alice:
        return 'BOB'
    elif bob < alice:
        return 'ALICE'
    else:
        if current_player == a:
            return 'ALICE'
        else:
            return 'BOB'

t = int(input())
for _ in range(t):
    N, a, b = map(int, input().split())
    arr = list(map(int, input().split()))

    cp = a
    arr.sort(reverse=True)
    print(winner(arr, cp, a, b))

ввод вышеуказанного кода

2
5 3 2
1 2 3 4 5
5 2 4
1 2 3 4 5

Ожидаемый результат:

ALICE
BOB

Может ли кто-нибудь помочь мне достичь этого с помощью рекурсии или какой лучший питонический способ выполнить эту задачу?

Примечание: Другие подобные SO вопросы, касающиеся диапазона номеров. Здесь я пытаюсь со списком в цикле.

Ответы [ 2 ]

0 голосов
/ 08 января 2019

Проблема в том, что ваша рекурсивная функция winner() работает над двумя разными проблемами. Вам нужно извлечь только рекурсивную часть:

def take_turn(array, a, b):
    global current_player

    for number in array:
        if number % current_player == 0:
            array.remove(number)

            if current_player == a:
                current_player = b
            else:
                current_player = a

            take_turn(array, a, b)

            break  # sub-optimal play

curent_player = None

t = int(input())

for _ in range(t):
    _, b, a = map(int, input().split())
    array = list(map(int, input().split()))

    current_player = b  # Bob plays first

    take_turn(array, a, b)

    # loser is the player stuck unable to make a move
    print('ALICE' if current_player == b else 'BOB')

Это не дает правильного результата, так как он не играет оптимально - он просто заставляет работать рекурсию. Может также произойти сбой, если массив станет достаточно большим, в зависимости от того, как установлен предел глубины рекурсии Python.

0 голосов
/ 08 января 2019

Вы должны сделать отступ для вызова функции так, чтобы он не всегда срабатывал:

def func(list, p1, p2):
    for element in list:
        if condition:
            new_list = remove element from list
            func(new_list, p1, p2)

Однако, вы можете обойтись без рекурсии:

while True:
    for element in list:
        if condition:
            list.remove(element)
            break
    else:
        break  # we didn't break out of the inner loop, so we're done
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...