[Samsung] 2020-2 오전 1번 2차원 테트리스

Question

Language: Python

Difficulty: Gold 2

해당 문제의 풀이는 모노미노도미노2의 Solution 2번 과정과 동일하게 풀었으며, 각각의 색깔을 가지는 부분들을 독립적인 2차원 배열로 생성해서 타일을 넣는 작업과 꽉찬 행 제거, 연한 부분의 처리 부분을 진행하였다. 추가적으로, list 대신 deque를 활용하여 시간 복잡도 부분에서 개선하였다.

각 과정들을 살펴보면 아래와 같다.

타일을 밀어 넣는 작업

각 타입 별로 타입의 시작 행, 시작 열, 끝 행, 끝 열을 구해서 아래와 같이 각 구역에 넣는 과정을 진행한다.

#각 구역에 타일을 밀어넣는다.
def push_tile_to_zone(zone,start_row,start_col,end_row,end_col):
    
    while end_row < 5 and zone[end_row+1][start_col] ==0 and zone[end_row+1][end_col] ==0:
        start_row+=1
        end_row+=1

    #타일 삽입 진행
    for row in range(start_row,end_row+1):
        for col in range(start_col,end_col+1):
            zone[row][col]=1
    
    return [start_row,end_row]

꽉찬 행 처리

하나의 행이 가득 차게 되면 해당 행을 지우고 위의 행들은 한 행씩 내려준다. list, queue 형태로 되어 있기 때문에 행을 지우게 되면 위에 있던 행은 자동으로 내려오게 된다.

#꽉 찬 행을 제거하고 위의 행들을 내린다.
def remove_full_tiles(zone,rows):
    count=0
    for row in rows:
        #꽉 차 있으면 해당 행에 있는 값들의 합은 4가 된다.
        if sum(zone[row])==4:
            del zone[row]
            zone.appendleft([0]*4)
            count+=1
    return count

연한 부분의 행 처리

연한 부분에 타일이 있는 행이 있는 경우에는 아래의 행을 제거해야 하기 때문에, 연한 부분에 있는 타일이 있는 행의 갯수를 찾아서 그 갯수 만큼 아랫 부분에서 행을 추출한다.

#연한 부분에서 타일을 포함하고 있는 행의 갯수 만큼 아래 행들을 제거한다.
def remove_tiles_from_light_space(zone):
    remove_count=0
    for row in range(2):
        #타일이 하나라도 있으면 합이 0보다 크다.
        if sum(zone[row]) >=1:
            remove_count+=1
    
    for _ in range(remove_count):
        zone.pop()
        zone.appendleft([0]*4)


Solution

from collections import deque

#각 구역에 타일을 밀어넣는다.
def push_tile_to_zone(zone,start_row,start_col,end_row,end_col):
    
    while end_row < 5 and zone[end_row+1][start_col] ==0 and zone[end_row+1][end_col] ==0:
        start_row+=1
        end_row+=1

    #타일 삽입 진행
    for row in range(start_row,end_row+1):
        for col in range(start_col,end_col+1):
            zone[row][col]=1
    
    return [start_row,end_row]

#꽉 찬 행을 제거하고 위의 행들을 내린다.
def remove_full_tiles(zone,rows):
    count=0
    for row in rows:
        #꽉 차 있으면 해당 행에 있는 값들의 합은 4가 된다.
        if sum(zone[row])==4:
            del zone[row]
            zone.appendleft([0]*4)
            count+=1
    return count

#연한 부분에서 타일을 포함하고 있는 행의 갯수 만큼 아래 행들을 제거한다.
def remove_tiles_from_light_space(zone):
    remove_count=0
    for row in range(2):
        #타일이 하나라도 있으면 합이 0보다 크다.
        if sum(zone[row]) >=1:
            remove_count+=1
    
    for _ in range(remove_count):
        zone.pop()
        zone.appendleft([0]*4)


#타일을 밀어넣는 작업
def push_tile(red_zone,yellow_zone,tile_type,tile_row,tile_col):
    tile_start_row,tile_start_col,tile_end_row,tile_end_col=0,0,0,0
    scores=0
    #빨간색에 넣기
    if tile_type == 1:
        tile_start_row,tile_start_col,tile_end_row,tile_end_col=0,3-tile_row,0,3-tile_row
    elif tile_type==2:
        tile_start_row,tile_start_col,tile_end_row,tile_end_col=0,3-tile_row,1,3-tile_row
    elif tile_type==3:
        tile_start_row,tile_start_col,tile_end_row,tile_end_col=0,3-tile_row-1,0,3-tile_row
    
    rows=push_tile_to_zone(red_zone,tile_start_row,tile_start_col,tile_end_row,tile_end_col)
    scores+=remove_full_tiles(red_zone,rows)
    remove_tiles_from_light_space(red_zone)

    #노란색에 넣기
    if tile_type == 1:
        tile_start_row,tile_start_col,tile_end_row,tile_end_col=0,tile_col,0,tile_col
    elif tile_type==2:
        tile_start_row,tile_start_col,tile_end_row,tile_end_col=0,tile_col,0,tile_col+1
    elif tile_type==3:
        tile_start_row,tile_start_col,tile_end_row,tile_end_col=0,tile_col,1,tile_col
    
    rows=push_tile_to_zone(yellow_zone,tile_start_row,tile_start_col,tile_end_row,tile_end_col)
    scores+=remove_full_tiles(yellow_zone,rows)
    remove_tiles_from_light_space(yellow_zone)
    
    return scores

def print_board(title,board):
    print(title)
    for row in board:
        print(*row)

def solution():
    red_zone=deque([0]*4 for _ in range(6))
    yellow_zone=deque([0]*4 for _ in range(6))

    total_points=0
    for tile_type,tile_row,tile_col in tiles:
        total_points+=push_tile(red_zone,yellow_zone,tile_type,tile_row,tile_col)
    
    total_tiles=0
    for row in range(2,6):
        total_tiles+=sum(red_zone[row])
        total_tiles+=sum(yellow_zone[row])
    print(total_points)
    print(total_tiles)
if __name__ == "__main__":
    k=int(input())
    tiles=[list(map(int,input().split())) for _ in range(k)]

    solution()

댓글남기기