Algorithm

삼각 달팽이

GREEN.1229 2021. 6. 3. 20:15

아래 문제는 프로그래머스에서 제공하는 월간 코드 챌린지 시즌1 > 삼각 달팽이의 문제입니다🧑🏻‍💻

문제 제시

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

제한사항

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

입출력 예

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]

문제 해결

import Foundation

enum Move {
    case down
    case right
    case up
}

func solution(_ n:Int) -> [Int] {
    var result = [[Int]](repeating: [Int](repeating: 0, count: n), count: n)
    var max = n
    var move: Move = Move.down
    var num = 1
    var row = -1
    var column = 0
    
    while 0 < max {
        switch move {
        case .down:
            for _ in 0..<max {
                row += 1
                result[row][column] = num
                num += 1
            }
            max -= 1
            move = .right
            
        case .up:
            for _ in 0..<max {
                row -= 1
                result[row][column] = num
                num += 1
            }
            column -= max
            max -= 1
            move = .down
            
        case .right:
            for _ in 0..<max {
                column += 1
                result[row][column] = num
                num += 1
            }
            max -= 1
            move = .up
            
        default:
            break
        }
    }
    return result.flatMap{ $0 }.filter{ $0 != 0}
}

사용된 개념

 - 열거형

 - 스위치문

 - 2차원 배열

 - 반복문

 - 고차함수 (flatMap, filter)

문제 뒷담화

해당 문제는 생각을 많이 요했다. 레벨2라고 하기엔 조금 시간이 많이 걸렸다.

우선 접근은 n의 값이 주어지면 총 n번 아래,오른쪽,위 이런식으로 해당 횟수만큼 돈다. 그걸 잘 생각해봤다.

우선 아래,오른쪽,위에 대한 열거형 타입을 선언했다.

그리고 총 nXn의 2차원 배열을 만들어주었다.

처음 시작 숫자는 1부터 시작하고 행과 열을 row와 column 변수로 선언해주었다.

그리고 switch문을 통해 각 이동 방향에 따라 조건문을 돌려준다.

아래로 이동할때는 열은 가만히 있고 행의 수만 1씩 증가하면서 숫자를 넣어준다.

다 돌면 오른쪽으로 이동하기전 n을 변수로준 max값을 1 감소시키고 오른쪽 케이스를 타도록 해준다.

max값을 1 감소시키는 이유는 위에서 말했듯이 n번을 돌기에 1번 아래로 다 이동했다는 뜻이다. 이제 n-1번 조작 방향을 거치면된다.

그리고 오른쪽 이동 시에는 행은 가만히두고 열만 하나씩 증가시키며 값을 넣어준다.

마찬가지로 끝나면 max값은 1 감소시키고 위 조작 케이스를 타도록 해준다.

위 이동시에는 행을 1씩 감소시키며 열은 그대로 두고 값을 넣어준다.

그리고 조건이 끝나면 열에서 현재 max값을 빼준것을 열로 지정해준다. 그래야 그 열부터 아래로 거치며 시작할 수 있다.

이렇게 조건을 나눠 돈뒤 배열이 만약 n이 4가 주어진다면 아래와 같이 2차원 배열에 담길것이다.

이걸 1차원 배열로 바꿔주기 위해 2차원 배열을 1차원 배열로 바꿔주는 flatMap 고차함수를 사용한다.

그럼 위와같이 1차원 배열로 완성이된다. 0의 수는 nXn 배열을 바꿔준거라 들어간것으로 0을 제외시켜줘야한다.

0을 제외시키기 위해 filter로 0이 아닌 수만 반환되도록 고차함수를 사용한다.

그러면 최종적으로 아래와 같이 정상적으로 희망 결과값이 반환된다.