프로그래머스_[1차]프렌즈4블록

임정민·2024년 2월 6일
1

알고리즘 문제풀이

목록 보기
158/173
post-thumbnail

프로그래머스 Lv2 문제입니다. 실전에 대비하기 위해 60분 시간제한을 두고 풀었습니다.

문제

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

[나의 풀이]

⌛ 55분


def find_square(i,j,board):
    
    b1 = board[i][j]
    b2 = board[i][j+1] 
    b3 = board[i+1][j] 
    b4 = board[i+1][j+1] 
    
    if b1==b2 and b2==b3 and b3==b4:
        return True
    else:
        return False

def solution(m, n, board):
    answer = 0 
    find_block = True
    tmp = ['' for i in range(n)]

    for i in range(m):
        board[i] = list(board[i])
        
    while find_block:
        
        find_block = False
        find_xy = []
        
        for i in range(m-1): # "TTTANT"
            for j in range(n-1): # T,T,T,A,N,T
                if board[i][j]==' ':
                    continue
                elif find_square(i,j,board):

                    find_xy.append([i,j])
                    find_block = True

        for x,y in find_xy:
      
            board[x][y] = ""
            board[x+1][y] = ""
            board[x][y+1] = ""
            board[x+1][y+1] = ""
            
        
        for i in range(m):
            print(board[i])
        
        tmp = ['' for _ in range(n)]
        for i in range(m):
            row = board[i]
            for j in range(n):
                tmp[j] += row[j]

        for i in range(n):
            
            if len(tmp[i])<m:
                tmp[i] = " "*(m-len(tmp[i])) + tmp[i]
        
        new_board = ['' for i in range(m)]
        for i in range(n):
            row = tmp[i] # ' TTTT'
            for j in range(m):
                new_board[j] += row[j]

        for i in range(m):
            new_board[i] = list(new_board[i])
        board = new_board

    for i in range(m):
        for j in range(n):
            if board[i][j]==' ':
                answer += 1
        
    return answer

1차원 문자열 배열이 주어지고(board) 같은 모양의 카카오프렌즈 블록이 2×2 형태로 붙어있다면 블록이 사라지면서 점수를 얻으며 빈공간은 위에서 아래로 채우는 게임입니다.🐰🐰🐰



먼저 쉽게 인덱싱하고 초기화하기 위해 문자열 데이터를 list()시켜 2차원배열 형태로 만들었습니다.

입력된 배열에서 사라질 2x2 블록 현황을 체크하고 블록마다 ''로 초기화 시켜 제거하였습니다.

이후, 빈 공간을 채우기 위해 열끼리 문자열 연산하고 줄어든 길이만큼 왼쪽으로 ' ' (빈 문자열을) 더한 뒤, 다시 문자열을 list()형태로 바꾸어 새로운 board로 초기화하는 방식으로 구현하였습니다.

[다른 사람의 풀이1]


def solution(m, n, board):
    x = board
    x2 =[]

    for i in x: 
        x1 = []
        for i2 in i:
            x1.append(i2)
        x2.append(x1)

    point = 1
    while point != 0:
        list = []
        point = 0
        for i in range(m - 1):
            for j in range(n - 1):
                if x2[i][j] == x2[i][j + 1] == x2[i + 1][j] == x2[i + 1][j + 1] != '팡!':
                    list.append([i, j])
                    point += 1

        for i2 in list:
            i, j = i2[0], i2[1]
            x2[i][j], x2[i][j + 1], x2[i + 1][j], x2[i + 1][j + 1] = '팡!', '팡!', '팡!', '팡!'

        for i3 in range(m):
            for i in range(m - 1):
                for j in range(n):
                    if x2[i + 1][j] == '팡!':
                        x2[i + 1][j], x2[i][j] = x2[i][j], '팡!'

    cnt = 0
    for i in x2:
        cnt += i.count('팡!')
    return cnt

'나의 풀이'와는 점수를 얻어 2x2 블록이 사라지고 빈 공간을 채우는 구현 방식이 다른 풀이입니다.🐕🐕🐕

첫번째 row부터 돌며 현재위치 다음 행의 블록(아래 블록)이 없다면 두 블록의 위치를 바꾸는 작동 방식입니다.

[다른 사람의 풀이2]

def solution(m, n, board):
    for i in range(m):
        board[i] = list(board[i])
    
    cnt = 0
    rm = set()
    while True:
        # 보드를 순회하며 4블록이 된 곳의 좌표를 집합에 기록
        for i in range(m-1):
            for j in range(n-1):
                t = board[i][j]
                if t == []:
                    continue
                if board[i+1][j] == t and board[i][j+1] == t and board[i+1][j+1] == t:
                    rm.add((i,j));rm.add((i+1,j))
                    rm.add((i,j+1));rm.add((i+1,j+1))
        
        # 좌표가 존재한다면 집합의 길이만큼 세주고 블록을 지움 
        if rm:
            cnt += len(rm)
            for i,j in rm:
                board[i][j] = []
            rm = set()
        # 없다면 함수 종료
        else:
            return cnt
        
        # 블록을 위에서 아래로 당겨줌
        while True:
            moved = 0
            for i in range(m-1):
                for j in range(n):
                    if board[i][j] and board[i+1][j]==[]:
                        board[i+1][j] = board[i][j]
                        board[i][j] = []
                        moved = 1
            if moved == 0:
                break

2x2 형태로 지워질 블록들의 좌표를 set() 객체에 넣으며 중복될 수 있는 좌표들을 제거하는 방식입니다.🐢🐢🐢

만약 지워질 좌표가 없다면 이는 더 이상 점수를 없으므로 바로 종료하게 됩니다.

블록들을 위에서 아래로 당길 시에는 '다른 사람의 풀이1'처럼 아래 블록이 비어있을 때 바꿔주는 방식이고, while True문을 통해 한 Row씩 순차적으로 채워준 방식입니다.

감사합니다.

profile
https://github.com/min731

0개의 댓글