프로그래머스/파이썬_입문

💫안전지대 + set()

싱싱한복초이 2024. 12. 5. 10:17

https://school.programmers.co.kr/learn/courses/30/lessons/120866

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

[문제 설명]

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

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

 

제한사항

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

[나의 풀이]

def solution(board):
    n = len(board)  # n * n 크기의 보드
    directions = [(-1, -1), (-1, 0), (-1, 1), 
                  (0, -1),         (0, 1), 
                  (1, -1), (1, 0), (1, 1)]  
    danger_zone = [[0] * n for _ in range(n)]  # 위험 지역 표시용 배열

    for i in range(n):
        for j in range(n):
            if board[i][j] == 1:  # 지뢰 발견
                danger_zone[i][j] = 1  # 현재 위치 위험표시
                for di, dj in directions:  
                    ni, nj = i + di, j + dj
                    if 0 <= ni < n and 0 <= nj < n:  # 유효한 범위 내에 있을 경우 위험표시
                        danger_zone[ni][nj] = 1

    # 안전 지역 개수 계산
    safe_count = sum(1 for i in range(n) for j in range(n) if danger_zone[i][j] == 0)
    return safe_count

 

[다른 풀이]

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)

 

set()

Python의 **set(집합)**은 중복된 값을 허용하지 않는 자료구조입니다. 이는 수학에서의 집합과 유사하게 동작하며, 원소의 중복을 자동으로 제거하고 순서가 없는 데이터를 저장합니다.

 

주요 특징

1. 중복값 제거: set은 입력된 값 중 중복된 값은 자동으로 제거합니다.

2. 순서 없음: set은 순서를 유지하지 않습니다. 저장된 데이터의 순서는 예측할 수 없습니다.

3. 변경 가능: 새로운 값을 추가하거나 기존 값을 제거할 수 있습니다.

4. 빠른 연산: set은 검색, 추가, 삭제 작업에서 리스트보다 빠른 성능을 제공합니다.

 

*set의 활용: 집합연산

##교집합
a = {1, 2, 3}
b = {2, 3, 4}
print(a & b)

{2, 3} #출력

##합집합
a = {1, 2, 3}
b = {2, 3, 4}
print(a | b)

{1, 2, 3, 4} #출력

##차집합
a = {1, 2, 3}
b = {2, 3, 4}
print(a - b)

{1} #출력

##대칭차집합
a = {1, 2, 3}
b = {2, 3, 4}
print(a ^ b)

{1, 4} #출력

 

if not x: continue구문

if not x: continue는 x의 값이 0이거나 False일 때 실행을 건너뛰겠다는 의미입니다. 

 

def solution(board):
    answer = 0

    # 이중 반복문: row(행)와 col(열)을 올바르게 정의
    for row in range(len(board)):
        for col in range(len(board[row])):
            if board[row][col] == 1:  # 지뢰를 발견하면
                # 현재 지뢰의 주변 8방향 탐색
                for i in range(max(row-1, 0), min(row+2, len(board))):
                    for j in range(max(col-1, 0), min(col+2, len(board))):
                        if board[i][j] == 1:  # 이미 지뢰가 있는 칸은 건너뜀
                            continue
                        board[i][j] = -1  # 위험 지역으로 표시

    # 안전한 칸(값이 0인 칸) 개수 계산
    for row in board:
        answer += row.count(0)

    return answer
def get_arounds(x, y, max_length):
    arounds = []

    for m in (-1, 0, 1):
        for n in (-1, 0, 1):
            loc = x+m, y+n
            if 0 <= loc[0] < max_length and 0 <= loc[1] < max_length:
                arounds.append(loc) #현재 위치 (x, y)에서 변화량 (m, n)을 더한 새로운 좌표를 계산하여 loc에 저장
    return arounds


def solution(board):
    mines = []
    n = len(board)
    for i in range(n):
        for j in range(n):
            if board[i][j]:
                mines.append((i,j))
    for x, y in mines:
        arounds = get_arounds(x, y, n)
        for a, b in arounds:
            board[a][b] = 1

    return sum(row.count(0) for row in board)

'프로그래머스 > 파이썬_입문' 카테고리의 다른 글

외계어 사전  (0) 2025.01.03
💫숨어있는 숫자의 덧셈 (2)  (0) 2024.12.10
삼각형의 완성조건 (2)  (0) 2024.11.30
다항식 더하기 + f-string  (0) 2024.11.28
캐릭터의 좌표  (0) 2024.11.23