[프로그래머스] Lv0_안전지대

박선영·2023년 10월 7일
0
post-thumbnail

Lv0_안전지대

📄Description

다음 그림과 같이 지뢰가 있는 지역과 지뢰에 인접한 위, 아래, 좌, 우 대각선 칸을 모두 위험지역으로 분류합니다.

지뢰는 2차원 배열 board에 1로 표시되어 있고, board에는 지뢰가 매설 된 지역 1과, 지뢰가 없는 지역 0만 존재합니다.
지뢰가 매설된 지역의 지도 board가 매개변수로 주어질 때, 안전한 지역의 칸 수를 return하도록 solution 함수를 완성해주세요.

제한 조건

  • board는 n * n 배열입니다.
  • 1 ≤ n ≤ 100
  • 지뢰는 1로 표시되어 있습니다.
  • board에는 지뢰가 있는 지역 1과 지뢰가 없는 지역 0만 존재합니다.

입출력 예시

boardresult
[[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 0, 0]]
16
[[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 1, 1, 0],
[0, 0, 0, 0, 0]]
13
[[1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1]]
0

입출력 예 설명

  1. (3, 2)에 지뢰가 있으므로 지뢰가 있는 지역과 지뢰와 인접한 위, 아래, 좌, 우, 대각선 총 8칸은 위험지역입니다. 따라서 16을 return합니다.
  2. (3, 2), (3, 3)에 지뢰가 있으므로 지뢰가 있는 지역과 지뢰와 인접한 위, 아래, 좌, 우, 대각선은 위험지역입니다. 따라서 위험지역을 제외한 칸 수 13을 return합니다.
  3. 모든 지역에 지뢰가 있으므로 안전지역은 없습니다. 따라서 0을 return합니다.

🤔생각 정리

  1. (x, y) 좌표를 중심으로 주변 8칸을 특정값으로 바꾸면서 위험지역을 표시해야겠네
    (x-1,y-1), (x-1,y), (x-1,y+1), (x,y-1), (x,y+1), (x+1,y-1), (x+1,y), (x+1,y+1)
  2. 위험지역 표시는 borad 안이고 0일 때만 할 수 있겠네
    -1 < r < n and -1 < c < n and board[r][c] == 0일 때
  3. 안전지역은 0인 지역이고 0의 개수를 세면 되겠네

💡Pseudo Code💡

1. n = board의 길이
2. for x in range(n) and for y in range(n): 좌표 
3.		(x,y)에 지뢰가 있다면:
4.			for (r,c) in 주변 8:
5.				(r,c)가 board 안이며 안전지역이라면:
6. 					위험지역(2)로 지정
7. 안전지역(0)인 칸의 개수 세기

🖥️코드화

import itertools

def solution(board):
    n = len(board)
    for x, y in list(itertools.product(range(n), repeat=2)):
        if board[x][y]==1: # 지뢰가 있을 때
            for i, j in list(itertools.product((-1, 0, 1), repeat=2)):# 방향
                r, c = x+i, y+j    
                # borad 안이고 0일 때
                if -1 < r < n and -1 < c < n and board[r][c] == 0:
                    board[r][c] = 2
    # print(board)
    return sum([1 for r in board for c in r if not c]) # 안전지역 칸 수

📌코드 비교 및 감상

  1. 집합 활용
    집합을 활용해서 위험지역인 모든 좌표를 추가하되 중복을 제거한다.
    (1) enumerate 함수를 사용해 좌표의 위치와 칸의 정보를 모두 접근한다.
    (2) 주변 좌표를 집합에 update한다.
    (3) 추가된 좌표를 확인하며 board 안인 좌표의 개수를 센다 - 위험지역
    (4) 전체 칸 수 - 위험지역 칸 수 = 안전지역 칸 수

    (나는 안전지역을 계산하기 위해 위험지역으로 바꾸는 방법을 채택했다면, 이 코드는 위험지역을 계산해 역으로 안전지역의 칸 수를 계산하는 방법을 사용한다. 코드가 확실히 간단해보인다..)
    코드를 인용하자면 이렇다.
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)
profile
데이터를 만지는 사람

0개의 댓글