https://programmers.co.kr/learn/courses/30/lessons/17679
시뮬레이션 문제, set이용, 2차원 배열 처리
문제설명
블라인드 공채를 통과한 신입 사원 라이언은 신규 게임 개발 업무를 맡게 되었다. 이번에 출시할 게임 제목은 프렌즈4블록.
같은 모양의 카카오프렌즈 블록이 2×2 형태로 4개가 붙어있을 경우 사라지면서 점수를 얻는 게임이다.
만약 판이 위와 같이 주어질 경우, 라이언이 2×2로 배치된 7개 블록과 콘이 2×2로 배치된 4개 블록이 지워진다. 같은 블록은 여러 2×2에 포함될 수 있으며, 지워지는 조건에 만족하는 2×2 모양이 여러 개 있다면 한꺼번에 지워진다.
TTTANT
RRFACC
RRRFCC
TRRRAA
TTMMMF
TMMTTJ
각 문자는 라이언(R), 무지(M), 어피치(A), 프로도(F), 네오(N), 튜브(T), 제이지(J), 콘(C)을 의미한다
입력으로 블록의 첫 배치가 주어졌을 때, 지워지는 블록은 모두 몇 개인지 판단하는 프로그램을 제작하라.
입출력 예
m n board answer
4 5 [CCBDE, AAADE, AAABF, CCBBF] 14
6 6 [TTTANT, RRFACC, RRRFCC, TRRRAA, TTMMMF, TMMTTJ] 15
솔루션
board를 행/열을 바꾸어 조작하기 쉽게 만든다.
[['T', 'R', 'R', 'T', 'T', 'T'],
['T', 'R', 'R', 'R', 'T', 'M'],
['T', 'F', 'R', 'R', 'M', 'M'],
['A', 'A', 'F', 'R', 'M', 'T'],
['N', 'C', 'C', 'A', 'M', 'T'],
['T', 'C', 'C', 'A', 'F', 'J']]
아래 오른쪽 점을 기준으로 board를 순회하면서 4칸이 같은 블록을 찾아 (공백 제외)
pop_set에 넣어준다. 중복되는 블록이 두번 계산되지 않게 하기위해 set을 사용한다.
터진 좌표를 0으로 만들어주고 없어진 갯수만큼 '_'(empty)블록을 위에 위치시킨 후 나머지 블록(0이 아닌 블록)들을 모아준다.
터진 갯수를 반환하여 count에 더해준다.
터지는 블록수가 없어질 때까지 반복한다.
코드
# 파이썬
def pop_num(b, m, n):
pop_set = set()
# search
for i in range(1, n):
for j in range(1, m):
if b[i][j] == b[i-1][j-1] == b[i-1][j] == b[i][j-1] != '_':
pop_set |= set([(i, j), (i-1, j-1), (i-1, j), (i, j-1)])
# set_board
for i, j in pop_set:
b[i][j] = 0
for i, row in enumerate(b):
empty = ['_'] * row.count(0)
b[i] = empty + [block for block in row if block != 0]
return len(pop_set)
def solution(m, n, board):
count = 0
b = list(map(list,zip(*board)))
while True:
pop = pop_num(b, m, n)
if pop == 0: return count
count += pop
좋은코드 감사합니다