프로그래머스 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씩 순차적으로 채워준 방식입니다.
감사합니다.