문제 설명
https://school.programmers.co.kr/learn/courses/30/lessons/120866
내 풀이
def solution(board):
answer = 0
# 지뢰의 인덱스를 담은 배열 land_arr
land_arr = []
# 지뢰의 인덱스를 찾아서 land_arr 배열에 담음
for i in range(len(board)):
for j in range(len(board)):
if board[i][j] == 1:
land_arr.append([i,j])
# 위, 우측 위 대각선, 오른쪽, 오른쪽 아래 대각선, 아래, 좌측 아래 대각선, 왼쪽, 좌측 위 대각선
direction = [[0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [-1, -1], [-1, 0], [-1, 1]]
for l in land_arr:
# 지뢰 인덱스로 board 배열 접근
#print(board[l[0]][l[1]])
for x, y in direction:
#print(l[0] + x, l[1] + y, len(board))
if 0 <= (l[0] + x) < len(board) and 0 <= (l[1] + y) < len(board):
#print(l[0] + x, l[1] + y)
board[l[0] + x][l[1] + y] = 1
# 지뢰 인덱스로 board 배열 접근
#print(board[land_arr[0][0]][land_arr[0][1]])
for b in board:
answer += b.count(0)
return answer
def solution(board):
answer = 0
# 지뢰의 인덱스를 담은 배열 land_arr
land_arr = []
# 지뢰의 인덱스를 찾아서 land_arr 배열에 담음
for i in range(len(board)):
for j in range(len(board)):
if board[i][j] == 1:
land_arr.append([i,j])
# 위, 우측 위 대각선, 오른쪽, 오른쪽 아래 대각선, 아래, 좌측 아래 대각선, 왼쪽, 좌측 위 대각선
direction = [[0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [-1, -1], [-1, 0], [-1, 1]]
# 지뢰의 인덱스에서 각 방향 값을 더해, 그 값을 1로 채움 -> 위험지역이 1로 변경됨
for l in land_arr:
for x, y in direction:
if 0 <= (l[0] + x) < len(board) and 0 <= (l[1] + y) < len(board):
board[l[0] + x][l[1] + y] = 1
# 위험지역을 제외한 지역(원소가 0)을 찾아 개수를 센다.
for b in board:
answer += b.count(0)
return answer
먼저, 주어진 배열 board를 순회하며 지뢰가 있는 곳(원소 = 1)의 인덱스를 land_arr 배열에 담았다.
따라서 land_arr에는 지뢰의 위치 인덱스만 담기게 된다.
아래 그림처럼 지뢰가 있는 곳의 위, 우측 위 대각선, 오른쪽, 오른쪽 아래 대각선, 아래쪽, 좌측 아래 대각선, 왼쪽, 좌측 위 대각선은 모두 위험지대가 되므로 위험지대를 모두 1로 채운다.
이는 land_arr 배열을 순회하며, 지뢰가 있는 곳의 인덱스를 통해
그 인덱스에서 각각의 x, y 방향으로 이동하며 값을 1로 채우는 방법으로 진행한다.
이때, 위험지대(이동한 위치(즉, 지뢰 위치에서 방향 값을 더한 위치))가 주어진 지역 범위를 벗어날 수 없으므로,
이동한 위치는 0보다 크고 board의 길이보다 작아야 한다!
이제 지뢰의 위치와 위험지대는 모두 1로 바뀌었으므로, board 배열에서 위험지역을 제외한 지역(원소가 0인 곳)을 찾아 개수를 더해 answer로 반환한다!
다른 사람 풀이
def solution(board):
n = len(board)
danger = set()
for i, row in enumerate(board):
for j, x in enumerate(row):
if not x:
continue
danger.update((i+di, j+dj) for di in [-1,0,1] for dj in [-1, 0, 1])
return n*n - sum(0 <= i < n and 0 <= j < n for i, j in danger)
내가 푼 풀이와 비슷하지만 좀 더 깔끔한 풀이인듯하다.
제한된 지역의 길이를 n로 지정하고, 위험한 지역의 좌표를 저장하기 위한 빈 집합 danger을 만든다.
for문을 통해 주어진 배열을 순회하며 현재 셀이 0 (즉, 빈 공간)이면 다음 셀로 넘어간다. (if not x : continue)
현재 위치가 0이 아니면 현재 위치 주변의 위험한 지역의 좌표를 danger 집합에 업데이트한다.
여기서 i+di와 i+dj는 현재 위치에서 상하좌우 대각선 방향으로 한 칸씩 이동한 좌표이다.
(di를 [-1, 0, 1], dj를 [-1, 0, 1]로 지정했으므로 이를 조합하면 상하좌우 대각선 총 8가지 방향으로 움직이게된다)
이제, 위첨지역의 좌표 구했음로, 전체 지역의 원소 수에서 위험한 지역의 수를 빼서 안전한 지역의 개수를 구한다.
이를 위해 danger 집합에 있는 각 좌표에 대해 해당 좌표가 지역의 범위 내에 있는지 확인을 한다.
느낀점
코드는 길지만, 생각보다 엄청 복잡한 문제는 아닌듯하다.
아닌가? 내가 알게모르게 실력이 오른걸까?
정답률이 60%인데 혼자 힘으로 풀어내어 뿌듯하다-!
아무튼 기분은 좋다^^
'코딩테스트 > PYTHON' 카테고리의 다른 글
[프로그래머스][PYTHON] Lv. 0 k의 개수 (0) | 2024.03.19 |
---|---|
[프로그래머스][PYTHON] Lv. 0 외계어 사전 (0) | 2024.03.16 |
[프로그래머스][PYTHON] Lv. 0 숨어있는 숫자의 덧셈 (2) (0) | 2024.03.14 |
[프로그래머스][PYTHON] Lv. 0 다항식 더하기 (0) | 2024.03.14 |
[프로그래머스][PYTHON] Lv. 0 최댓값 만들기 (2) (0) | 2024.03.13 |