P 기준 맨하탄 거리 2 이하에서 다른 P가 있을 때 거리두기를 지키지 않은 상황이다. 맨하탄 거리가 1이라면 파티션을 확인할 필요 없이 거리두기를 어긴 상황. 맨하탄 거리가 2일 때 파티션 X를 확인해 조건에 따라 거리두기를 지켰는지를 확인하자.
def solution(places):
result = []
offset = [[-2, 0], [-1, -1], [-1, 0], [-1, 1], [0, -2], [0, -1], [0, 1], [0, 2], [1, -1], [1, 0], [1, 1], [2, 0]]
for place in places:
people = []
partitions = []
i = 0
for line in place:
j = 0
for digit in line:
if digit == 'P':
people.append([i, j])
elif digit == 'X':
partitions.append([i, j])
j += 1
i += 1
distancing = True
for person in people:
x, y = person
for i, j in offset:
if abs(i) + abs(j) == 1 and [x+i, y+j] in people:
distancing = False
break
if [x+i, y+j] in people:
if i == 0:
if [x, y+1] in partitions or [x, y-1] in partitions: continue
else:
distancing = False
break
elif j == 0:
if [x+1, y] in partitions or [x-1, y] in partitions: continue
else:
distancing = False
break
else:
if i == 1 and j == -1:
if [x+1, y] in partitions and [x, y-1] in partitions: continue
else:
distancing = False
break
elif i == 1 and j == 1:
if [x, y+1] in partitions and [x+1, y] in partitions: continue
else:
distancing = False
break
elif i == -1 and j == 1:
if [x-1, y] in partitions and [x, y+1] in partitions: continue
else:
distancing = False
break
elif i == -1 and j == -1:
if [x-1, y] in partitions and [x, y-1] in partitions: continue
else:
distancing = False
break
if not distancing:
break
if distancing: result.append(1)
else: result.append(0)
return result
P를 기준으로 맨하탄 거리 2 이하가 되는 좌표를 구하기 위한 offset를 만들어두었고, P의 좌표값에 이를 더해 이 위치에 다른 P가 있는지를 체크한다. 이때 맨하탄 거리가 1이라면 곧바로 거리두기를 어겼으므로 distancing이 False가 되고 break. 2일 때에는 파티션 X의 좌표값을 확인해 적절하게 다른 P 사이를 가로막고 있는지 확인한다. 이때 직선/대각선 케이스를 따로 분류해 파티션 위치를 확인했다. 모든 경우에 P 인근(즉 맨하탄 거리 2 이하)에 다른 P가 없다면 이 대기실에서는 거리두기가 모두 지켜킨 상황이다.