-1

I could replicate tower of Hanoi problem easily but here is a twist of moving disks +1 or -1 peg/tower only i.e. from peg/tower 1 it can go to space 2 only not to 3.

so far I have this recursive working code for classic situation and struggling to insert movement constraint as stated above

def printMove(fr, to):
    print('Move from ' + str(fr) + ' to ' + str(to))

def Towers(n, fr, to, mid):
    if n == 1:
        printMove(fr, to)
    else:
        Towers(n-1, fr, mid, to)
        Towers(1, fr, to, mid)
        Towers(n-1, mid, to, fr)

n = input("Input the number of disc: ")
print(Towers(int(n), 'P1', 'P2', 'P3'))

could someone help me visualise the constriaint algorithmically

Val
  • 6,585
  • 5
  • 22
  • 52
Pradi KL
  • 696
  • 7
  • 13

2 Answers2

2

When the fr and to pegs are not adjacent, you need to subdivide the problem into two steps. One to move from fr to the mid peg, and one to move the rest of the way to the to peg. This can be done with an extra recursive case:

def Towers(n, fr, to, mid):
    if abs(fr - to) > 1:
        Towers(n, fr, mid, to)
        Towers(n, mid, to, fr)
    elif n == 1:
        printMove(fr, to)
    else:
        Towers(n-1, fr, mid, to)
        Towers(1, fr, to, mid)
        Towers(n-1, mid, to, fr)

Note that the new case needs to be tested before the base case, since you can't move even a single disk more than one peg at a time.

The way I'm checking for adjacent pegs requires that they have numeric labels (so you'd call it with something like Towers(4, 1, 2, 3)). If you're using some other label system (such as strings, in the call you make in the question), you'd need to add some extra logic to let the code know which pegs are adjacent and which are not.

Blckknght
  • 100,903
  • 11
  • 120
  • 169
0

In the normal version of Tower of Hanoi we divide the problem as:-
1) put upper (n-1)-tower in of auxiliary peg. (2^(n-1)-1 steps)
2) put n-th tower in Destination peg. 1 step
3) put upper (n-1)-tower in Destination peg. (2^(n-1)-1 steps)
In total (2^(n-1)-1+1+2^(n-1)-1)=2^n-1 steps Here we write put in Destination peg or Auxiliary peg because we can directly put any disk from anywhere to anywhere, all pegs being symmetric.

But in this constrained version, if we label the the three pegs as 1,2 and 3, two cases have to be considered (as all pegs are not equivalent and order matters unlike previous case.)
Note: a) if you don't want to use 1,2,3 as peg number (use names maybe), you just have to write a few extra lines of code.
b) Here 'disk n' or 'n-th disk' refers to n-th disk when disks are arranged in ascending order of size.

1) if fr!=2 and to!=2, then we have to move the whole tower to the furthest peg (i.e. peg 1 to peg 3 or vice versa). Say, we want to move tower from 1 to 3. Then following will be the steps

i) We cannot move the n-th disk until upper (n-1)-tower is removed and those (n-1)-tower cannot be on adjacent peg (i.e. peg 2 or mid) either, so we move (n-1) tower to peg 3(to). (3^(n-1)-1 steps)
ii) Then move n-th disk to peg 2 (mid) (1 step).
iii) Move (n-1) tower to peg 1 (fr) back again. (3^(n-1)-1 steps)
iv) Then move n-th disk to peg 3 (to). (1 step)
v) Lastly, move (n-1) tower to peg 3(to) again. (3^(n-1)-1 steps)
Total (3^(n-1)-1 + 1 + 3^(n-1)-1 + 1 + 3^(n-1)-1 steps = 3^n-1 steps)

2) if fr==2 or to==2,then we have to move towers to an adjacent peg. For example if we have n disks on peg 2 which we want to move to peg 3:-In reaching the final configuration it will pass through a configuration where (n-1)-tower is on peg 1 and n-th disk is on peg 2. Therefore,
i)we have to place the (n-1)-tower on peg 1 from peg 2. Otherwise we cannot move the n-th disk to peg 3.
ii) Move n-th disk to peg 3.
iii) Finally, move the (n-1)-tower on peg 3.

no=int(input("Enter Number of disks "))

def move_tower(n,fr,to,mid):
    if (n>=1)and(fr!=2)and(to!=2):
        move_tower(n-1,fr,to,mid)
        print("Moving disk ",n,"from ",fr," to ",mid)
        move_tower(n-1,to,fr,mid)
        print("Moving disk ",n,"from ",mid," to ",to)
        move_tower(n-1,fr,to,mid)
    elif (n>=1)and((fr==2)or(to==2)):
        move_tower(n-1,fr,mid,to)
        print("Moving disk ",n,"from ",fr," to ",to)
        move_tower(n-1,mid,to,fr)

# move_tower(no,1,2,3)
move_tower(no,1,3,2)

To code, it is helpful to know intermediate configurations between final and initial configuration. For that pl check these links :
i> Normal version of Tower of Hanoi is similar to counting numbers in binary.
ii> This constrained version of Tower of Hanoi is similar to counting numbers in ternary base 3. Also in moving tower from peg 1 to peg 3 we have to pass through all possible (legal) configurations of disks i.e. 3^n configurations.