코딩테스트 연습 - 거리두기 확인하기
[["POOOP", "OXXOX", "OPXPX", "OOXOX", "POXXP"], ["POOPX", "OXPXP", "PXXXO", "OXXXO", "OOOPP"], ["PXOPX", "OXOXP", "OXPOX", "OXXOP", "PXPOX"], ["OOOXX", "XOOOX", "OOOXX", "OXOOX", "OOOOO"], ["PXPXP", "XPXPX", "PXPXP", "XPXPX", "PXPXP"]] [1, 0, 1, 1, 1]
programmers.co.kr
해결 과정
문제를 이해하고 그대로 풀어나가면 되는 구현 문제. 다만, 다중 for 문을 빠져나가야 하는 코드 작성 시, flag를 통해 해결했는데 indent를 잘못 맞춰서 해매기도 했고, distance를 구할 때, 정수/실수를 구분하지 않아서 처음 부터 찬찬히 다시 보고 해결했던 문제.
나의 풀이
import math
def distance(x1, y1, x2, y2):
return math.sqrt(((x2 - x1)**2) + ((y2 - y1)**2))
def m_distance(x1, y1, x2, y2):
return abs(x1 - x2) + abs(y1 - y2)
def solution(places):
answer = []
flag = False
coordinates = []
for i in range(5):
for j in range(5):
coordinates.append((i, j))
for index, place in enumerate(places):
for row_index, row in enumerate(place):
for col_index, col in enumerate(row):
if col == "P":
# TODO: col과 거리 2 이하인 것 중 P들 찾기
candidates = [] # (1, 2) # (row_index, col_index)
for i, j in coordinates:
if m_distance(i, j, row_index, col_index) <= 2:
if row_index == i and col_index == j:
continue
candidates.append((i, j))
for a, b in candidates:
if place[a][b] == "P":
dis = distance(a, b, row_index, col_index)
if dis == 1.0:
answer.append(0)
# 처음 for문으로 가도록 처리
flag = True
break
elif dis == 2.0:
# 가운데가 X 인지 확인
if place[(a + row_index) // 2][(b + col_index) // 2] != "X":
answer.append(0)
flag = True
break
elif dis == math.sqrt(2):
# X로 잘 둘러쌓여 있는지 확인
if place[a][col_index] == "O" or place[row_index][b] == "O":
answer.append(0)
flag = True
break
if (flag):
break
if (flag):
flag = False
break
else:
answer.append(1)
return answer
다른 풀이
- 가능한 케이스를 고려해서 if 문으로 풀어낸 풀이
- 왼쪽 -> 오른쪽, 위 -> 아래 방향으로 탐색하기 때문에, 이전에 이미 봤던 경우는 탐색하지 않는 코드이기도 함.
내 풀이의 경우는 candidates를 찾는 과정에서 이미 봤던 경우도 재탐색하게 되는데, 이런 부분에서 효율성을 줄일 수 있을 듯 함.
def check(place):
for irow, row in enumerate(place):
for icol, cell in enumerate(row):
if cell != 'P':
continue
if irow != 4 and place[irow + 1][icol] == 'P':
return 0
if icol != 4 and place[irow][icol + 1] == 'P':
return 0
if irow < 3 and place[irow + 2][icol] == 'P' and place[irow + 1][icol] != 'X':
return 0
if icol < 3 and place[irow][icol + 2] == 'P' and place[irow][icol + 1] != 'X':
return 0
if irow != 4 and icol != 4 and place[irow + 1][icol + 1] == 'P' and (place[irow + 1][icol] != 'X' or place[irow][icol + 1] != 'X'):
return 0
if irow != 4 and icol != 0 and place[irow + 1][icol - 1] == 'P' and (place[irow + 1][icol] != 'X' or place[irow][icol - 1] != 'X'):
return 0
return 1
def solution(places):
return [check(place) for place in places]
IDEA
다중 for 문 빠져나가기
python은 C언어의 lable, goto 같은게 없다. 따라서 flag를 두고 다중 for 문을 빠져나가는 방식을 택했다. 다만, python의 indent를 제대로 맞췄는지 잘 확인해야 한다.
for - enumerate
이 문제에서 유용하게 사용했던 for - enumerate.
'Coding Test > 문제 풀이' 카테고리의 다른 글
[문제 풀이] 더 맵게 (0) | 2022.03.02 |
---|---|
[문제 풀이] 수식 최대화 (0) | 2022.02.24 |
[문제 풀이] 큰 수 만들기 (0) | 2022.02.17 |
[문제 풀이] 체육복 (0) | 2022.02.16 |
[문제 풀이] 순위 검색 (0) | 2022.02.09 |
코딩테스트 연습 - 거리두기 확인하기
[["POOOP", "OXXOX", "OPXPX", "OOXOX", "POXXP"], ["POOPX", "OXPXP", "PXXXO", "OXXXO", "OOOPP"], ["PXOPX", "OXOXP", "OXPOX", "OXXOP", "PXPOX"], ["OOOXX", "XOOOX", "OOOXX", "OXOOX", "OOOOO"], ["PXPXP", "XPXPX", "PXPXP", "XPXPX", "PXPXP"]] [1, 0, 1, 1, 1]
programmers.co.kr
해결 과정
문제를 이해하고 그대로 풀어나가면 되는 구현 문제. 다만, 다중 for 문을 빠져나가야 하는 코드 작성 시, flag를 통해 해결했는데 indent를 잘못 맞춰서 해매기도 했고, distance를 구할 때, 정수/실수를 구분하지 않아서 처음 부터 찬찬히 다시 보고 해결했던 문제.
나의 풀이
import math
def distance(x1, y1, x2, y2):
return math.sqrt(((x2 - x1)**2) + ((y2 - y1)**2))
def m_distance(x1, y1, x2, y2):
return abs(x1 - x2) + abs(y1 - y2)
def solution(places):
answer = []
flag = False
coordinates = []
for i in range(5):
for j in range(5):
coordinates.append((i, j))
for index, place in enumerate(places):
for row_index, row in enumerate(place):
for col_index, col in enumerate(row):
if col == "P":
# TODO: col과 거리 2 이하인 것 중 P들 찾기
candidates = [] # (1, 2) # (row_index, col_index)
for i, j in coordinates:
if m_distance(i, j, row_index, col_index) <= 2:
if row_index == i and col_index == j:
continue
candidates.append((i, j))
for a, b in candidates:
if place[a][b] == "P":
dis = distance(a, b, row_index, col_index)
if dis == 1.0:
answer.append(0)
# 처음 for문으로 가도록 처리
flag = True
break
elif dis == 2.0:
# 가운데가 X 인지 확인
if place[(a + row_index) // 2][(b + col_index) // 2] != "X":
answer.append(0)
flag = True
break
elif dis == math.sqrt(2):
# X로 잘 둘러쌓여 있는지 확인
if place[a][col_index] == "O" or place[row_index][b] == "O":
answer.append(0)
flag = True
break
if (flag):
break
if (flag):
flag = False
break
else:
answer.append(1)
return answer
다른 풀이
- 가능한 케이스를 고려해서 if 문으로 풀어낸 풀이
- 왼쪽 -> 오른쪽, 위 -> 아래 방향으로 탐색하기 때문에, 이전에 이미 봤던 경우는 탐색하지 않는 코드이기도 함.
내 풀이의 경우는 candidates를 찾는 과정에서 이미 봤던 경우도 재탐색하게 되는데, 이런 부분에서 효율성을 줄일 수 있을 듯 함.
def check(place):
for irow, row in enumerate(place):
for icol, cell in enumerate(row):
if cell != 'P':
continue
if irow != 4 and place[irow + 1][icol] == 'P':
return 0
if icol != 4 and place[irow][icol + 1] == 'P':
return 0
if irow < 3 and place[irow + 2][icol] == 'P' and place[irow + 1][icol] != 'X':
return 0
if icol < 3 and place[irow][icol + 2] == 'P' and place[irow][icol + 1] != 'X':
return 0
if irow != 4 and icol != 4 and place[irow + 1][icol + 1] == 'P' and (place[irow + 1][icol] != 'X' or place[irow][icol + 1] != 'X'):
return 0
if irow != 4 and icol != 0 and place[irow + 1][icol - 1] == 'P' and (place[irow + 1][icol] != 'X' or place[irow][icol - 1] != 'X'):
return 0
return 1
def solution(places):
return [check(place) for place in places]
IDEA
다중 for 문 빠져나가기
python은 C언어의 lable, goto 같은게 없다. 따라서 flag를 두고 다중 for 문을 빠져나가는 방식을 택했다. 다만, python의 indent를 제대로 맞췄는지 잘 확인해야 한다.
for - enumerate
이 문제에서 유용하게 사용했던 for - enumerate.