코드
def solution(park, routes):
# 시작점('S') 찾기
x, y = 0, 0
for row in range(len(park)):
for col in range(len(park[row])):
if park[row][col] == 'S': # 시작 지점 'S'
x, y = row, col
# 이동 방향 정의
op = {'N':(-1, 0), 'S':(1, 0), 'W':(0, -1), 'E':(0, 1)}
# 이동
for i in routes:
dx, dy = op[i.split()[0]] # op에서 해당 방향에 맞는 이동 값 dx, dy로 가져오기
n = int(i.split()[1]) # 이동 횟수
xx, yy = x, y # n번의 이동 동안 변하는 좌표 저장 xx, yy
canmove = True # 이동할 수 있는 route인지 확인
# n번 이동해보기
for _ in range(n):
nx = xx + dx # 이동한 위치
ny = yy + dy # 이동한 위치
# 공원 안에 있고, 장애물이 아니면 이동 가능(True)
if 0 <= nx <= len(park)-1 and 0 <= ny <= len(park[0])-1 and park[nx][ny] != 'X':
canmove = True
xx, yy = nx, ny
else: # 공원을 벗어낫거나, 장애물이면 이동 불가(False)
canmove = False
break
if canmove: # 이동이 가능하면 위치 반영해주기
x, y = nx, ny
return [x, y]
전체적인 흐름은 다음과 같이 세 단계로 구분할 수 있다.
1. 시작점 찾기
2. 이동 방향 정의
3. routes에 따라 이동해 보기
- 3-1. 이동 가능한 위치인지 확인
- 3-2. 위치 반영해 주기
1, 2 단계는 쉽게 코드를 작성할 수 있어, 3단계에 대해서만 자세하게 풀이를 남겨보겠다.
먼저, routes의 개수만큼 반복하는 동안 필요한 변수들을 다음과 같다.
dx, dy = op[i.split()[0]] # op에서 해당 방향에 맞는 이동 값 dx, dy로 가져오기
n = int(i.split()[1]) # 이동 횟수
xx, yy = x, y # n번의 이동 동안 변하는 좌표 저장 xx, yy
canmove = True # 이동할 수 있는 route인지 확인
routes의 요소(i)는 공백을 기준으로 앞에는 이동 방향(N, S, E, W)이, 뒤에는 이동 횟수(1 ≤ n ≤ 9)가 문자열로 나타나있다.
그러므로 split 한 [0]번 요소인 이동 방향을 정의해 둔 op에서 찾아 가져온다.
딕셔너리 op에는 value들이 (0, 1) 형식으로 저장되어 있기 때문에 dx, dy = op[i.split()[0]]을 하면 dx에는 0이 dy에는 1이 저장된다.
그런 다음 [1]번 요소인 이동 횟수(이동 칸수)를 정수형으로 저장한다.
n칸 이동을 하며 이동한 좌표가 장애물은 없는지, 공원 범위를 벗어나지는 않는지 확인을 해주는 과정이 필요하다.
가능한 이동 좌표를 xx, yy 변수에 저장하고, 가능/불가능 여부를 boolean 타입으로 canmove에 저장한다.
그럼 이제 n칸 이동을 실시한다.
# n번 이동해보기
for _ in range(n):
# 이동한 위치
nx = xx + dx
ny = yy + dy
# 공원 안에 있고, 장애물이 아니면 이동 가능(True)
if 0 <= nx <= len(park)-1 and 0 <= ny <= len(park[0])-1 and park[nx][ny] != 'X':
canmove = True
xx, yy = nx, ny
else: # 공원을 벗어낫거나, 장애물이면 이동 불가(False)
canmove = False
break
# 이동이 가능하면 위치 반영해주기
if canmove:
x, y = nx, ny
nx, ny는 한 번 이동했을 때 바뀌는 좌표이다.
이 좌표가 공원 범위 안에 있는지(0 <= nx <= len(park)-1 and 0 <= ny <= len(park[0])-1), 장애물이 아닌지(park[nx][ny] != 'X') 확인한다.
공원 안에 있고, 장애물이 아니라면 canmove=True로 바꿔주고, xx, yy에 nx, ny를 저장해 준다.
하지만, 공원의 범위를 벗어 낫거나, 장애물이라면 canmove=False로 바꿔주고 for문을 break 한다.
예를 들어, 2칸을 이동할 때 1칸 이동은 불가능한 위치이고, 2칸 이동은 가능한 위치라고 해보자.
그럼 이 2칸 이동이라는 route는 가능한 이동인가?
1칸 이동부터 길이 막혔으니 애초에 2칸은 이동을 할 수가 없다. 따라서 불가능한 이동이다.
그러므로 첫 번째 이동이 불가능하면 두 번째 이동은 확인하지 않고 canmove=False로 표시하고 다음 route를 확인한다.
해당 route의 명령인 n칸 이동 for문이 종료되면 canmove의 여부를 확인한다.
True이면 이동이 가능한 route이므로 x, y에 이동한 위치(nx, ny)를 반영해 준다.
모든 routes에 대해 위 과정을 반복한 뒤 x, y를 리턴해주면 최종 위치를 구할 수 있다.