Почему эти два алгоритма возврата имеют одинаковые выходы? - PullRequest
0 голосов
/ 07 февраля 2020

Я сделал две реализации алгоритма возврата, чтобы решить эту проблему на Codewars (https://www.codewars.com/kata/5a6b24d4e626c59d5b000066). Моя проблема в том, что я спрашиваю, почему работает первая реализация, а не почему вторая. Я думаю, что моя проблема в выражении return в последней строке со знаками ha sh. Я не понимаю, почему, когда откат заканчивается, так как решение было найдено, вторая реализация возвращает правильное решение вместо пустого списка. Это потому, что когда решение передается предыдущему вызову функции, его значение в предыдущем вызове (которое было с элементом less) перезаписывается полным решением?

First:

def square_sums_row(n):
    a , sol = [ x for x in range(1,n+1)] , []
    def recurse(a,sol):
        if a == [] : 
            return sol 
        for i,x in enumerate(a) :
            if is_valid(x,sol) :
                sol.append(x)
                iterate = recurse(a[:i]+a[i+1:],sol) ###########
                if iterate : ###########
                    return iterate #########
                sol.pop(-1)
        return False
    def is_valid(x,sol):
        if len(sol) == 0 :
            return True
        if (( sol[-1] + x )**0.5) % 1 == 0:
            return True
        return False
    return recurse(a,sol)

Второй:

def square_sums_row(n):
    s , sol = [ x for x in range(1,n+1)] , []
    def recurse(s,sol):
        if s == [] :  
            return sol
        for i,x in enumerate(s) :
            if is_valid(x,sol) :
                sol.append(x)
                if recurse(s[:i]+s[i+1:],sol) : ###########
                    return sol ##############
                sol.pop(-1)
        return False
    def is_valid(x,sol):
        if len(sol) == 0 :
            return True
        if (( sol[-1] + x )**0.5) % 1 == 0:
            return True
        return False
    return recurse(s,sol)

Ответы [ 2 ]

1 голос
/ 07 февраля 2020

Чтобы развернуть другой ответ, существует только один объект списка sol, который передается и возвращается. Это никогда не копируется. Вот еще одно решение, чтобы подчеркнуть этот момент. Здесь sol нигде не является аргументом, он просто берется из замыкания, и внутренние функции возвращают только логические значения.

def square_sums_row(n):
    sol = []

    def recurse(s):
        if s == []:
            return True
        for i, x in enumerate(s):
            if is_valid(x):
                sol.append(x)
                iterate = recurse(s[:i] + s[i + 1:])  ###########
                if iterate:  ###########
                    return True
                sol.pop(-1)
        return False

    def is_valid(x):
        if len(sol) == 0:
            return True
        if ((sol[-1] + x) ** 0.5) % 1 == 0:
            return True
        return False

    if recurse([x for x in range(1, n + 1)]):
        return sol
    else:
        return False

1 голос
/ 07 февраля 2020

Это работает, потому что они возвращают то же самое, оба решения возвращают sol. Просто вторая возвращает переменную sol напрямую, тогда как первая возвращает выходные данные функции (которая является той же переменной sol, переданной в качестве аргумента).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...