[Programmers] 퍼즐조각 채우기 Python

2023. 8. 12. 13:59·Algorithm (PS)
728x90

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

# https://school.programmers.co.kr/learn/courses/30/lessons/84021
from collections import deque

dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]

def get_position(sx, sy, table, visited, mode):
    one_piece = [(0, 0)] # 한 조각을 이루는 좌표 리스트
    visited[sx][sy] = True
    queue = deque(one_piece)
    n = len(table)
    while queue:
        x, y = queue.popleft()
        for i in range(4):
            # 실제 board 위에서 좌표
            bx = sx + dx[i] + x
            by = sy + dy[i] + y

            nx = x + dx[i]
            ny = y + dy[i]
            if 0 <= bx < n and 0 <= by < n and not visited[bx][by] and table[bx][by] == mode:
                visited[bx][by] = True
                queue.append((nx, ny))
                one_piece.append((nx, ny))

    return one_piece

def rotate_puzzle(one_piece): # ex. [(0,0), (1,0)]
    # 90 도 회전한 퍼즐 모양 모음
    rotated_puzzle_list = [one_piece]
    for i in range(3):
        new_pos = []
        for x, y in rotated_puzzle_list[-1]:
            nx = -y
            ny = x
            new_pos.append((nx, ny))
        rotated_puzzle_list.append(new_pos)

    return rotated_puzzle_list

# table 2차원 배열에서 퍼즐 조각의 위치 & 모양 저장하기 -> dfs
def get_puzzle(table):
    puzzle_list = [] # [cnt, (x1,y1), (x2,y2)] , [cnt, (a1, b1), .. ] ...
    n = len(table)
    visited = [[False] * n for _ in range(n)]
    for i in range(n):
        for j in range(n):
            if table[i][j] and not visited[i][j]:
                one_piece = get_position(i, j, table, visited, 1) # def get_position(sx, sy, table, visited, mode = 1):
                count = len(one_piece)
                # rotate 시킨 좌표까지

                puzzle_list.append([count]+rotate_puzzle(one_piece))
    return puzzle_list

def check(game_board, puzzle, x, y):
    n = len(game_board)
    for px, py in puzzle:    # puzzle 안에 있는 모든 좌표들이 조건에 맞아야 함
        nx, ny = x + px, y + py
        if 0 <= nx < n and 0 <= ny < n and game_board[nx][ny] == 0:
            continue
        else:
            return False
    return True


# 0 인 칸을 찾아야 함 !
def dfs(puzzle_list, game_board):

    answer = 0
    n = len(game_board)
    m = len(puzzle_list)
    visited = [[False] * n for _ in range(n)]
    check_puzzle = [False] * m

    for i in range(n):
        for j in range(n):
            if not visited[i][j] and game_board[i][j] == 0:
                one_vacant = get_position(i, j, game_board, visited, 0) # 빈칸 크기 -> def get_position(sx, sy, table, visited, mode = 1):
                size_vacant = len(one_vacant)

                # puzzle_list에 빈공간에 들어갈 수 있는 조각 확인
                for vx, vy in one_vacant:
                    flag = False
                    x, y = vx + i, vy + j
                    # puzzle_list
                    for k in range(m):
                        if check_puzzle[k]: # 이미 사용한 퍼즐 조각
                            continue
                        size_puzzle = puzzle_list[k][0]
                        if size_puzzle != size_vacant: # 반드시 크기가 딱 맞아야 함 !
                            continue
                        for puzzle in puzzle_list[k][1:]:
                            if check(game_board, puzzle, x, y): # true
                                flag = True
                                answer += size_puzzle
                                check_puzzle[k] = True
                                break
                        if flag:
                            break
                    if flag:  # 이미 처리된 경우에 for 문을 탈출시키고 다음 vacant 확인하기 !
                        break
    return answer


# game_board = [[1,1,0,0,1,0],[0,0,1,0,1,0],[0,1,1,0,0,1],[1,1,0,1,1,1],[1,0,0,0,1,0],[0,1,1,1,0,0]]
# table = [[1,0,0,1,1,0],[1,0,1,0,1,0],[0,1,1,0,1,1],[0,0,1,0,0,0],[1,1,0,1,1,0],[0,1,0,0,0,0]]

def solution(game_board, table):
    puzzle_list = get_puzzle(table)
    answer = dfs(puzzle_list, game_board)

    return answer
728x90

'Algorithm (PS)' 카테고리의 다른 글

[백준] 2138번: 전구와 스위치 Python  (0) 2023.08.19
[백준] 2631번: 줄세우기 (Python) | 가장 긴 증가하는 부분 수열 구하기  (0) 2023.08.19
[백준] 14714번: 홍삼게임 (Easy) - Python  (0) 2023.08.08
[백준] 28305번: 세미나 배정 (Python/파이썬)  (0) 2023.07.23
[프로그래머스/Kakao] 압축 python  (0) 2023.07.11
'Algorithm (PS)' 카테고리의 다른 글
  • [백준] 2138번: 전구와 스위치 Python
  • [백준] 2631번: 줄세우기 (Python) | 가장 긴 증가하는 부분 수열 구하기
  • [백준] 14714번: 홍삼게임 (Easy) - Python
  • [백준] 28305번: 세미나 배정 (Python/파이썬)
minjiwoo
minjiwoo
Data Engineering과 Cloud Native 기술에 대해 Dive Deep 하는 플랫폼 엔지니어가 되는 것을 목표로 하고 있습니다. 경험과 공부한 내용을 기록하며 지속가능한 엔지니어가 되는 것이 꿈입니다.
minjiwoo
minji's engineering note
minjiwoo
전체
오늘
어제
  • 분류 전체보기 (612)
    • Data Engineering (42)
      • Apache Spark (11)
      • Databricks & Delta Lake (9)
      • Airflow (3)
      • SQL (6)
      • Trouble Shooting (2)
      • Hadoop (2)
      • MLOps (1)
    • Cloud Engineering (104)
      • AWS (23)
      • Linux 🐧 (29)
      • Docker 🐳 (21)
      • Kubernetes ⚙️ (20)
      • Ansible (10)
    • Computer Science (87)
      • 네트워크 (9)
      • 운영체제 (25)
      • 정보처리기사 (48)
      • CS 기술 면접 스터디 (3)
    • Programming Languages (27)
      • Python (17)
      • C와 C++ (10)
    • Backend (5)
      • Django (2)
    • 프로젝트 (2)
      • 테크포임팩트 (2)
    • iOS (11)
      • 레이블러리 (2)
    • Algorithm (PS) (275)
      • LeetCode (6)
    • 개발일기 (29)
      • 내돈내산 후기🎮 (3)
      • 개발자 취준생 (4)
      • Today I Learned (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

  • Hi there

인기 글

태그

  • ansible
  • 쿠버네티스
  • 클라우드
  • Leetcode
  • 파이썬
  • 프로그래머스
  • 카카오코딩테스트
  • Swift
  • 백준
  • Databricks
  • 백트래킹
  • linux
  • dp
  • BFS
  • 운영체제
  • python
  • 데이터엔지니어
  • AWS
  • EC2
  • SPARK
  • 리눅스
  • 알고리즘
  • 코딩테스트
  • Kubernetes
  • 빅데이터
  • 데이터브릭스
  • 스파크
  • 데이터엔지니어링
  • dfs
  • docker

최근 댓글

최근 글

hELLO· Designed By정상우.v4.5.2
minjiwoo
[Programmers] 퍼즐조각 채우기 Python
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.