
# adjHanoi.py
'''
Tower of Hanoi with. Adjacency Requirement: 

Suppose that in addition to the requirement that they never move a larger disk on top of a smaller one, the priests who move the disks of the Tower of Hanoi are also allowed only to move disks one by one from one pole to an adjacent pole. 

Assume poles A and C are at the two ends of the row and pole B is in the middle. 

Discrete Mathematics With Applications,
Susanna S. Epp
Third Edition, Thomas Learning, 2004
Q 8.18
'''


def hanoi(n, source, target):
  aux = getOther(source, target)
  if n > 0:
    if isAdjacent(source, target):
      hanoi(n-1, source, aux)
      move(n, source, target)
      hanoi(n-1, aux, target)
    else:  # aux adj source and aux adj target
      hanoi(n-1, source, target)
      move(n, source, aux)
      hanoi(n-1, target, source)
      move(n, aux, target)
      hanoi(n-1, source, target)


def move(disk, s, d):
  global count
  print(f"{count:2d}. Disk {disk}: {s} --> {d}")
  count += 1


def getOther(p1, p2):
  nPoles = poles.copy()
  nPoles.remove(p1)
  nPoles.remove(p2)
  return nPoles[0]


def isAdjacent(p1, p2):
  pos1 = poles.index(p1)
  pos2 = poles.index(p2)
  return (abs(pos1 - pos2) == 1)


# ------------------

source = "src"
aux = "aux"
target = "dst"
poles = [source, aux, target]
count = 1

n = int(input("n=? "))
hanoi(n, source, target)
