이 보드게임은 격자모양 게임판 위에서 말을 움직이는 게임으로, 시작 위치에서 목표 위치까지 최소 몇 번만에 도달할 수 있는지 말하는 게임입니다.
이 게임에서 말의 움직임은 상, 하, 좌, 우 4방향 중 하나를 선택해서 게임판 위의 장애물이나 맨 끝에 부딪힐 때까지 미끄러져 이동하는 것을 한 번의 이동으로 칩니다.
다음은 보드게임판을 나타낸 예시입니다.
...D..R
.D.G...
....D.D
D....D.
..D....
여기서 "."은 빈 공간을, "R"은 로봇의 처음 위치를, "D"는 장애물의 위치를, "G"는 목표지점을 나타냅니다. 위 예시에서는 "R" 위치에서 아래, 왼쪽, 위, 왼쪽, 아래, 오른쪽, 위 순서로 움직이면 7번 만에 "G" 위치에 멈춰 설 수 있으며, 이것이 최소 움직임 중 하나입니다.
게임판의 상태를 나타내는 문자열 배열 board가 주어졌을 때, 말이 목표위치에 도달하는데 최소 몇 번 이동해야 하는지 return 하는 solution함수를 완성하세요. 만약 목표위치에 도달할 수 없다면 -1을 return 해주세요.
기본적인 경로 탐색 문제. 단 이동을 바로 한 칸이 아닌 '장애물을 만나거나 맵 밖에 벗어나기 직전까지' 이동해주면 되므로 그 부분만 신경써서 구현해주면 된다.
init : 초기화 함수. board의 가로세로 크기 N, M을 저장하고 전체를 탐색하며 시작 위치와 도착 위치를 찾아 반환한다.
move : 앞서 말한 이동 함수. 일정 방향으로 x, y를 계속 업데이트하며, 앞서 말한 조건(맵 밖에 나가거나 장애물 D에 도달할 경우)에 부합되면 반복문을 탈출한다. 그리고 그 전의 상태를 반환한다.
bfs : 최소 경로를 찾으므로 bfs로 구현하였다. 큐 자료구조를 이용하여 구현하고, 종료 지점에 도달하면 이동 거리를 반환한다. 탐색이 종료될 때까지 반환값이 없을 경우 도달에 실패한다는 의미이므로 -1을 반환한다.
solution : 메인함수. init으로 start, end를 반환받아 bfs 함수에 전달한다. 그리고 그 결과를 반환한다.
풀이 코드
from collections import deque
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
N, M = 0, 0
def init(board) :
global N, M
N, M = len(board), len(board[0])
for i in range(N) :
for j in range(M) :
if board[i][j] == 'R' :
start = (j, i)
if board[i][j] == 'G' :
end = (j, i)
return start, end
def move(board, x, y, k) :
while -1 < x < M and -1 < y < N and board[y][x] != 'D':
x, y = x + dx[k], y + dy[k]
return x - dx[k], y - dy[k]
def bfs(board, start, end) :
x, y = start
q = deque([(x, y, 0)])
visited = [[float('inf')]*M for _ in range(N)]
visited[y][x] = 0
while q :
x, y, dist = q.popleft()
if (x, y) == end :
return dist
for k in range(4) :
ax, ay = move(board, x, y, k)
if visited[ay][ax] > dist + 1 :
visited[ay][ax] = dist + 1
q.append((ax, ay, dist+1))
return -1
def solution(board):
start, end = init(board)
result = bfs(board, start, end)
return result