from collections import deque
class Node():
def __init__(self, y, x, level=0):
self.x = x
self.y = y
self.level = level
def bfs(start: Node, matrix: list)->int:
visited = [[0 for _ in range(5)] for _ in range(5)]
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
q = deque()
q.append(start)
visited[start.y][start.x] = 1
while len(q) != 0:
now = q.popleft()
# print(f"{now.x} {now.y} {now.level}")
if now != start and matrix[now.y][now.x] == "P":
# print(f"cath! {now.x} {now.y} {now.level}")
return now
for i in range(4):
nx = now.x + dx[i]
ny = now.y + dy[i]
if nx < 0 or ny < 0 or nx >= 5 or ny >= 5:
continue
if matrix[ny][nx] == "X":
continue
if visited[ny][nx] == 1:
continue
# print(f"next! {nx} {ny} {now.level+1}")
q.append(Node(ny, nx, now.level+1))
visited[ny][nx] = 1
# 찾지 못한 경우 -1 반환
return Node(0,0,-1)
def solution(places):
answer = []
# 모든 place에서 검사를 한다.
for place in places:
is_next_place = False
# 한 place 내부의 모든 좌표에서 거리를 계산해본다.
for y in range(len(place)):
is_escape_from_this_spot = False
for x in range(len(place[0])):
if place[y][x] == "P":
node = bfs(Node(y, x), place)
# 한 좌표에서 어느 곳에서도 P를 못 찾은 경우 다음 좌표를 검사한다.
if node.level == -1:
continue
# 한 좌표에서 거리가 2 이하인 P를 찾은 경우 0을 표기하고 다음 place로 넘어간다.
if node.level <= 2:
is_escape_from_this_spot = True
break
if is_escape_from_this_spot:
is_next_place = True
break
if is_next_place:
answer.append(0)
continue
# 모든 좌표를 검사했음에도 거리가 2 이하인 점을 찾지 못했다면 1을 표기하고 다음 place로 넘어간다.
answer.append(1)
return answer
한 좌표에서 어느 곳에서도 다른 P를 못 찾은 경우에느 다음 좌표로 넘어가야 했는데, 이 부분에서 break를 해버렸다. 이를 continue로 바꿔주고 테스트 케이스를 모두 해결할 수 있었다.
벽이 존재하는 상황에서 맨해튼 거리를 구하기 위해선 중간에 벽이 있는지 확인해야 했다. 이런 경우에는 모든 경우를 예측해서 대비해야만 문제를 풀 수 있었기에 휴먼 에러에 취약한 코드가 만들어질 것이라 생각했다. 따라서 보다 더 보편적으로 많은 경우를 처리할 수 있는 bfs를 사용했다.
삼중 for문을 사용했는데 차라리 place 하나를 check 할 수 있는 함수를 따로 만들어서 물리적으로라도 for문의 차원을 낮췄어야 했다. 그렇지 못해서 중간에 flag 변수가 많이 사용되어 읽기 힘든 코드가 되었다.