[C++] 연습 문제 : 달팽이

👻 연습 문제 : 달팽이

달팽이 모양처럼 빙글빙글 돌아가면서 숫자를 출력해보자.

  • 답안 예시

Alt Text
Alt Text

각각 5와 9를 입력받았을 때의 결과값이고 오른쪽, 아래, 왼쪽, 위 순으로 돌아가며 숫자가 나오는 것을 확인할 수 있다.


🌱 코드 분석

  • 보드의 가로세로 크기를 최대 100으로 정한다.
  • 입력 받은 수만큼 보드의 크기를 설정한다.
  • 정해진 방향대로 숫자를 채우다가 더 이상 갈 수 없으면 방향을 바꿔주며 반복한다.

가장 중요한 부분은 세 번째이다. 해당 부분을 따로 함수로 빼서 만들었다.

  • 방향 설정
    방향의 정보를 열거형으로 정해주었다.
    enum DIR {
      RIGHT = 0,
      DOWN = 1,
      LEFT = 2,
      UP = 3
    };
    
  • 보드 세팅
void SetBoard() {
    int dir = RIGHT;
    int num = 1;
    int y = 0;
    int x = 0;

    while (true) {
        board[y][x] = num;

        if (num == N * N) break;

        int ny;
        int nx;
        switch (dir)
        {
        case RIGHT:
            ny = y;
            nx = x + 1;
            break;
        case DOWN:
            ny = y + 1;
            nx = x;
            break;
        case LEFT:
            ny = y;
            nx = x - 1;
            break;
        case UP:
            ny = y - 1;
            nx = x;
            break;
        }

        // 이동할 수 있는지 체크
        // 이동하지 못하면 방향 전환
        if (ny < 0 || ny >= N || nx < 0 || nx >= N || board[ny][nx] != 0) {
            switch (dir) 
            {
            case RIGHT:
                dir = DOWN;
                break;
            case DOWN:
                dir = LEFT;
                break;
            case LEFT:
                dir = UP;
                break;
            case UP:
                dir = RIGHT;
                break;
            }
            continue;
        }

        y = ny;
        x = nx;
        num++;
    }
 
}

우선 무한 반복을 돌리면서 보드에 값을 채워준다. 보드에 값을 세팅한 후 다음으로 갈 곳의 인덱스를 먼저 찾는다. 방향에 따라 정할 수 있다.

그렇게 정한 다음 인덱스 nynx에 해당하는 곳이 일정 범위(0 ≤ ny, nx < N)를 넘어서면 방향만 바꾸고 다시 다음 인덱스를 찾도록 정하였다.

위의 코드는 다음과 같이 줄일 수 있다.

void SetBoard() {
    int dir = RIGHT;
    int num = 1;
    int y = 0;
    int x = 0;

    int dy[4] = { 0, 1, 0, -1 };
    int dx[4] = { 1, 0, -1, 0 };

    while (true) {
        board[y][x] = num;

        if (num == N * N) break;

        int ny = y + dy[dir];
        int nx = x + dx[dir];

        // 이동할 수 있는지 체크
        // 이동하지 못하면 방향 전환
        if (ny < 0 || ny >= N || nx < 0 || nx >= N || board[ny][nx] != 0) {
            dir = (dir + 1) % 4;
            continue;
        }

        y = ny;
        x = nx;
        num++;
    }
 
}

두 개의 switch문을 요약하였다. 우선 방향 따라 다음 인덱스를 정하는 부분을, 방향 정보만 담은 배열을 생성해 더해주었다. 그리고 해당 범위를 벗어났을 때 방향을 전환해주는 부분도 열거형을 순환하는 코드로 바꿔주었다.


👻 글을 마치며

우선 나는 1시간 넘게 고민했지만 결국 만들진 못했다..😔 그래도 고민하면서 이런 저런 방법도 찾아보고 정답에 거의 근접할 정도로는 만들어봤으니 만족한다. 문제는 모두 달라도 자세히 보면 다 비슷한 알고리즘을 의미하고 있기 때문에 매일 연습하다보면 자연스레 길이 보이지 않을까 생각한다. 그래도 풀 수 있었으면 좋았을텐데.. 아쉽긴 하다 😭 복습 열심히 해야겠다.


소스코드 보러가기


출처
인프런 Rookies님 강의

Categories:

Updated:

Leave a comment