본문 바로가기
개발/알고리즘

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

by ISA(류) 2021. 9. 28.

# 문제 원문

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

 

제한사항

  • n은 1 이상 1,000 이하입니다.

입출력 예

n / result

4 [1,2,9,3,10,8,4,5,6,7]
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]

 

# 문제 풀이

삼각 달팽이를 만드는 문제로, 비슷한 문제로 숫자 매트리스 만들기(이름 기억안남)을 풀어 본적 있어서 쉬웠다. 삼각형을 이루는 숫자들의 규칙성을 DP방식으로 쪼개서 입력 받은 n의 총 원소 갯수 까지 반복하며 규칙에 맞게 숫자들을 입력하고 문제에서 원하는 방식으로 하나의 배열로 만들어서 반환하면 되는 문제. 사실 이전에는 이런 문제들을 붙잡고는 어떻게 하면 공식 같은걸로 간단히 연산해서 풀어 낼 수 있을까? 같은 고민을 해서 시간을 많이 날렸는데 그런 시행착오 과정에서 많은 고생을 한후에 구현 하는 문제는 예외 케이스를 모두 고려하기 힘드므로 그냥 실제로 해당 요소를 구현하는게 더 빠르다는 것을 느껴서 바로 구현하기로 마음 먹었다. 솔직히 알고리즘 연구를 하는 것도 아닌데 굳이 오버 러닝 할 이유가 없는 것 같다.

내 장점이자 단점이 하나를 붙잡으면 쓰잘데기 없는 것 까지 파고 들어가는건데 이게 이런 단순한 문제풀이에서는 오히려 효율적이지 않다. 그래서 알고리즘이 별로 재미 없는 편 인듯 (매일 하다보니 흥미가 조금 붙긴하지만...)

 

# 솔루션 플로우

1. 입력 받은 n만큼의 빈 2차원 배열을 만든다.

2. 입력 받은 n + (n - 1) + ... + 1, 즉 맥시멈 사이즈를 구한다.

3. 1부터 구해진 맥시멈 사이즈까지 반복하면서 rdx, cdx, direct를 변경해가면서 배열의 요소를 채운다.

4. 구해진 2차원 배열 result를 합쳐서 1차원 배열로 만든다.

5. 구해진 result를 반환한다.

1. 반복문을 활용한 풀이

function solution(n) {
    const result = new Array(n).fill(true).map((_) => []);
    const max = result.reduce((result, _, idx) => result + idx + 1, 0);

    let rdx = 0;
    let cdx = 0;
    let direct = "D";
    for (let int = 1; int <= max; int++) {
        result[rdx][cdx] = int;
        if (direct === "D") {
            if (result[rdx + 1] !== undefined && !result[rdx + 1][cdx]) {
                rdx++;
            } else {
                direct = "R";
                cdx++;
            }

        } else if (direct === "R") {
            if (cdx < rdx && !result[rdx][cdx + 1]) {
                cdx++;
            } else {
                if (cdx - 1 >= 0) cdx--;
                if (rdx - 1 >= 0) rdx--;
                direct = "U";
            }
        } else if (direct === "U") {
            if (!result[rdx - 1][cdx - 1]) {
                rdx--;
                cdx--;
            } else {
                rdx++;
                direct = "D";
            }
        }
    }

    return result.reduce((result, current) => {
        current.forEach((num) => result.push(num));
        return result;
    }, []);
}
반응형