알고리즘 :: 컴파일러도 “귀찮다” 라고 말하는 하노이 탑 문제


사용자 삽입 이미지

난 단지 지쳐서 Ctrl+C 눌렀을 뿐이고.

얘는 단지 귀찮다고 말할 뿐이고.


하노이 탑 문제를 재귀호출을 이용하여 풀다가 지쳐서 중지시켰는데, 컴파일러가 저런 메시지를 보여줬습니다. 어디에 이런 XBox가 숨어있는건지… ㅋ


하노이 탑을 풀면서 생각한 겁니다만, 재귀호출은 현재를 기반으로 하여 과거를 예측하는 문장이라는 생각이 듭니다. 항상 마지막 과정을 시작으로 하여 처음 과정을 유추하고 결과를 재생하죠.


하노이 탑 문제가 궁금하시다면..

19세기경 유럽에서는 “창세기부터 지금까지 브라마 사원에서 계속되고 있다”는 선전용 문구와 함께 유명했던 “하노이 탑”이라는 게임이 있었답니다.


전설에 의하면 아직도 계속되고 있다는 이 게임은 창세기에 그 사원의 사제가 하나님으로부터 다이아몬드로 된 세 개의 말뚝에 꽂혀 있는 구리 제단을 받았는데, 첫 번째 말뚝에는 금으로 된 64개의 원반이 쌓여 있었고, 각 원반은 바로 밑에 있는 원반보다 조금씩 작았습니다. 사제는 모든 원반을 두 번째 말뚝을 이용하여 세 번째 말뚝에 옮기는 임무를 부여 받았는데, 아래와 같은 규칙이 있었습니다.


  1. 원반은 한번에 하나씩만 옮겨야 한다.
  2. 위에 놓인 원반은 아래의 원반보다 클 수 없다.

만일 그 사제가 64개의 원반을 옮기는 작업을 다 끝내면, 이 세상에는 종말이 온다고 합니다.


재귀 호출을 이용한 소스가 궁금하시다면..

#include <stdio.h>

int cnt = 0;

void moveHanoi(char, char, char, int);

int main(void)
{
    int n;

    printf("하노이 탑에서 옮기려는 원반의 수는? >> ");
    scanf("%d", &n);

    moveHanoi('A', 'B', 'C', n);
    return 0;
}

void moveHanoi(char from, char via, char dest, int n)
{
    if(n == 1) {
        printf("\n%5d: 말뚝 %c 에서 말뚝 %c 로 원반 %d 을 이동 \n", ++cnt, from, dest, 1);
    }
    else {
        moveHanoi(from, dest, via, n-1);
        printf("%5d: 말뚝 %c 에서 말뚝 %c 로 원반 %d 을 이동 \n", ++cnt, from, dest, n);
        moveHanoi(via, from, dest, n-1);
    }
}

Similar Posts

0 Comments

  1. 재귀 함수란 것이 스스로를 호출하는 것을 말합니다. 위 소스에서 moveHanoi() 함수가 있는데, 이 함수 안에서 다시 moveHanoi() 함수를 호출하지요. 그리고 호출된 moveHanoi() 함수는 또 다른 moveHanoi() 함수를 호출합니다. 이렇게 계속 스스로를 호출하기 때문에 계속 반복을 할 수 있는 것입니다.

    함수는 호출되면서 데이터가 스택에 쌓이게 되고, 함수가 종료되면 스택에서 제거됩니다. 그런데 재귀 함수는 자기 자신이 종료되기도 전에 자기 자신을 부르기 때문에 스택에서 제거되지 않고 계속 쌓이게 되죠. 그리고 마지막에 (n==1) 과 같은 조건을 만나서 더 이상 호출을 할 필요가 없게 되면, 호출된 순서의 역순으로 차례대로 함수가 종료됩니다. 여기서 함수가 종료되면서 문자열을 출력하죠.

    재귀 함수는 처음 접하는 분께는 어려운 개념일 거예요. 제 대답이 도움이 되었으면 좋겠네요. 자세한 내용은 아래 문서를 봐주세요.

    http://www.winapi.co.kr/clec/cpp2/16-2-1.htm
    http://www.winapi.co.kr/clec/cpp2/16-2-2.htm

  2. 안녕하세요^^ C 를 공부하고 있는 학생인데요.

    죄송하지만 복사를 해서 실행시켜 보았습니다.

    다른 하노이 프로그램 보다

    더욱 짧고 간단하고 완벽하다고 생각합니다.

    글을 남기는 이유는 의문점이 생겨서 인데요.

    재귀 함수를 사용하는데.

    while, for 문이 없음에도. 어떻게 무한 반복 하듯이 반복하는지 궁금합니다.

    이제 입문 하는 학생이 염치없게도 가르침 부탁합니다.

    항상 건강하세요^^

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다