Computer Science/Algorithms

๐Ÿ—ผTower of Hanoi

metamong 2024. 4. 9.

intro

๐Ÿ—ผ ์œ ๋ช…ํ•œ 'ํ•˜๋…ธ์ด์˜ ํƒ‘' ์•Œ๊ณ ๋ฆฌ์ฆ˜์— ๋Œ€ํ•ด ์†Œ๊ฐœํ•œ๋‹ค. 3๊ฐœ์˜ ๊ธฐ๋‘ฅ์ด ์žˆ๊ณ , ๋‹ค์–‘ํ•œ ํฌ๊ธฐ์˜ n๊ฐœ์˜ ์›ํŒ(์›ํŒ์˜ ํฌ๊ธฐ๋Š” ๋ชจ๋‘ ๋‹ค๋ฅด๋‹ค)์ด ์กด์žฌํ•œ๋‹ค. ํผ์ฆ์„ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์—๋Š” ํ•œ ๊ธฐ๋‘ฅ์— n๊ฐœ์˜ ์›ํŒ๋“ค์ด ์ž‘์€ ๊ฒƒ์ด ์œ„์— ์žˆ๋„๋ก ์ˆœ์„œ๋Œ€๋กœ ์Œ“์—ฌ ์žˆ๋‹ค. ์•„๋ž˜ 3๊ฐ€์ง€ ์กฐ๊ฑด์„ ๋งŒ์กฑ ์‹œํ‚ค๋ฉด์„œ ๋‹ค๋ฅธ ๊ธฐ๋‘ฅ์œผ๋กœ ์˜ฎ๊ฒจ์„œ ๋‹ค์‹œ ์Œ“๋Š” ํผ์ฆ์ด๋‹ค.

 

โ‘  ํ•œ ๋ฒˆ์— 1๊ฐœ์˜ ์›ํŒ๋งŒ ์˜ฎ๊ธธ ์ˆ˜ ์žˆ๋‹ค.

โ‘ก ๊ฐ€์žฅ ์œ„์— ์žˆ๋Š” ์›ํŒ๋งŒ ์ด๋™ํ•  ์ˆ˜ ์žˆ๋‹ค.

โ‘ข ํฐ ์›ํŒ์ด ์ž‘์€ ์›ํŒ ์œ„์— ์žˆ์–ด์„œ๋Š” ์•ˆ๋œ๋‹ค.

 

์ด ๋•Œ, ์ตœ์†Œ ์ด๋™ํšŸ์ˆ˜๋กœ ๋งจ ์™ผ์ชฝ ๊ธฐ๋‘ฅ์—์„œ ๋งจ ์˜ค๋ฅธ์ชฝ ๊ธฐ๋‘ฅ์œผ๋กœ n๊ฐœ์˜ ์›ํŒ์„ ์ˆœ์„œ์— ๋งž์ถ”์–ด์„œ ์Œ“์•„์ฃผ๋ฉด ๋œ๋‹ค

example demo (n=3)

๐Ÿ—ผ n=3์ผ ๋•Œ Hanoi Tower๋ฅผ ์Œ“์•„๋ณด์ž!

๐Ÿ—ผ Hanoi Tower ๋ฌธ์ œ๋Š” ํฌ๊ฒŒ ์•„๋ž˜ 3๊ฐ€์ง€ ์ˆœ์„œ๋กœ ์ง„ํ–‰๋œ๋‹ค.

* Hanoi(3,A,C,B): 3๊ฐœ์˜ ์›๋ฐ˜์„ A์—์„œ C๊นŒ์ง€ (B๋ฅผ ๊ฑฐ์ณ) ์˜ฎ๊ธฐ๋Š” ๊ณผ์ •

 

โ‘  1๋ฒˆ๋ถ€ํ„ฐ 4๋ฒˆ๊นŒ์ง€์˜ ๊ณผ์ • = Hanoi(2,A,B,C)

: ๋จผ์ € ๋งจ ์•„๋ž˜ N๋ฒˆ์˜ ์›๋ฐ˜์„ ์ œ์™ธํ•˜๊ณ  (N-1)๊ฐœ์˜ ์›๋ฐ˜์„ A์—์„œ ๋ฐ”๋กœ ์˜† B๋กœ ์˜ฎ๊ธด๋‹ค

 

โ‘ก 5๋ฒˆ ๊ณผ์ •

: A์— ์žˆ๋Š” N๋ฒˆ ์›๋ฐ˜์„ C๋กœ ์˜ฎ๊ธด๋‹ค

 

โ‘ข 6๋ฒˆ๋ถ€ํ„ฐ 8๋ฒˆ๊นŒ์ง€์˜ ๊ณผ์ • = Hanoi(2,B,C,A)

: B์— ์žˆ๋Š” (N-1)๊ฐœ์˜ ์›๋ฐ˜์„ C๋กœ ์˜ฎ๊ธด๋‹ค

 

* ์œ„ 3๊ฐ€์ง€ ๊ณผ์ •์„ ๊ทธ๋ฆผ์œผ๋กœ ๋‚˜ํƒ€๋‚ด๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

recursion & code

๐Ÿ—ผ ๋”ฐ๋ผ์„œ Hanoi(3,A,C,B)๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

(์ด ๋•Œ, move(N,1,3)์€ N๋ฒˆ ์›๋ฐ˜์„ 1๋ฒˆ์—์„œ 3๋ฒˆ ๊ธฐ๋‘ฅ์œผ๋กœ ์˜ฎ๊ธฐ๋Š” ๊ฒƒ์„ ๋œปํ•จ)

 

Hanoi(3,A,C,B) = Hanoi(2,A,B,C) + Hanoi(1,A,C,B) + Hanoi(2,B,C,A)

 

๐Ÿ—ผ ์ผ๋ฐ˜ํ™”ํ•œ๋‹ค๋ฉด

 

Hanoi(N,A,C,B) = Hanoi(N-1,A,B,C) + Hanoi(1,A,C,B) + Hanoi(N-1,B,C,A)

โ˜ž Hanoi(N,start,dest,via) = Hanoi(N-1,start,via,dest) + Hanoi(1,start,dest,via) + Hanoi(N-1,via,dest,start)

(if N == 1 then move 1 plate to dest and return)

 

: "Hanoi(N,A,C,B) = N-1๊ฐœ์˜ ์›๋ฐ˜์„ ๋จผ์ € A์—์„œ B๋กœ ์˜ฎ๊ธฐ๊ณ , ๋‚จ์€ N๋ฒˆ์งธ ์›๋ฐ˜์„ C๋กœ ์˜ฎ๊ธด ๋’ค, B์— ์žˆ๋Š” N-1๊ฐœ์˜ ์›๋ฐ˜์„ C๋กœ ์˜ฎ๊ธด๋‹ค"

 

๐Ÿ—ผํŒŒ์ด์ฌ ์ฝ”๋“œ๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๋‹ค. 3๊ฐœ์˜ ์›๋ฐ˜์ด ์˜ฎ๊ธฐ๋Š” ๊ณผ์ •์„ ์ถœ๋ ฅ.

ans=[]
def hanoi(n,a,c,b):
    if n == 1:
        ans.append((a,c))
    else:
        hanoi(n-1,a,b,c)
        hanoi(1,a,c,b)
        hanoi(n-1,b,c,a)

hanoi(3,1,3,2)

for x in ans:
    print(*x)
        
'''
1 3
1 2
3 2
1 3
2 1
2 3
1 3
'''

number of moves

๐Ÿ—ผN๊ฐœ์˜ ์›๋ฐ˜์„ ํ•˜๋…ธ์ด ํƒ‘์—์„œ ์›€์ง์ด๋Š” ํšŸ์ˆ˜๋ฅผ hanoi(N)์ด๋ผ ํ•˜์ž

 

hanoi(N) = hanoi(N-1) + 1 + hanoi(N-1)

(N==1์ด๋ผ๋ฉด hanoi(1) = 1)

 

: hanoi(N)์„ a_n์ด๋ผ ํ•˜๋ฉด ์•„๋ž˜ ๊ทธ๋ฆผ์— ์˜ํ•ด hanoi(N) = 2^n - 1

exercises

โ˜… <BOJ G5 11729 ํ•˜๋…ธ์ด ํƒ‘ ์ด๋™ ์ˆœ์„œ> โ˜…

Q. N๊ฐœ์˜ ์›ํŒ์˜ ํ•˜๋…ธ์ด ํƒ‘ ์ด๋™ ์ˆœ์„œ ์ฐจ๋ก€๋Œ€๋กœ ์ถœ๋ ฅ(ํ•˜๋…ธ์ด ํƒ‘ ์œ„ ์˜ˆ์ œ ์ฝ”๋“œ์™€ ๋™์ผ). ์ด๋™ ํšŸ์ˆ˜๋Š” 2^N-1๋กœ ์ถœ๋ ฅ 

 

โ˜… <BOJ G5 1914 ํ•˜๋…ธ์ด ํƒ‘> โ˜…

Q. ์œ„ 11729 ๋ฌธ์ œ์™€ ๋™์ผ

 

โ˜… <BOJ G4 23250 ํ•˜๋…ธ์ด ํƒ‘ K> โ˜…

Q. K๋ฒˆ์งธ ์ด๋™์„ ์ถœ๋ ฅ. ์ด ๋•Œ ์‹œ๊ฐ„์ดˆ๊ณผ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•ด ์„ ํƒ์ ์œผ๋กœ ์žฌ๊ท€ ํ™œ์šฉ. N๊ฐœ์˜ ์›ํŒ์ด๋ผ๋ฉด ์ฒซ hanoi() ํ•จ์ˆ˜๋Š” (2^(n-1)-1) ํšŸ์ˆ˜ ์ดํ•˜์ผ ๋•Œ๋งŒ, ๋‘๋ฒˆ์งธ ๋‹จ๋… ์ด๋™์€ 2^(n-1)๋ฒˆ์งธ ์ด๋™. ๋‘ ๋ฒˆ์งธ hanoi() ํ•จ์ˆ˜๋Š” 2^(n-1)+1 ~ 2^(n)-1 ๋ฒˆ์งธ ์ด๋™์ผ ๋•Œ๋งŒ, ์žฌ๊ท€ ๋Œ๋ฆฐ๋‹ค

 

โ˜… <BOJ S2 15500 ์ด์ƒํ•œ ํ•˜๋…ธ์ด ํƒ‘> โ˜…

Q. ๊ธฐ์กด ํ•˜๋…ธ์ด ํƒ‘์€ ์›ํŒ ์ˆœ์„œ๋Œ€๋กœ ๋ง‰๋Œ€์— ์œ„์น˜ํ•ด ์žˆ์–ด์•ผ ํ•˜๋‚˜, ์›ํŒ ์ˆœ์„œ๋Œ€๋กœ ์žˆ์„ ํ•„์š” ์—†๋Š” ๋ณ€ํ˜•๋œ ํ•˜๋…ธ์ด ํƒ‘ ๋ฌธ์ œ. ์ตœ์†Œ ์ด๋™ ํšŸ์ˆ˜๋Š” ๊ทธ์ € ๋‹น์žฅ ๊ฐ€์žฅ ๋ฌด๊ฒŒ๊ฐ€ ๋งŽ์ด ๋‚˜๊ฐ€๋Š” ์›ํŒ์„ ์ฐพ์„ ๋•Œ๊นŒ์ง€ ์‹œ๋ฎฌ๋ ˆ์ด์…˜์œผ๋กœ ๋ฐ”๊พผ ํšŸ์ˆ˜. pop() + append() ๋ฐ˜๋ณตํ•˜๊ณ  ์ฐพ์œผ๋ฉด pop()ํ•œ ๋’ค ์„ธ๋ฒˆ์งธ ์ตœ์ข… ๋ง‰๋Œ€์— append(). stack + simulation์œผ๋กœ ๊ทธ์ € ํ’€๋ฆฌ๋Š” ๋ฌธ์ œ.

+ printing disk number

๐Ÿ—ผ ์•ž์„œ ํ•™์Šตํ•œ ํ•˜๋…ธ์ด์˜ ํƒ‘ ์žฌ๊ท€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ ์ด๋™ํ•˜๋Š” ๋ง‰๋Œ€์˜ ์ข…๋ฅ˜(์ด์ „/์ดํ›„)๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ๊ฒƒ ์™ธ๋กœ ๋งจ ์œ„๋ถ€ํ„ฐ ์ž‘์€ ์ˆœ์„œ๋Œ€๋กœ 1๋ฒˆ, 2๋ฒˆ, 3๋ฒˆ ์ด๋ ‡๊ฒŒ N๋ฒˆ๊นŒ์ง€ ๋ฒˆํ˜ธ๋ฅผ ๋งค๊ฒผ์„ ๋•Œ, ๋ช‡ ๋ฒˆ์˜ ์›ํŒ์ด ์ด๋™ํ•˜๋Š” ์ง€ disk number๋„ ๋„์ค‘์— ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

โ˜… hanoi ์žฌ๊ท€ ์ฝ”๋“œ๋ฅผ ์ง๊ด€์ ์œผ๋กœ ๋ณด๋ฉด else๋ฌธ์—์„œ์˜ move๋Š” N๋ฒˆ ์›ํŒ์„ ์˜ฎ๊ธฐ๊ณ (2~N๋ฒˆ) / if๋ฌธ์—์„œ์˜ move๋Š” ์žฌ๊ท€ ์ข…๋ฃŒ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด ๋งˆ์ง€๋ง‰์œผ๋กœ ๋‚จ์€ 1๋ฒˆ ์›ํŒ์„ ์˜ฎ๊ธฐ๋Š”(1๋ฒˆ), ๋‘ ์ข…๋ฅ˜์˜ move๋กœ ๋ถ„์„ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

โ˜… ๋”ฐ๋ผ์„œ ๋‘ ์ข…๋ฅ˜์˜ move(N๋ฒˆ ์›๋ฐ˜ ์˜ฎ๊ธฐ๋Š” move๋Š” (N,์ถœ๋ฐœ์ง€์ ,๋„์ฐฉ์ง€์ )์„ ans์— append / 1๋ฒˆ ์›๋ฐ˜ ์˜ฎ๊ธฐ๋Š” move(์žฌ๊ท€ ์ข…๋ฃŒ์šฉ)๋Š” (1,์ถœ๋ฐœ์ง€์ ,๋„์ฐฉ์ง€์ )์„ ans์— append) 

ans=[]
def hanoi(n,a,c,b):
    if n == 1:
        ans.append((1,a,c))
    else:
        hanoi(n-1,a,b,c)
        ans.append((n,a,c))
        hanoi(n-1,b,c,a)

n=int(input())
print(2**n-1)
hanoi(n,1,3,2)
for pair in ans:
    n1,n2,n3=pair[0],pair[1],pair[2]
    n2='XABC'[n2]
    n3='XABC'[n3]
    print(f'move disk {n1} {n2}->{n3}')

 


ํ•˜๋…ธ์ด์˜ ํƒ‘ wiki

hanoi(N) ์ฆ๋ช… ๊ณผ์ •

'Computer Science > Algorithms' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

๐Ÿ˜๏ธEuler Sieve  (1) 2024.04.21
๐ŸฅCounting Sort  (0) 2024.04.17
โž•Merge Sort  (0) 2024.04.06
๐Ÿก Two Pointers  (1) 2024.02.11
๐Ÿฆœ Pigeonhole Principle  (0) 2024.02.02

๋Œ“๊ธ€