[백준 11729번] - 하노이 탑 이동 순서 (javascript)

2024. 10. 12. 22:21·알고리즘/재귀

[11729] 하노이 탑 이동 순서

들어가기 전에

오늘은 백준 골드 5 난이도의 하노이 탑 문제를 자바스크립트로 풀어봤다. 이 문제는 재귀문제로 재귀의 개념과 작동 원리를 이해하고 있어야 한다. 

문제 설명

입력값으로 하노이 탑의 높이인 N이 입력되면 1번 장대에 존재하던 N개의 탑을 모두 3번 장대로 이동시키는 이 문제의 목표이다. 단, 한 번에 하나의 원판만 옮길 수 있으며, 더 작은 원판 위에 더 큰 원판을 올릴 수 없다.

선수 지식

이 문제를 풀기 전에 알아야 할 개념은 아래와 같다.

  • 재귀 함수를 구현하는 방법

사용한 함수/메서드

문제 풀이에 있어 핵심 메서드는 아니지만, 결과 출력을 처리할 때 사용했다.

  • Array.prototype.join()

아이디어

이해를 돕기 위한 설명

우선 문제에서 주어진 예시 입력값을 가지고 생각해보자. 하노이 탑의 높이가 3인 경우이다. 판은 (빨간색 / 주황색 / 노랑색)으로 구성돼 있다.

 

일단, A에 있는 탑을 전부 C로 옮기기 위해서는 A의 가장 밑에 있는 노랑색 판을 먼저 C로 이동시켜야 한다. 작은 원판 위에 더 큰 원판을 올릴 수는 없으므로, A에는 노란색 판만 남아 있어야 하고, C에는 어떠한 원판도 존재해서는 안된다. 그렇다면 나머지 탑(빨강색과 주황색)은 어디에 있어야 할까? 전부 정렬되어 B 장대에 있어야 한다. 즉 아래 우측의 그림과 같은 상태를 만들어야 한다.

이 상태가 돼야 노란색 판을 C로 이동시킬 수 있다. 자 근데 생각해보자, A에서 B로 (빨간색, 주황색 판)을 이동시키기 위해서는 주황색 판(또 맨 아랫판이네!)부터 (A→B) 로 이동시켜야 한다. 그런데 위에 빨간색 판이 하나 더 있다. 그럼 빨간색 판은 어디로 이동시켜야 할까? 빨간색 판은 (A→B)로 주황색 판이 이동하는 걸 막으면 안되므로 나머지 장대인 C로 이동해야 한다. 빨간색 판을 이동시키고 나면, 이제 주황색 판을 (A→B)로 이동시킬 수 있게된다, 그리고 C에 있는 빨간색 판을 B로 갖고 오면? A에 있는 노란색 판을 C로 이동시킬 수 있게 되는 거다.

 

자 C로 노란색 판을 이동을 시켰으면 이제 B로 옮겨놓은 나머지 탑을 똑같이 맨 아랫판부터 C로 차례차례 갖고 와야 한다. 이 때, B의 주황색 판을 C로 갖고 오기 위해서는 어떻게 해야할까? 위에서 진행했던 방식과 마찬가지로 B(from)의 주황색 판을 C(to)로 (B→C)로 이동시키기 위해서는 나머지 장대인 A(temp)로 주황색 판 위의 탑들을 모두 이동시켜야 한다. 위에 빨간판밖에 없으니 그냥 옮기면 된다!

 

 

💡아하!

A 에서 C로 N개의 탑을 이동시키려면, 먼저 A에서 B로 (1 ~ N - 1)개의 판을 이동시킨 뒤 N번째 판을 C로 이동시켜야 한다. 이 부분에서 재귀함수가 사용되는 것이다.

왜냐면 A에서 B로 (1 ~ N - 1)개의 판을 이동시키려면 먼저 N - 1번째 판이 B로 이동해야 하기 때문에 또 A에서 C로 (1 ~ N - 2) 개의 판을 이동시켜야하기 때문이다. 이 과정은 옮겨야 하는 판의 높이가 1이 될 때까지 계속된다. 이게 base line, 재귀의 탈출 조건이 되는거다.

 

아이디어 정리

위의 글이 너무 기니, 간단하게 정리해보겠다.

 

① 맨 아랫판 위에 있는 걸 모두 목적지도 출발지도 아닌 장대로(temp)로 옮긴다  (1 ~ n-1)의 판
② 맨 아랫판을 목적지로 옮긴다 n번째 판
③ temp로 옮겨 놨었던 나머지 탑을 목적지로 옮긴다 (1~n-1)까지의 판

 

여기서 맨 아랫판 위에 있는 나머지 탑을 이동시키는 과정에서 재귀함수가 쓰인다. 판이 한 개 밖에 남지 않을 때까지 계속 위의 탑을 옮기고, 옮기고,,,, 해야하기 때문이다.

 

 

코드 설명

const fs = require('fs');
const N = +fs.readFileSync('/dev/stdin').toString().trim();

let cnt = 0;
let answer =[];

// 어디서 어디로, 높이가 얼마나 되는 탑을 이동시킬건지!
function hanoiTop(from, to, height) {

    //탑의 높이가 1이라면, 맨 아래 원판만 있으므로 바로 옮겨주면 된다.
    if(height === 1) {
        answer.push(`${from} ${to}`);
        cnt++;
        return;
    }

    //탑의 높이가 2 이상인 n이라면, 맨 아래 원판 위에 있는 탑 (1~n-1)을 우선 옮겨야 한다.
    //어디로 옮겨야 하냐, from과 to가 아닌 다른 판으로 이동시켜야 한다.
    // 1 + 2 + 3 = 6이고, 6에서 from과to의 번호를 빼면 나머지 장대의 번호가 나올 것이다.
    const temp = 6 -  from - to;
    hanoiTop(from, temp, height - 1);

    //위에 쌓인 탑을 다 치웠으면, 맨 아래 위치한 원판을 원하는 곳으로 이동시킬 수 있다.
    hanoiTop(from, to, 1);

    //console.log('탑을 가져온다');
    hanoiTop(temp, to, height - 1);
}

hanoiTop(1, 3, N);

console.log(cnt + '\n' +answer.join('\n'));

'알고리즘 > 재귀' 카테고리의 다른 글

백준 1074번 Z (javascript)  (0) 2024.10.14
[백준] 2630번 - 종이의 개수  (1) 2024.10.12
[재귀] 백준 1780번 - 종이의 개수  (0) 2024.10.11
'알고리즘/재귀' 카테고리의 다른 글
  • 백준 1074번 Z (javascript)
  • [백준] 2630번 - 종이의 개수
  • [재귀] 백준 1780번 - 종이의 개수
뜐🐸
뜐🐸
패왕색 패기를 갖춘 뜐입니다~
  • 뜐🐸
    뜐의 개발 로그
    뜐🐸
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 기초 학습
        • HTML
        • CSS
        • JavaScript
        • Version Co..
        • 미니 프로젝트
        • DOM & 웹 AP..
      • CSS 프레임워크
        • Bootstrap
      • React
        • 개념 정리
        • 기초 정리
      • 알고리즘
        • Week 1: 입출..
        • 재귀
        • 백트래킹
      • javascript
      • FastAPI
        • 크롤링 서버 만들기
      • 전역 상태 관리
        • Redux
      • 한 입 리액트 챌린..
      • 영어
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 글쓰기
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    :hover
    자바스크립트 #하노이 탑 #재귀 #백준 # 11729
    오블완
    :focus
    :nth-child(n)
    백준 #코딩테스트 #1074번 #재귀 #알고리즘 # 알고리즘 문제풀이
    inline-block
    티스토리챌린지
    가상 선택자
    :active
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
뜐🐸
[백준 11729번] - 하노이 탑 이동 순서 (javascript)
상단으로

티스토리툴바