원반이 2개일 때
총 3번 이동 1번 원반을 1에서 2로 이동 2번 원반을 1에서 3로 이동 1번 원반을 2에서 3로 이동
원반이 3개일 때
총 7번 이동 1번 원반을 1에서 3로 이동 2번 원반을 1에서 2로 이동 1번 원반을 3에서 2로 이동 3번 원반을 1에서 3로 이동 1번 원반을 2에서 1로 이동 2번 원반을 2에서 3로 이동 1번 원반을 1에서 3로 이동
n
이라 할 때, n
을 도착 기둥에 옮기기 위해 그 위에 놓여 있는 n-1
개의 원반을 보조 기둥에 옮긴다. n
을 도착 기둥에 옮긴다. n-1
개의 원반을 도착 기둥에 옮긴다.MOVE_MESSAGE = "{}번 원반을 {}에서 {}로 이동"
def move(N, start, destination):
print(MOVE_MESSAGE.format(N, start, destination))
def hanoi(n, start, destination, via):
"""
하노이의 탑 규칙에 따라 원반을 옮기고,
옮길 때마다 원반의 시작 위치와 이동한 위치를 출력합니다.
마지막으로 총 이동 횟수를 반환합니다.
:params
n: 총 원반 개수
start: 시작 기둥
destination: 도착 기둥
via: 보조 기둥:
:return count:
"""
# 원반이 1개일 때 시작 기둥에서 도착 기둥까지 한 번에 이동
if n <= 1:
move(1, start, destination)
return 1
count = 0
# 원반 n-1개를 시작 기둥에서 보조 기둥으로 이동
count += hanoi(n - 1, start, via, destination)
# 가장 큰 원반을 시작 기둥에서 도착 기둥으로 이동
count += 1
move(n, start, destination)
# 원반 n-1개를 보조 기둥에서 도착 기둥으로 이동
count += hanoi(n - 1, via, destination, start)
return count
if __name__ == '__main__':
n = 3
start = 1
destination = 3
via = 2
total_count = hanoi(n, start, destination, via)
print('총 이동 횟수:', total_count)
'''
출력 결과
1번 원반을 1에서 3로 이동
2번 원반을 1에서 2로 이동
1번 원반을 3에서 2로 이동
3번 원반을 1에서 3로 이동
1번 원반을 2에서 1로 이동
2번 원반을 2에서 3로 이동
1번 원반을 1에서 3로 이동
총 이동 횟수: 7
'''
먼저 " 수열 = 개의 원판을 이동하는 횟수 " 라고 정의하자.
개의 원판을 이동시키기 위해서는 그 위의 -개의 원판을 다른 막대로 이동하고 맨 아래쪽 원판을 도착지로 이동해야 한다. 그리고 다시 -개의 원판을 이동해야 하므로 다음과 같은 점화식이 성립한다.
=> = 2
그리고 이를 일반항으로 풀어내면 임을 알 수 있다.
참고
n
개의 원반을 모두 옮기기 위해서는