코딩테스트
[Hackerrank] The Bomberman Game
essay0263
2025. 1. 15. 02:29
문제 설명
Bomberman은 직사각형 격자(grid)에서 폭탄을 설치하고 터뜨리는 게임입니다. 각 칸은 폭탄(O)이 있거나 비어있음(.)을 나타냅니다.
게임은 다음 규칙에 따라 진행됩니다:
- 1초: Bomberman은 아무 행동도 하지 않습니다.
- 짝수 초(2, 4, 6, ...): 비어있는 모든 칸에 폭탄을 설치합니다.
- 폭탄은 설치 후 정확히 3초 후에 폭발하며, 폭발 시 상하좌우 인접한 칸도 함께 비워집니다.
- 동시에 설치된 폭탄은 동시에 폭발합니다.
- 폭발로 인해 비워진 칸에는 즉시 폭탄이 설치되지 않습니다.
목표
- **초기 격자 상태(grid)**와 시간 n이 주어질 때, n초 후의 격자 상태를 출력하시오.
입력 형식
- 첫 번째 줄: 세 개의 정수 r(행의 수), c(열의 수), n(시뮬레이션 시간).
- 다음 r줄: 초기 격자 상태.
- .: 빈 칸
- O: 폭탄이 설치된 칸
출력 형식
- n초 후의 격자 상태를 출력합니다.
문제 예시
입력:
6 7 3
.......
...O...
....O..
.......
OO.....
OO.....
출력:
OOO.OOO
OO...OO
OOO...O
..OO.OO
...OOOO
...OOOO
사실 이 문제는 문제를 이해하는 시간이 훨씬 오래 걸렸다. 아무리 봐도 문제를 이해를 못 하다가 구글링을 통해서 블로그 글을 보고 알게 되었다.
그래서 결국 문제를 생각해 보면 2초, 4초, 6초... 에는 필드가 전부 폭탄으로 채워져 있고, 1초, 5초, 9초마다 동일한 필드가 반복되고 3초, 7초, 11초... 마다 동일한 필드가 반복되는 것을 확인할 수 있다.
그리고 dx = [0, 1, 0, -1], dy = [1, 0, -1, 0]으로 두어서 dx[i], dy[i]로 해서 각 열마다 상하좌우를 확인해서 범위 안이고, 폭탄이면 그 주변을 터트리는 방식을 이용했다.
dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]
def bomberMan(n, grid):
# Write your code here
x = len(grid)
y = 0
for i in grid[0]:
if i == "O" or i == ".":
y += 1
if n % 2 == 0:
visited = [["O" for _ in range(y)] for _ in range(x)]
elif n % 4 == 3:
visited = [["O" for _ in range(y)] for _ in range(x)]
for j in range(y):
for i in range(x):
if grid[i][j] == "O":
visited[i][j] = "."
for num in range(4):
if (i + dx[num]) >= 0 and (i + dx[num]) < x and (j + dy[num]) >= 0 and (j + dy[num]) < y:
visited[i + dx[num]][j + dy[num]] = "."
elif n == 1:
return grid
elif n % 4 == 1:
visited = [["O" for _ in range(y)] for _ in range(x)]
for j in range(y):
for i in range(x):
if grid[i][j] == "O":
visited[i][j] = "."
for num in range(4):
if (i + dx[num]) >= 0 and (i + dx[num]) < x and (j + dy[num]) >= 0 and (j + dy[num]) < y:
visited[i + dx[num]][j + dy[num]] = "."
grid = visited
visited = [["O" for _ in range(y)] for _ in range(x)]
for j in range(y):
for i in range(x):
if grid[i][j] == "O":
visited[i][j] = "."
for num in range(4):
if (i + dx[num]) >= 0 and (i + dx[num]) < x and (j + dy[num]) >= 0 and (j + dy[num]) < y:
visited[i + dx[num]][j + dy[num]] = "."
visited = ["".join(x) for x in visited]
return visited
이렇게 보니까 정답이 나왔다. 그런데 코드가 너무 지저분해서 수정을 해주었다.
def bomberMan(n, grid):
rows, cols = len(grid), len(grid[0].replace(" ", ""))
if n == 1:
return grid
elif n % 2 == 0:
return ['O' * cols for _ in range(rows)]
def explode(grid):
exploded = [['O'] * cols for _ in range(rows)]
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
for i in range(rows):
for j in range(cols):
if grid[i][j] == 'O':
exploded[i][j] = '.'
for dx, dy in directions:
ni, nj = i + dx, j + dy
if 0 <= ni < rows and 0 <= nj < cols:
exploded[ni][nj] = '.'
return [''.join(row) for row in exploded]
first_explosion = explode(grid)
second_explosion = explode(first_explosion)
return first_explosion if n % 4 == 3 else second_explosion
정답처리되었다.