
# hanoiIter.py
# The Method of Scorer, Grundy, and Smith

import sys

def moves(n):
  if n%2 == 0:
    while True:
      moveDisk(srcNm, auxNm)
      moveDisk(srcNm, destNm)
      moveDisk(auxNm, destNm)
  else:
    while True:
      moveDisk(srcNm, destNm)
      moveDisk(srcNm, auxNm)
      moveDisk(auxNm, destNm)


def moveDisk(p1Nm, p2Nm):
  '''
    When one of these two poles is empty we must move 
    the disk from the non-empty pole to the empty one.

    When the top disk of one pole is smaller than the disk
    on top of the other pole, then we move the smaller of 
    two disks to the pole with the bigger disk.
  '''
  if (poles[p1Nm] == []) and (poles[p2Nm] == []):  
    # both poles are empty
    # print(f"Finished: {p1Nm} and {p2Nm} both empty")
    sys.exit(0)

  if poles[p1Nm] == []:  # p1 is empty
    doMove(p2Nm, p1Nm)
  elif poles[p2Nm] == []:
    doMove(p1Nm, p2Nm)
  else:
    # look at both top disks for comparison
    p1Disk = poles[p1Nm][-1]
    p2Disk = poles[p2Nm][-1]
    if (p1Disk > p2Disk): # p2 disk is smaller
      doMove(p2Nm, p1Nm)
    else:                 # p1 disk is smaller
      doMove(p1Nm, p2Nm)


def doMove(fromNm, toNm):
  disk = poles[fromNm].pop()
  poles[toNm].append(disk) 
  print(f"Disk {disk}: {fromNm} --> {toNm}  :", strPoles())


def strPoles():
  return f"[ {l2s(poles[srcNm]):{sz}s} [ {l2s(poles[auxNm]):{sz}s} [ {l2s(poles[destNm]):{sz}s}"


def l2s(pole):
  return ' '.join([str(disk) for disk in pole])


# ----------------------

n = int(input("n? "))
sz = n*2

# a dictionary of poles to hold the disks
srcNm, auxNm, destNm,  = 'A', 'B', 'C'    # pole names
poles = {srcNm:[], auxNm:[], destNm:[]}

# put disks on source pole
for i in range(n, 0, -1):
  poles[srcNm].append(i)

print(' '*18,  srcNm, ' '*sz, auxNm, ' '*sz, destNm);
print(' '*18, strPoles())

moves(n)