ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [위클리 챌린지] 3주차
    알고리즘/프로그래머스 2021. 8. 29. 19:09

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

     

    코딩테스트 연습 - 3주차

    [[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]] [[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]] 14 [[0,0,0],[1,1,0],[1,1,1]] [[1,1,1],[1,0,0],[0,0,0]] 0

    programmers.co.kr

     

    간소화랑 효율성 고려안하고 짜서 그런지 코드가 좀 난잡하다.

     

    - 풀이

     

    1. table에 대해 각각의 블럭에 대해 아래와 같은 배열을 만든다.

    0 0 0 0 0 0
    0 0 1 0 0 0
    0 1 1 0 0 0
    0 0 1 0 0 0
    0 0 0 0 0 0
    0 0 0 0 0 0

     

    2. game_board에 대해서도 위와 같이 배열을 만든다.

    3. 2번에서 만든 빈칸배열(board)에 대해 맞는 블럭을 찾는다.

    4. 블럭과 빈칸의 크기가 같고 check()함수가 True라면, answer에 합산, 그리고 한 블럭이 두개이상의 빈칸에 들어가는 것을 막기위해 삭제

    5. check함수

      - block을 회전시키면서 맞는지 비교

      - 블럭과 빈칸의 위치를 list1, list2에 좌표형태로 추가

    EX) 위와 같은 'ㄱ'자 블럭과 빈칸을 나타내는 두 배열에 대해

    list1 = [[0,0], [0,1], [1,0]]

    list2 = [[1,1], [1,2], [2,1]] 

    이라 할 때, list1 - list2 = [[-1,-1], [-1,-1], [-1,-1]]

    list1[:, 0]값들이 다 같고, list2[:, 1]값도 다 같으면 같은 모양이라고 할 수 있다.

    * unique() : 유일한 값들을 반환한다.

     

     

    import numpy as np
    def solution(game_board, table):
        answer = 0  
    
    ### table블럭 구하기 ###
        blocks = []
        for i in range(len(table)):
            for j in range(len(table[i])):
                if table[i][j]: #블럭이 있으면
                    table[i][j] = 0
                    queue = [[i, j]]
                    block = np.zeros((len(table), len(table)))
                    block[i][j] = 1
                    while queue:
                        x, y = queue[0][0], queue[0][1]
                        del queue[0] 
                        if y+1 < len(table[x]) and table[x][y+1]==1: #좌
                            queue.append([x, y+1])
                            table[x][y+1] = 0
                            block[x][y+1] = 1
                        if y > 0 and table[x][y-1]==1: #우
                            queue.append([x, y-1])
                            table[x][y-1] = 0
                            block[x][y-1] = 1
                        if x > 0 and table[x-1][y]==1: #상
                            queue.append([x-1, y])
                            table[x-1][y] = 0
                            block[x-1][y] = 1
                        if x+1 < len(table) and table[x+1][y]==1: #하
                            queue.append([x+1, y])
                            table[x+1][y] = 0
                            block[x+1][y] = 1
                    blocks.append(np.array(block))
    
    ### game_board블럭 구하기 ###                
        cnt = 0 #debug
        for i in range(len(game_board)):
            for j in range(len(game_board[i])):
                if not game_board[i][j]: #빈칸이면
                    game_board[i][j] = 1
                    queue = [[i, j]]
                    block = np.zeros((len(game_board), len(game_board)))
                    block[i][j] = 1
                    while queue:
                        x, y = queue[0][0], queue[0][1]
                        del queue[0] 
                        if y+1 < len(game_board[x]) and game_board[x][y+1]==0: #좌
                            queue.append([x, y+1])
                            game_board[x][y+1] = 1
                            block[x][y+1] = 1
                        if y > 0 and game_board[x][y-1]==0: #우
                            queue.append([x, y-1])
                            game_board[x][y-1] = 1
                            block[x][y-1] = 1
                        if x > 0 and game_board[x-1][y]==0: #상
                            queue.append([x-1, y])
                            game_board[x-1][y] = 1
                            block[x-1][y] = 1
                        if x+1 < len(game_board) and game_board[x+1][y]==0: #하
                            queue.append([x+1, y])
                            game_board[x+1][y] = 1
                            block[x+1][y] = 1
                    cnt += 1    
    ### 빈칸에 맞는 블럭인지 체크 후 answer에 추가 ###
                    for k in range(len(blocks)):
                        if blocks[k].sum()==np.array(block).sum() and check(blocks[k], block):  #테이블, 보드
                            answer += blocks[k].sum()
                            block = []
                            del blocks[k]
                            break
        return answer
    
    ### 블럭을 돌려가며, 칸에 맞는지 체크 ###
    def check(block, board):
        for k in range(4):  #rotate 90 180 270 360
            block = np.rot90(block)
            list1, list2 = [], []
            for i in range(len(block)):
                for j in range(len(block[i])):
                    if block[i][j] == 1:
                        list1.append([i, j])
                    if board[i][j] == 1:
                        list2.append([i, j])
            temp = np.array(list1) - list2  #np.array는 리스트간의 연산이 가능
            if len(np.unique(temp[:,0]))==1 and len(np.unique(temp[:,1]))==1:
                print(temp)
                return True
        return False

     

Designed by Tistory.