[ํ๋ก๊ทธ๋๋จธ์ค/python] ์ํด๋ฆฌ ์ฑ๋ฆฐ์ง 3์ฃผ์ฐจ : ํผ์ฆ ์กฐ๊ฐ ์ฑ์ฐ๊ธฐ
๋ฌธ์ ์ค๋ช
ํ ์ด๋ธ ์์ ๋์ธ ํผ์ฆ ์กฐ๊ฐ์ ๊ฒ์ ๋ณด๋์ ๋น ๊ณต๊ฐ์ ์ ์ ํ ์ฌ๋ ค๋์ผ๋ ค ํฉ๋๋ค. ๊ฒ์ ๋ณด๋์ ํ ์ด๋ธ์ ๋ชจ๋ ๊ฐ ์นธ์ด 1x1 ํฌ๊ธฐ์ธ ์ ์ฌ๊ฐ ๊ฒฉ์ ๋ชจ์์ ๋๋ค. ์ด๋, ๋ค์ ๊ท์น์ ๋ฐ๋ผ ํ ์ด๋ธ ์์ ๋์ธ ํผ์ฆ ์กฐ๊ฐ์ ๊ฒ์ ๋ณด๋์ ๋น์นธ์ ์ฑ์ฐ๋ฉด ๋ฉ๋๋ค.
- ์กฐ๊ฐ์ ํ ๋ฒ์ ํ๋์ฉ ์ฑ์ ๋ฃ์ต๋๋ค.
- ์กฐ๊ฐ์ ํ์ ์ํฌ ์ ์์ต๋๋ค.
- ์กฐ๊ฐ์ ๋ค์ง์ ์๋ ์์ต๋๋ค.
- ๊ฒ์ ๋ณด๋์ ์๋ก ์ฑ์ ๋ฃ์ ํผ์ฆ ์กฐ๊ฐ๊ณผ ์ธ์ ํ ์นธ์ด ๋น์ด์์ผ๋ฉด ์ ๋ฉ๋๋ค.
๋ค์์ ํผ์ฆ ์กฐ๊ฐ์ ์ฑ์ฐ๋ ์์์ ๋๋ค.
์ ๊ทธ๋ฆผ์์ ์ผ์ชฝ์ ํ์ฌ ๊ฒ์ ๋ณด๋์ ์ํ๋ฅผ, ์ค๋ฅธ์ชฝ์ ํ ์ด๋ธ ์์ ๋์ธ ํผ์ฆ ์กฐ๊ฐ๋ค์ ๋ํ๋ ๋๋ค. ํ ์ด๋ธ ์์ ๋์ธ ํผ์ฆ ์กฐ๊ฐ๋ค ๋ํ ๋ง์ฐฌ๊ฐ์ง๋ก [์,ํ,์ข,์ฐ]๋ก ์ธ์ ํด ๋ถ์ด์๋ ๊ฒฝ์ฐ๋ ์์ผ๋ฉฐ, ํฐ ์นธ์ ํผ์ฆ์ด ๋์ด์ง ์์ ๋น ๊ณต๊ฐ์ ๋ํ๋ ๋๋ค. ๋ชจ๋ ํผ์ฆ ์กฐ๊ฐ์ ๊ฒฉ์ ์นธ์ ๋ฑ ๋ง๊ฒ ๋์ฌ์์ผ๋ฉฐ, ๊ฒฉ์ ์นธ์ ๋ฒ์ด๋๊ฑฐ๋, ๊ฑธ์ณ ์๋ ๋ฑ ์๋ชป ๋์ธ ๊ฒฝ์ฐ๋ ์์ต๋๋ค.
์ด๋, ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด 3,4,5๋ฒ ์กฐ๊ฐ์ ๊ฒฉ์ ์นธ์ ๋์ผ๋ฉด ๊ท์น์ ์ด๊ธ๋๋ฏ๋ก ๋ถ๊ฐ๋ฅํ ๊ฒฝ์ฐ์ ๋๋ค.
- 3๋ฒ ์กฐ๊ฐ์ ๋๊ณ 4๋ฒ ์กฐ๊ฐ์ ๋๊ธฐ ์ ์ ์์ชฝ์ผ๋ก ์ธ์ ํ ์นธ์ ๋น์นธ์ด ์๊น๋๋ค.
- 5๋ฒ ์กฐ๊ฐ์ ์ ์์ผ๋ก ์ธ์ ํ ์นธ์ ๋น์นธ์ด ์๊น๋๋ค.
๋ค์์ ๊ท์น์ ๋ง๊ฒ ์ต๋ํ ๋ง์ ์กฐ๊ฐ์ ๊ฒ์ ๋ณด๋์ ์ฑ์ ๋ฃ์ ๋ชจ์ต์ ๋๋ค.
์ต๋ํ ๋ง์ ์กฐ๊ฐ์ ์ฑ์ ๋ฃ์ผ๋ฉด ์ด 14์นธ์ ์ฑ์ธ ์ ์์ต๋๋ค.
ํ์ฌ ๊ฒ์ ๋ณด๋์ ์ํ game_board, ํ ์ด๋ธ ์์ ๋์ธ ํผ์ฆ ์กฐ๊ฐ์ ์ํ table์ด ๋งค๊ฐ๋ณ์๋ก ์ฃผ์ด์ง๋๋ค. ๊ท์น์ ๋ง๊ฒ ์ต๋ํ ๋ง์ ํผ์ฆ ์กฐ๊ฐ์ ์ฑ์ ๋ฃ์ ๊ฒฝ์ฐ, ์ด ๋ช ์นธ์ ์ฑ์ธ ์ ์๋์ง return ํ๋๋ก solution ํจ์๋ฅผ ์์ฑํด์ฃผ์ธ์.
์ ํ์ฌํญ
- 3 ≤ game_board์ ํ ๊ธธ์ด ≤ 50
- game_board์ ๊ฐ ์ด ๊ธธ์ด = game_board์ ํ ๊ธธ์ด
- ์ฆ, ๊ฒ์ ๋ณด๋๋ ์ ์ฌ๊ฐ ๊ฒฉ์ ๋ชจ์์ ๋๋ค.
- game_board์ ๋ชจ๋ ์์๋ 0 ๋๋ 1์ ๋๋ค.
- 0์ ๋น์นธ, 1์ ์ด๋ฏธ ์ฑ์์ง ์นธ์ ๋ํ๋ ๋๋ค.
- ํผ์ฆ ์กฐ๊ฐ์ด ๋์ผ ๋น์นธ์ 1 x 1 ํฌ๊ธฐ ์ ์ฌ๊ฐํ์ด ์ต์ 1๊ฐ์์ ์ต๋ 6๊ฐ๊น์ง ์ฐ๊ฒฐ๋ ํํ๋ก๋ง ์ฃผ์ด์ง๋๋ค.
- table์ ํ ๊ธธ์ด = game_board์ ํ ๊ธธ์ด
- table์ ๊ฐ ์ด ๊ธธ์ด = table์ ํ ๊ธธ์ด
- ์ฆ, ํ ์ด๋ธ์ game_board์ ๊ฐ์ ํฌ๊ธฐ์ ์ ์ฌ๊ฐ ๊ฒฉ์ ๋ชจ์์ ๋๋ค.
- table์ ๋ชจ๋ ์์๋ 0 ๋๋ 1์ ๋๋ค.
- 0์ ๋น์นธ, 1์ ์กฐ๊ฐ์ด ๋์ธ ์นธ์ ๋ํ๋ ๋๋ค.
- ํผ์ฆ ์กฐ๊ฐ์ 1 x 1 ํฌ๊ธฐ ์ ์ฌ๊ฐํ์ด ์ต์ 1๊ฐ์์ ์ต๋ 6๊ฐ๊น์ง ์ฐ๊ฒฐ๋ ํํ๋ก๋ง ์ฃผ์ด์ง๋๋ค.
- game_board์๋ ๋ฐ๋์ ํ๋ ์ด์์ ๋น์นธ์ด ์์ต๋๋ค.
- table์๋ ๋ฐ๋์ ํ๋ ์ด์์ ๋ธ๋ก์ด ๋์ฌ ์์ต๋๋ค.
์ ๋ต
# dfs ์ด์ฉํ์ฌ ์ด์ฐจ์ ๋ฆฌ์คํธ์ ๋ธ๋ก ๋ชจ์ ๋ฆฌ์คํธ ์ ์ฅ ํจ์
def dfs(i, j, board, visited, empty, n):
section = []
stack = [(i, j)]
while stack:
x, y = stack.pop()
if x >= 0 and y >= 0: # ์ธ๋ฑ์ค ์ฒดํฌ
try:
if visited[x][y] == False and board[x][y] == n:
visited[x][y] = True
section.append((x,y))
stack.append((x-1, y))
stack.append((x+1, y))
stack.append((x, y-1))
stack.append((x, y+1))
except IndexError:
continue
empty.append(sorted(section))
# ๋ธ๋ก์ ์์น๋ฅผ (0,0)์ ๊ธฐ์ค์ผ๋ก ๋ณ๊ฒฝํ๋ ํจ์
def standard_0(b):
tmp = []
std_x = b[0][0]
std_y = b[0][1]
for x, y in b:
tmp.append((x-std_x, y-std_y))
return sorted(tmp)
def solution(game_board, table):
answer = []
N = len(game_board)
visited_board = [list(False for _ in range(N)) for _ in range(N)]
empty_board = [] # game_board์ ๋น์๋ฆฌ ์ขํ ๋ฆฌ์คํธ
visited_table = [list(False for _ in range(N)) for _ in range(N)]
empty_table = [] # table์ ๋ธ๋ก ์ขํ ๋ฆฌ์คํธ
# dfs ์ด์ฉํ์ฌ game_board์ ๋น ์๋ฆฌ ์ขํ ๋ฆฌ์คํธ empty_board์ ์ ์ฅ
for i in range(N):
for j in range(N):
if visited_board[i][j] == False and game_board[i][j] == 0:
dfs(i, j, game_board, visited_board, empty_board, 0)
# dfs ์ด์ฉํ์ฌ table์ ๋ธ๋ก ์ขํ ๋ฆฌ์คํธ empty_table์ ์ ์ฅ
for i in range(N):
for j in range(N):
if visited_table[i][j] == False and table[i][j] == 1:
dfs(i, j, table, visited_table, empty_table, 1)
# standard ํจ์ ์ด์ฉํ์ฌ empty_table์ ๋ธ๋ก ์ขํ๋ฅผ (0,0) ๊ธฐ์ค์ผ๋ก ๋ณ๊ฒฝ ํ blocks์ ์ ์ฅ
blocks = []
for block in empty_table:
blocks.append(standard_0(block))
# ์ด์ฐจ์ ๋ฆฌ์คํธ ํ์นธ์ฉ ๋์๋ณด๋ฉฐ ๋ง๋ ์๋ฆฌ ์๋์ง ํ์ธ ํจ์
def match(block):
for x in range(N):
for y in range(N):
move = []
for _x, _y in block:
new_x = x+_x
new_y = y+_y
if new_x >= 0 and new_y >=0: # ์ธ๋ฑ์ค ์ฒดํฌ
try:
_ = game_board[x+_x][y+_y] # ์ธ๋ฑ์ค ์ฒดํฌ
move.append((x+_x, y+_y))
except IndexError:
break
else:
break
if len(block) == len(move) and move in empty_board: # ๋ง๋ ์๋ฆฌ ์ฐพ์
empty_board.remove(move) # ๋น์๋ฆฌ ์ญ์
answer.extend(move)
return True
return False
# ๋ธ๋ก 90๋ ํ์ ํจ์
def rotate_90(block):
new = []
for x, y in block:
new.append((y, N-1 - x))
return standard_0(new)
# ๋ธ๋ก ํ๋์ฉ ๋ง๋ ์๋ฆฌ ์๋์ง ์ดํด๋ณด๊ณ ์์ผ๋ฉด ํ์ ํ ์ฐพ๊ธฐ ๋ฐ๋ณต
for block in blocks:
for _ in range(4):
if match(block) == False: # ๋ง๋ ์๋ฆฌ ์์
block = rotate_90(block) # ๋ธ๋ก ํ์
else: # ๋ง๋ ์๋ฆฌ ์ฐพ์
break
return len(answer)
โ ์ฐ์ game_board์ ๋น์นธ๊ณผ table์ ์๋ ๋ธ๋ก์ ์ขํ๊ฐ์ ๋ธ๋ก ๋จ์๋ก ๊ฐ๊ฐ ๋ฆฌ์คํธ์ ์ ์ฅํ๊ณ
table์ ์๋ ๋ธ๋ก ๋ฆฌ์คํธ๋ฅผ game_board์ ๋ชจ๋ ์นธ์ ๋์ ํด๋ณด๋ฉฐ game_board์ ๋น์นธ๊ณผ ์ผ์นํ๋์ง ํ์ธํ๋ค.
์ผ์นํ์ง ์๋๋ค๋ฉด ํ์ ํ ๋ค์ ๋์ ํ๋ฉฐ ํ์ธํด๋ณธ๋ค.
๐ฅ ํํ์ ๊ฐ์ ๋ณ๊ฒฝ์ด ๋ถ๊ฐ๋ฅํ๋ค
๐ฅ ๋ธ๋ก์ ์ขํ๋ฅผ (0,0) ๊ธฐ์ค์ผ๋ก ์ฎ๊ฒจ์ผ board์ ๋ชจ๋ ์นธ ํ์์ด ๊ฐ๋ฅํ๋ค.
๐ฅ ๋ฆฌ์คํธ์ ์ธ๋ฑ์ค๊ฐ ์์์ธ ๊ฒฝ์ฐ๋ IndexError์ ๊ฑธ๋ฆฌ์ง ์์ผ๋ฏ๋ก ๋ฐ๋ก ํ์ธํด์ฃผ์ด์ผ ํ๋ค.
1. dfs ํจ์
dfs๋ฅผ ์ด์ฉํ์ฌ ์ด์ฐจ์ ๋ฆฌ์คํธ board์ ์๋ ๋ธ๋ก ๋ชจ์์ ์ขํ ๋ฆฌ์คํธ๋ฅผ empty ๋ฆฌ์คํธ์ ์ ์ฅํ๋ค.
game_board์์๋ ๊ฐ์ด 0์ธ ๋ธ๋ก์, table์์๋ ๊ฐ์ด 1์ธ ๋ธ๋ก์ ํ์ธํด์ฃผ์ด์ผ ํ๋ฏ๋ก
์ธ์ n์ ํตํด ๊ตฌ๋ณํด์ค๋ค.
stack.pop() ์ขํ๋ฅผ ๊ธฐ์ค์ผ๋ก ์ํ์ข์ฐ์ ์ขํ๋ฅผ stack์ ๋ฃ์ด์ค๋ค.
์ด๋ stack.pop()์ ๊ฐ์ด board ์ธ๋ฑ์ค ์์ ์๋์ง ํ์ธ ํ ์งํํด์ผ ํ๋ค.
์ธ๋ฑ์ค๊ฐ ์์์ธ ๊ฐ์ผ ๋๋ if๋ฌธ์ ํตํด ํ์ธํ๊ณ , ์ธ๋ฑ์ค๊ฐ ์ค๋ฅธ์ชฝ์ผ๋ก ๋ฒ์ด๋ฌ์ ๋๋ except๋ฅผ ํตํด ํ์ธํ๋ค.
def dfs(i, j, board, visited, empty, n):
section = []
stack = [(i, j)]
while stack:
x, y = stack.pop()
if x >= 0 and y >= 0: # ์ธ๋ฑ์ค ์ฒดํฌ
try:
if visited[x][y] == False and board[x][y] == n:
visited[x][y] = True
section.append((x,y))
stack.append((x-1, y))
stack.append((x+1, y))
stack.append((x, y-1))
stack.append((x, y+1))
except IndexError:
continue
empty.append(sorted(section))
2. standard_0 ํจ์
dfs ํจ์๋ฅผ ํตํด table์์ ์ป์ ๋ธ๋ก ์ขํ ๋ฆฌ์คํธ empty_table์
(0,0)์์๋ถํฐ ๋ง์ถฐ๋ณด๋ฉฐ ๋น์นธ ๋ฆฌ์คํธ์ธ empty_board์ ๋น๊ตํด๋ณผ ๊ฒ์ด๋ค.
(0,0)์์ ์์ฐจ์ ์ผ๋ก ๋ชจ๋ ์นธ์ ์ดํด๋ณด๊ธฐ ์ํด์๋
empty_table์ ๋ธ๋ก์ด (0,0)์ ๊ธฐ์ค์ผ๋ก ์์นํด์์ด์ผํ๋ค.
๋ธ๋ก b์ ์ฒซ๋ฒ์งธ ์ขํ ๊ฐ์ (0,0)์ ๋ง์ถ๊ณ ๋๋จธ์ง ์ขํ๋ ์ด์ ๋ฐ๋ผ ์ฎ๊ฒจ์ค๋ค.
๐ฅ ์ด๋ ์ขํ๋ฅผ ๋ํ๋ด๋ ํํ ๊ฐ์ ๋ณ๊ฒฝ์ด ๋ถ๊ฐ๋ฅํ๋ฏ๋ก ๋ณ๊ฒฝ์ด ์๋ ๋ค์ ๋ง๋ค์ด return ํ๋ค.
def standard_0(b):
tmp = []
std_x = b[0][0]
std_y = b[0][1]
for x, y in b:
tmp.append((x-std_x, y-std_y))
return sorted(tmp)
3. match ํจ์
๋ชจ๋ ์นธ์ ๋๋ฉด์ empty_board์ ์ ์ฅ๋ ๋น์๋ฆฌ์ ๊ฐ์ ๋ชจ์์ธ์ง ํ์ธํ๋ค.
๋ชจ๋ ์นธ์ ๋ ๋ ์ฐ์ ์ธ๋ฑ์ค ๋ฒ์๊ฐ ๋ง๋์ง ํ์ธํ๋ค.
if ๋ฌธ์ ํตํด ์ธ๋ฑ์ค๊ฐ ์์๋ก ๋์ด๊ฐ๋์ง ํ์ธํ๊ณ
_ ๋ณ์๋ฅผ ์ด์ฉํ์ฌ ์ธ๋ฑ์ค ๋ฒ์๊ฐ ๋์ด๊ฐ ๊ฒฝ์ฐ except์ ๊ฑธ๋ฆฌ๋๋ก ํ๋ค.
๐ฅ except ๋๋ฌธ์ block์ ์ผ๋ถ๋ง move์ ์ ์ฅ๋๋ ๊ฒฝ์ฐ๊ฐ ์์ผ๋ฏ๋ก
block์ ๊ธธ์ด์ move์ ๊ธธ์ด๊ฐ ๊ฐ์์ง ํ์ธํ์ฌ block์ ์ ๋ถ๊ฐ move์ ์ ์ฅ๋์๋์ง ํ์ธ ํ
empty_board์ ๋ง๋ ์๋ฆฌ๊ฐ ์๋์ง ํ์ธํ๋ค.
๋ง๋ ์๋ฆฌ๊ฐ ์๋ค๋ฉด ๋์ด์ ๋น์ด์๋ ์๋ฆฌ๊ฐ ์๋๊ธฐ ๋๋ฌธ์ empty_board์์ ์ญ์ ํ๊ณ answer์ ์ขํ๋ฅผ ์ ์ฅํ๋ค.
def match(block):
for x in range(N):
for y in range(N):
move = []
for _x, _y in block:
new_x = x+_x
new_y = y+_y
if new_x >= 0 and new_y >=0: # ์ธ๋ฑ์ค ์ฒดํฌ
try:
_ = game_board[x+_x][y+_y] # ์ธ๋ฑ์ค ์ฒดํฌ
move.append((x+_x, y+_y))
except IndexError:
break
else:
break
if len(block) == len(move) and move in empty_board: # ๋ง๋ ์๋ฆฌ ์ฐพ์
empty_board.remove(move) # ๋น์๋ฆฌ ์ญ์
answer.extend(move)
return True
return False
4. rotate_90 ํจ์
๊ธฐ์กด ๋ธ๋ก์ด ๋ง๋ ์๋ฆฌ๊ฐ ์์ ๊ฒฝ์ฐ ํ์ ํ์ฌ ๋ค์ ๋ง๋ ์๋ฆฌ๊ฐ ์๋์ง ์ฐพ์์ผํ๋ค.
์ขํ๋ฅผ 90๋ ํ์ ํ๋ฉด x ๊ฐ์ y, y ๊ฐ์ N-1-x๊ฐ ๋๋ค.
๐ฅ ์ด๋๋ ๋ง์ฐฌ๊ฐ์ง๋ก ํํ ๊ฐ์ ๋ณ๊ฒฝ ๋ถ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ๋ค์ ๋ง๋ค์ด return ํด์ฃผ์ด์ผํ๋ค.
def rotate_90(block):
new = []
for x, y in block:
new.append((y, N-1 - x))
return standard_0(new)