티스토리 뷰

반응형

 

 

 

안녕하세요. 저는 개발자 멍구입니다!
오늘은 저번 프로그래머스 코드챌린지 시즌1 문제, 두개뽑아서더하기에 이어 두번째문제 삼각달팽이를 풀어보겠습니다. 먼저 설명을 보도록 하겠습니다. 🤗

 

 


코드챌린지 시즌1 코딩테스트 두번째 문제
삼각달팽이 문제 설명

삼각달팽이는 정수 n이 값으로 주어졌을때, 밑변의 길이와 높이가 n인 삼각형에서 맨 윗 꼭짓점부터 반시계 방향으로 달팽이 채우기를 한 후, 첫 행 ~ 마지막 행짜기 모두 순서대로 값을 합친 1차원 배열을 답으로 제출하는 문제입니다. 

예를들면, n=4인 맨좌측의 삼각형은 달팽이 채우기결과가 위와 같습니다. 이를 순서대로 나열해서 1차월배열로 합치면 그 값은 1행 ~ 4행까지 차례대로 [1, 2, 9, 3, 10, 8, 4, 5, 6, 7] 이 됩니다. 

해당문제는 문제에서 제시한 대로 달팽이채우기를 한 뒤, 그대로 1차원 배열을 반환해주면 되는데요. 규칙성만 찾는다면 쉽게 풀 수 있는 배열 구현문제입니다. 

이어서 제한사항과 입/출력 예시를 보겠습니다.

 

 

앞서 설명했던 대로, n이 4일 경우, [1, 2, 9, 3, 10, 8, 4, 5, 6, 7] 의 출력값이 나오면 됩니다. n은 1이상 1,000이하 범위의 값이 들어옵니다. 

바로 swift언어로 해당 문제, 삼각달팽이를 풀어보겠습니다. 

 

 


코드챌린지 시즌1 코딩테스트 두번째 문제
삼각달팽이 문제 설명

먼저 dx, dy 배열을 선언하는데요. 이는 달팽이채우기를 할때 채우는 방향을 설정하는데에 사용합니다.
그림과 함께 방향을 어떻게 정의했는지 설명해보겠습니다.

 

 

- dx[0], dy[0] : 좌하단 방향으로 달팽이채우기
- dx[1], dy[1] : 우 방향으로 달팽이 채우기
- dx[2], dy[2] : 좌상단 방향으로 달팽이채우기

로 달팽이채우기를 하는 방향을 정의합니다. 전역변수가 아진 solution 메서드 내의 지역변수로 선언해서 풀어도 문제는 없을 것 같습니다. 
이제 본 메서드, solution을 구현해보겠습니다.

 

 

n을 입력받는 solution 메서드 초입부입니다. 

- dir : 앞서 정의했던 dx, dy의 인덱스 역할을 합니다.
- row, col : 달팽이 채우기를 할때의 그리는 위치를 확인하기 위한 행 / 열을 담당합니다.
- num : 1부터 2, 3, 4, 5, 6 식으로 달팽이채우기를 할때, 넘버링할 숫자값입니다. 
- G : 달팽이 채우기를 할 2차원 배열입니다. 

16 ~ 18행) 우리는 이제 이차원배열 G에 달팽이 채우기를 해야하는데요. 그 전에 해당 이차원배열 G에 삼각형 공간을 만들어둡니다. 가령 첫행은 1개, 두번째 행은 2개, ... n번째 행은 n개의 공간이 있겠죠? 그에 맞게 삼각형 공간을 만들어줍니다. 

이제 달팽이 채우기를 하겠습니다. (0, 0) 인덱스에 1이 들어갈테고 달팽이채우기로 2, 3, 4, 5... 의 숫자가 차례대로 들어갈 겁니다. 

 

 

20 ~ 21행) n부터 값이 하나하나 감소하는 반복문을 정의했습니다. 먼저 달팽이채우기의 규칙성을 먼저 알아보아야 할 것 같습니다. 

 

달팽이채우기의 첫 방향인 좌하단 방향으로 채워질 숫자는 1 ~ 6으로 총 6개입니다. 이후 우향으로 채울때 5칸, 좌상향 4칸 ... 이렇게 5, 4, 3, 2, 1로 채워야할 칸의 갯수가 1씩 감소합니다. 이런 규칙성을 활용하는 방향으로 코드를 작성해보는 것입니다. 

그렇게 하면, n, n-1, n-2 ... 1의 순서로 값을 순회하면서 방향 전황 및 숫자채우리를 진행하게 되겠죠?

swift에서 n ... 1 과 같이 역순으로 범위를 지정해서 값을 순회하면 런타임에러가 발생합니다. 이때는 (1 ... n).reversed() 를 활용하면 역순으로 값을 순회할 수 있습니다.

 

 

 

22 ~ 27행) 현재 달팽이채우기 방향에 맞게 숫자를 채우는 과정입니다. 맨 처음에는 좌하단 방향으로 달팽이 채우기를 하겠죠? 

28 ~ 34행) 한 라인의 달팽이채우기를 끝낸 뒤에 꼭짓점 숫자까지 채운 후, 방향을 전환하는 과정입니다. 방향전환은 (dir + 1) % 3로 다음 채워야할 방향을 전환하고, 그에 맞는 방향을 row, col에 설정하고 있습니다. 이를 반복하면 결과적으로 달팽이를 완벽하게 채울 수 있게 됩니다. 

$0는 앞서 맨 처음에 선언한 반복문의 값을 의미합니다. forEach 클로져의 경우 한개의 배열 컬렉션 내의 값을 순회하게 되는 그 순회하는 값을 $0로 표현할 수 있습니다. 그 외로 forEach { value in / forEach { _ in 등의 방식으로 $0대신 라벨을 지정해서 사용할 수도 있습니다. 

 

 

 

달팽이채우기를 완료했다면, 마지막 값을 출력해야겠죠? 마지막 값은 달팽이채우기가 된 배열을 순서대로 합친 1차원 배열을 반환하는 것입니다. 이는 reduce를 통해서 한줄로 연산을 할 수 있는데요. reduce는 초기값을 지정해서 접근한 배열을 순회 및 특정 연산을 수행하고 그에따른 누적결과를 얻을 수 있습니다. 

36행) G.reduce는 이차원배열, G에 있는 1차원 배열들을 순차적으로 순회하면서 초기값, [Int]()배열에 누적시킵니다. 결과적으로 [Int]타입의 1차월 배열을 반환하게 됩니다. 

그렇게 달팽이채우기 및 reduce를 통한 결과값 반환을 수행했습니다. 그 결과는 아래와 같습니다. 

 

 

 

 

 


지금까지 프로그래머스 코드챌린지 시즌1 알고리즘문제 중 하나인 삼각달팽이를 swift언어로 풀어보았습니다.
해당문제는 규칙성을 파악하고 규칙성에 맞게 배열을 다루는 문제였습니다. 

그 과정에서 저는 반복문 수행에 reversed(), forEach를 사용하고, 결과값 반환에 reduce를 활용해봤습니다. 물론, 고차함수 없이도 해당 문제를 충분히 풀 수 있으며, 오히려 더 빠른 결과를 얻을 수도 있습니다.

하지만 그 성능 차이가 크지 않기 때문에, 시간이 부족하거나, 보다 빨리 문제를 해결하기 위해서는 reduce / forEach 등의 고차함수 활용방법도 숙지하시는게 큰 도움이 되실 겁니다. 😄

 

 

반응형
댓글
반응형
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함