def move_disks(n, from_tower, to_tower, aux_tower):
result = []
###BEGIN SOLUTION
# base case
if n == 1:
return [f"Move disk {n:} from {from_tower:} to {to_tower:}."]
# recursive case
else:
# move n-1 disks from src to an aux tower
result = move_disks(n-1, from_tower, aux_tower, to_tower)
# move nth disk src to dest tower
result = [f"Move disk {n:} from {from_tower:} to {to_tower:}."]
# move n-1 disks from aux to dest
result = move_disks(n-1, aux_tower, to_tower, from_tower)
###END SOLUTION
return result
#Test cases
result = move_disks(3, "A", "B", "C")
print(result)
assert result == ["Move disk 1 from A to B.", "Move disk 2 from A to C.", "Move disk 1 from B to C.", "Move disk 3 from A to B.", "Move disk 1 from C to A.", "Move disk 2 from C to B.", "Move disk 1 from A to B."]
My doubt is this. Why is the iteration when n=1 for move_disks (in following picture), A,B,C for "from_tower,to_tower and aux_tower" respectively. I feel it should be A,C,B respectively.
Please refer to the image attached below for seeing python tutor visualization.
CodePudding user response:
Why is the iteration when n=1 for move_disks (in following picture), A,B,C for "from_tower,to_tower and aux_tower" respectively.
Because the goal of the whole problem is to move the whole stack from A to B. This can be seen from the top-level call: move_disks(3, "A", "B", "C")
. In this call B is the target.
Now when the number of disks is odd, then the first move (when n==1
) should be from A to B (with C being auxiliary). It is odd in this particular call move_disks(3, "A", "B", "C")
.
Be aware that each execution of move_disks
has its own set of names. You have already understood that the value of n
in one execution is not the same as in another execution, but the same principle applies to the other parameters: the caller may pass aux_tower
as value for the recursive name to_tower
, and so on.
Here is a visualisation of the first part of the process for 3 disks. Each box is an execution of the function. Each box has its own set of names:
move_disks(3, "A", "B", "C")
┌───────────────────────────────────────────────────────────────────┐
│ locals: n=3, from_tower="A", to_tower="B", aux_tower="C" │
│ else-case │
│ result = move_disks(2, "A", "C", "B") │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ locals: n=2, from_tower="A", to_tower="C", aux_tower="B" │ │
│ │ else-case │ │
│ │ result = move_disks(1, "A", "B", "C") │ │
│ │ ┌───────────────────────────────────────────────────────────┐ │ │
│ │ │ locals: n=1, from_tower="A", to_tower="B", aux_tower="C" │ │ │
│ │ │ if-case │ │ │
│ │ │ return ["Move disk 1 from A to B."] │ │ │
│ │ └───────────────────────────────────────────────────────────┘ │ │
│ │ result = ["Move disk 2 from A to C."] │ │
│ │ result = move_disks(1, "B", "C", "A") │ │
│ │ ┌───────────────────────────────────────────────────────────┐ │ │
│ │ │ locals: n=1, from_tower="B", to_tower="C", aux_tower="A" │ │ │
│ │ │ if-case │ │ │
│ │ │ return ["Move disk 1 from B to C."] │ │ │
│ │ └───────────────────────────────────────────────────────────┘ │ │
│ │ return result │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ ...etc