How can i memorize a paramter in a function that recall?

Viewed 75
def freed_prisoners(prison):
    prisoners_count = 0
    if prison[0] == 1:
        prisoners_count += 1
        del prison[0]
        if len(prison) != 0:
            for i in range(len(prison)):
                if prison[i] == 1:
                    prison[i] = 0
                else:
                    prison[i] = 1
            freed_prisoners(prison)
        else:
            return prisoners_count
    else:
        del prison[0]
        if len(prison) != 0:
            freed_prisoners(prison)
        else:
            return prisoners_count


print(freed_prisoners([1, 1, 0, 0, 0, 1, 0]))

It returns none and i don t know why That's the exercise: A prison can be represented as a list of cells. Each cell contains exactly one prisoner. A 1 represents an unlocked cell and a 0 represents a locked cell.

[1, 1, 0, 0, 0, 1, 0] Starting inside the leftmost cell, you are tasked with seeing how many prisoners you can set free, with a catch. You are the prisoner in the first cell. If the first cell is locked, you cannot free anyone. Each time you free a prisoner, the locked cells become unlocked, and the unlocked cells become locked again.

2 Answers

I think your two recursion lines:

freed_prisoners(prison)

Should both be:

return prisoners_count + freed_prisoners(prison)

With this modification every return returns the total of prisoners freed locally and also from the remaining cells.

To "memorize", you could add the paramater count to your function freed_prisoners(prison, count=0) and call freed_prisoners(prison, count).

However its not recommended in this case. You can break a recursion problem without the need of "memorizing" your parameter.

I suggest you try those recommendation

  1. Check if prison[0] == 1. Because if True: you're locked and cannot unlock anyone. You can return 0
  2. Reverse value of the prison when you unlock someone
  3. If all cells are locked return the count
  4. If you can unlock return the value of count + freed_prisoners(prison)

Example: (should work as is)

def freed_prisoners(prison, is_in_cell=True):
    c = 0
    if is_in_cell & prison[0] == 1:
        print("My cell is locked. Cannot free any prisoners")
        return 0
    if is_in_cell:
        prison.pop(0)
        c = 1
    def reverse_prison(prison):
        return [1 if (x == 0) else 0 for x in prison]
    for i, cell in enumerate(prison):
        if cell == 0:
             prison.pop(i)
             reverse_prison(prison)
             c += 1
             break
    if all(prison) == True:
        return c
    return c + freed_prisoners(prison, is_in_cell=False)
>>> PRISON = [0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0]
>>> print(freed_prisoners(PRISON))
12
Related