https://programmers.co.kr/learn/courses/30/lessons/68645
세가지 방향, 2차원배열 사용
문제설명
정수 n이 매개변수로 주어집니다. 다음 그림과 같이 밑변의 길이와 높이가 n인 삼각형에서 맨 위 꼭짓점부터 반시계 방향으로 달팽이 채우기를 진행한 후, 첫 행부터 마지막 행까지 모두 순서대로 합친 새로운 배열을 return 하도록 solution 함수를 완성해주세요.
입출력 예
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]
솔루션
이 문제에서는 3가지 방향이 존재한다. 아래 > 오른쪽 > 위
방향에 따라 다음 좌표를 반환하는 get_next 함수를 작성한다.
check_turn이라는 방향을 바꿔야하는지 여부를 반환하는 함수를 만든다.
1. 행이 범위 밖인경우
2. 열이 범위 밖인 경우
3. 숫자가 이미 채워진 경우
방향을 바꿔야 하면 방향을 바꿔주고,
현재 위치를 다음 위치로 바꿔준다.
# snail
[[1],
[2, 12],
[3, 13, 11],
[4, 14, 15, 10],
[5, 6, 7, 8, 9]]
코드
# 파이썬
import itertools
def get_next(cur_y, cur_x, cur_d):
DELTAS = {'U': (-1, -1), 'D': (1, 0), 'R': (0, 1)}
dy, dx = DELTAS[cur_d][0], DELTAS[cur_d][1]
nxt_y, nxt_x = cur_y + dy, cur_x + dx
return nxt_y, nxt_x
def check_turn(nxt_y, nxt_x, n, snail):
return nxt_y < 0 or nxt_y >= n or nxt_x > nxt_y or snail[nxt_y][nxt_x] != 0
def solution(n):
NEXT = {'U': 'D', 'D': 'R', 'R': 'U'}
N = sum(range(1, n+1))
snail = [[0] * i for i in range(1, n+1)]
cur_y, cur_x, cur_d = 0, 0, 'D'
for num in range(1, N+1):
snail[cur_y][cur_x] = num
if check_turn(*get_next(cur_y, cur_x, cur_d), n, snail):
cur_d = NEXT[cur_d]
cur_y, cur_x = get_next(cur_y, cur_x, cur_d)
return list(itertools.chain(*snail))
팁
2차배열을 1차배열로 만드는데 itertools.chain를 사용하면 편하다.
또, 방향과 다음방향을 딕셔너리로 저장하고 로직을 함수로 쪼개서 작성하면 간단하다.
많이 배웠습니다 멋진 풀이 감사합니다!