저고데

[프로그래머스][1차]프렌즈 블록 본문

프로그래머스

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

진철 2023. 2. 6. 22:35
728x90
반응형

문제 링크 : https://school.programmers.co.kr/learn/courses/30/lessons/17679

 

프로그래머스

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

programmers.co.kr

코드를 작성하기 위한 순서는 다음과 같다.

1. 2*2의 같은 모양이면 해당 블록을 제거하고 제거한 만큼 아래로 내려줘야하기 때문에 pop을 사용하기 위해서 board를 다르게 입력한다. (문제에서 나온 보드를 시계 방향으로 90도 돌렸다고 생각하시면 됩니다 !)

2. 2*2가 같은 모양인지 확인해주는 twobytwo 함수를 만들어준다.

3. twobytwo 함수에서 겹치는 부분의 블록도 생각해야하기 때문에, 해당되는 좌표를 기록하고 set를 사용하여 중복되지 않고 제거되는 블록의 갯수를 반환한다.

4. 2*2 블록을 제거할 때는 좌표의 1번째 Index 값이 큰 것부터 제거하고 0을 append하여 list의 길이가 변하지 않게 해준다.

5. twobytwo 함수에서 반환하는 값이 0일 경우, 더 이상 동일한 2*2 블록이 없으므로 0을 반환할 때까지 while문을 반복한다.

def twobytwo(pyo): #2번
    record=[]
    for i in range(len(pyo)-1):
        for j in range(len(pyo[i])-1):
            if pyo[i][j].isalpha() and pyo[i][j]==pyo[i][j+1] and pyo[i][j]==pyo[i+1][j] and pyo[i][j] == pyo[i+1][j+1]:
                record.append((i,j)) #동일한 블록에 해당하는 좌표를 리스트에 담아준다.
                record.append((i,j+1))
                record.append((i+1,j))
                record.append((i+1,j+1))
    cnt=list(set(record)) #3번
    return len(cnt), cnt

def solution(m, n, board):
    answer = 0
    pyo=[]
    for i in range(n): #1번
        temp=[]
        for j in range(m-1, -1, -1):
            temp.append(board[j][i])
        pyo.append(temp)
    
    while True:
        if twobytwo(pyo)[0]==0: #5번
            return answer
        answer+=twobytwo(pyo)[0]
        dd=twobytwo(pyo)[1]
        dd.sort(key=lambda x: -x[1]) #4번
        for i in dd:
            pyo[i[0]].pop(i[1])
            pyo[i[0]].append('0')
    return answer

표를 다른 방식으로 입력 받아서 pop을 사용하게 만드는 것이 본 문제의 핵심이었다.

그리고 2*2 블록을 제거할 때, 높이가 높은 것에부터 제거하고 제거한만큼 알파벳이 아닌 다른 숫자를 추가하는 것 역시 중요했다.

해당 문제를 풀면서 새로 배웠던 것은 isalpha() isdigit()과 같은 함수를 사용할 때는 문자열인 경우에만 가능하는 것이었다.

처음에는 pyo[i[0]].append(0)을 사용해서 계속 에러가 발생했었다.

이처럼 함수를 사용할 때는 함수의 정의를 제대로 알아야할 듯하다.

(아무튼 독특한 방법으로 문제를 푼 것 같아서 기분이 너무 좋았어요 ㅎㅎ)

728x90
반응형