[프로그래머스] 🧱 프렌즈 4 블록 - [1차] 2018 카카오 블라인드 채용 / Python
🧱 프렌즈 4 블록 문제 풀어보기
😃 나의 코드
dx = [0, 1, 0, 1] dy = [0, 0, 1, 1] def safe(width, height, c_idx, r_idx): for x, y in zip(dx,dy): if width-1 < x+c_idx or x+c_idx < 0 or height-1 < y+r_idx or y+r_idx < 0: return False return True def del_check(board, c_idx, r_idx): square_set = set() for x, y in zip(dx,dy): square_set.add(board[y+r_idx][x+c_idx]) if len(square_set) == 1 and square_set != {" "}: return True return False def del_block(board, c_idx, r_idx): for x, y in zip(dx,dy): board[y+r_idx][x+c_idx] = "" return board def total_del_block(board): total = 0 for row in board: for block in row: if block == ' ': total += 1 return total def drop_block(width, height, board): for x_idx in range(width): tmp_lst = [] for y_idx in range(height): tmp_lst.append(board[y_idx][x_idx]) col_str = "".join(tmp_lst) col_str = (height-len(col_str))*" " + col_str for y_idx in range(height): board[y_idx][x_idx] = col_str[y_idx] return board def solution(height, width, board): board = [[block for block in row] for row in board] answer = 0 while True: del_lst = [] for r_idx in range(height): for c_idx in range(width): if safe(width, height, c_idx, r_idx): if del_check(board, c_idx, r_idx): del_lst.append([c_idx, r_idx]) if len(del_lst) == 0: break for del_pos in del_lst: board = del_block(board, del_pos[0], del_pos[1]) board = drop_block(width, height, board) return total_del_block(board)
이 문제를 푸는 과정은 다음과 같습니다.
- 같은 모양의 2 X 2 블록을 찾는다.
- 그 블록을 제거한다.
- 블록을 아래로 떨어뜨려 빈 공간을 채운다.
- 더 이상 지울 블록이 없을 때까지 시행을 반복한다.
이런 시행이 잘 정리되고 각 시행별로 코드가 긴 문제는 각각의 시행을 함수로 만들어서 진행하면 코드가 덜 복잡하게 짤 수 있습니다. 문제 풀이에 앞서 편의를 위해
board = [[block for block in row] for row in board]
를 통해 board
를 2차원 배열로 바꿔줍니다.
del_lst = [] for r_idx in range(height): for c_idx in range(width): if safe(width, height, c_idx, r_idx): if del_check(board, c_idx, r_idx): del_lst.append([c_idx, r_idx])
우선 같은 모양의 2 X 2 블록을 찾는 과정입니다. 여기서 미리 만들어둔 dx
와 dy
를 이용합니다. dx
와 dy
는 각각 x
와 y
에 더해서 블록을 검증하는 역할을 합니다.
def safe(width, height, c_idx, r_idx): for x, y in zip(dx,dy): if width-1 < x+c_idx or x+c_idx < 0 or height-1 < y+r_idx or y+r_idx < 0: return False return True
우선 통과할 것은 safe()
함수입니다. dx
와 dy
를 더하는 과정에서 board
의 index
를 넘는 경우를 미리 방지해주는 역할을 합니다.
def del_check(board, c_idx, r_idx): square_set = set() for x, y in zip(dx,dy): square_set.add(board[y+r_idx][x+c_idx]) if len(square_set) == 1 and square_set != {" "}: return True return False
다음은 2 X 2 블록이 지워질 수 있는 지를 검증하는 del_check()
함수입니다. 각 블록을 set
자료형에 추가하여 모두 같은 모양이라면 set
의 크기가 1이고, 그 모양이 빈 공간이 아닐 시 True
를 그 외에는 False
를 반환합니다. del_check()
을 통해 검증된 c_idx
와 r_idx
는 del_lst
에 저장됩니다.
def del_block(board, c_idx, r_idx): for x, y in zip(dx,dy): board[y+r_idx][x+c_idx] = "" return board
del_lst
의 원소를 이용하여 board
의 블록을 제거해줍니다. 만약 del_lst
의 크기가 0
이라면 지울 블록이 없다는 뜻이기 때문에 무한 루프를 break
해줍니다.
def drop_block(width, height, board): for x_idx in range(width): tmp_lst = [] for y_idx in range(height): tmp_lst.append(board[y_idx][x_idx]) col_str = "".join(tmp_lst) col_str = (height-len(col_str))*" " + col_str for y_idx in range(height): board[y_idx][x_idx] = col_str[y_idx] return board
블록을 떨어뜨려 빈 공간을 채우는 과정입니다. 여러 방법이 있겠지만 저는 문자열을 이용하였습니다. 왼쪽부터 세로 배열을 받아 tmp_lst
에 저장합니다. 그 배열을 join을 이용하여 빈 공간을 없에줍니다. 문자열 길이를 다시 높이에 맞추기 위해 앞에 빈 칸을 적절히 추가합니다. 이를 바탕으로 다시 board
를 업데이트해줍니다. 이 과정을 사라질 블록이 없을 때까지 반복합니다.
def total_del_block(board): total = 0 for row in board: for block in row: if block == ' ': total += 1 return total
결과값은 전체에서 사라진 블록의 갯수를 구하는 것이기 때문에 board
를 확인하면서 빈 칸인 블록의 갯수를 세면 문제는 마무리됩니다.
Written with StackEdit.
'Algorithm > Problem Solving' 카테고리의 다른 글
[프로그래머스] ☎ 전화번호 목록 / Python (0) | 2019.02.14 |
---|---|
[프로그래머스] 👷♀️ 쇠막대기 / Python (2) | 2019.02.14 |
[프로그래머스] 👩💼 뉴스 클러스터링 - [1차] 2018 카카오 블라인드 채용 / Python / KAKAO BLIND RECRUITMENT (0) | 2019.02.14 |
[프로그래머스] 👨💻 캐시 - [1차] 2018 카카오 블라인드 채용 / Python (0) | 2019.02.13 |
[프로그래머스] 🎯 다트 게임 - [1차] 2018 카카오 블라인드 채용 / Python (1) | 2019.02.12 |
댓글
이 글 공유하기
다른 글
-
[프로그래머스] ☎ 전화번호 목록 / Python
[프로그래머스] ☎ 전화번호 목록 / Python
2019.02.14 -
[프로그래머스] 👷♀️ 쇠막대기 / Python
[프로그래머스] 👷♀️ 쇠막대기 / Python
2019.02.14 -
[프로그래머스] 👩💼 뉴스 클러스터링 - [1차] 2018 카카오 블라인드 채용 / Python / KAKAO BLIND RECRUITMENT
[프로그래머스] 👩💼 뉴스 클러스터링 - [1차] 2018 카카오 블라인드 채용 / Python / KAKAO BLIND RECRUITMENT
2019.02.14 -
[프로그래머스] 👨💻 캐시 - [1차] 2018 카카오 블라인드 채용 / Python
[프로그래머스] 👨💻 캐시 - [1차] 2018 카카오 블라인드 채용 / Python
2019.02.13
댓글을 사용할 수 없습니다.