본문 바로가기
Algorithme/Programmers

[프로그래머스] 삼각 달팽이 Java

by 케로베로 2020. 10. 8.

programmers.co.kr/learn/courses/30/lessons/68645

 

코딩테스트 연습 - 삼각 달팽이

5 [1,2,12,3,13,11,4,14,15,10,5,6,7,8,9] 6 [1,2,15,3,16,14,4,17,21,13,5,18,19,20,12,6,7,8,9,10,11]

programmers.co.kr

 

문제 요약

정수 n이 매개변수로 주어집니다. 다음 그림과 같이 밑변의 길이와 높이가 n인 삼각형에서 맨 위 꼭짓점부터 반시계 방향으로 달팽이 채우기를 진행한 후, 첫 행부터 마지막 행까지 모두 순서대로 합친 새로운 배열을 return 하도록 solution 함수를 완성해주세요.

 

문제 풀이

 규칙을 찾기 위해서 n이 1일 때부터 그림을 하나 씩 그려보았다. 처음에는 보이지 않았지만 다음 인덱스로 이동하는 과정에서 규칙을 찾아냈고 코드로 옮겨서 풀어보았다

 

규칙은 아래와 같다

  • 인덱스의 이동방향은 좌측 하단 이동, 우측 이동, 좌측 상단 이동 세가지가 있다.
  • 맨 처음에는 인덱스 0에서 시작해서 좌측하단 이동을 n - 1번 시행한다. (0 단계)
  • 그 후로는 우측 이동, 좌측 상단 이동, 좌측 하단 이동을 반복하는데 처음에는 한 종류의 이동이 n - 1번 반복되고 이동의 종류가 바뀔 때에는 이동 횟수가 1씩 감소한다. (1단계 ~ (n-1)단계)
  • ex) n = 3일 때 : 좌측 하단 이동 2회 / 우측 이동 2회 / 좌측 상단 이동 1회
  • ex) n = 4일 때 : 좌측 하단 이동 3회 / 우측 이동 3회 / 좌측 상단 이동 2회 / 좌측 하단 이동 1회
  • 마지막으로 위치해 있는 인덱스에 마지막 값을 찍으면 answer 배열 완성
  • 참고로 가장 위의 층을 1층으로 보고 가장 아래 층을 n층으로 봤을 때 좌측 하단 이동 시 인덱스는 (인덱스 + 현재 층)이 되고, 우측 이동 시 인덱스는 (인덱스 + 1)이 되며, 좌측 상단 이동 시 인덱스는 (인덱스 - 현재 층)으로 변한다.

문제가 그리 어렵지는 않았지만 규칙을 찾는데서 애를 좀 먹었다. 아직 문제풀이 실력이 많이 부족함을 느꼈다.

나의 코드

public class 삼각_달팽이 {
    public int[] solution(int n) {
        int triangularNumber = getTriangularNumber(n);  //  삼각수 변수
        int[] answer = new int[triangularNumber];   //  삼각수 배열

        int nowIdx = 0; //  현재 배열 인덱스
        int nowNum = 1; //  현재 삽입할 값
        int nowFloor = 1;//  현재 층

        /* 0 단계 */
        for (int i = 0; i < n - 1; ++i) {
            answer[nowIdx] = nowNum++;
            nowIdx += nowFloor++;
        }

        /* n 단계 */
        int step = 1;   //  현재 단계
        while (step < n) {
            for (int i = 0; i < (n - step); ++i) {
                answer[nowIdx] = nowNum++;
                if (step % 3 == 1)
                    nowIdx++;
                else if (step % 3 == 2)
                    nowIdx -= nowFloor--;
                else
                    nowIdx += nowFloor++;
            }
            step++;
        }

        //마지막 인덱스 값 찍기
        answer[nowIdx] = nowNum;

        return answer;
    }

    /* 삼각수 구하기 함수 */
    public int getTriangularNumber(int n) {
        int result = 0;
        for (int i = 1; i <= n; ++i)
            result += i;
        return result;
    }