Programming/Algorithm(Python)

[코드트리/python] 미지의 공간 탈출(2024년 하반기 삼성기출)

code_wizard 2025. 4. 11. 17:29

문제

미지의 공간 탈출

당신은 시간 여행자입니다. 시간 여행 도중 타임머신의 오작동으로 인해 크기 의 미지의 공간에 갇히게 되었습니다. 당신은 타임머신을 타고 이 공간에서 탈출해야 합니다. 탈출하기 위해, 타임머신의 기능을 활용하여 이 공간의 지리 정보를 파악했습니다.

이 공간은 한 변의 길이가 인 2차원 평면이며, 그 사이 어딘가에는 한 변의 길이가 인 정육면체 형태의 시간의 벽이 세워져 있습니다.

타임머신의 스캔 기능을 통해 다음의 정보를 얻을 수 있었습니다:

  1. 미지의 공간의 평면도: 위에서 내려다본 전체 맵입니다.
  2. 시간의 벽의 단면도: 시간의 벽의 윗면과 동서남북 네 면의 단면도입니다.

이 평면도와 단면도는 빈 공간 장애물로 구성되어 있으며, 각각 0과 1로 표현됩니다. 당신의 타임머신은 빈 공간만 이동할 수 있으며, 장애물 위치로는 이동할 수 없습니다.

당신의 타임머신은 시간의 벽의 윗면 어딘가에 위치하며, 시간의 벽의 윗면 단면도에서는 타임머신의 위치 2가 추가로 표시됩니다. 마찬가지로 미지의 공간의 평면도에서는 시간의 벽의 위치 3 탈출구 4가 추가로 표시됩니다. 탈출구는 시간의 벽 외부에 있는 미지의 공간의 바닥에 위치합니다.

시간의 벽과 맞닿은 미지의 공간의 바닥은 기본적으로 장애물들로 둘러 쌓여있습니다. 그러나 단 한 칸만 빈 공간으로 뚫려 있기 때문에 시간의 벽에서 미지의 공간의 바닥으로 이어질 수 있는 출구는 하나입니다.

또한, 미지의 공간의 바닥에는 총 개의 시간 이상 현상이 존재합니다. 각 시간 이상 현상은 바닥의 빈 공간 에서 시작하여  의 배수 턴마다 방향  한 칸씩 확산되며, 확산된 이후에도 기존 위치의 시간 이상 현상은 사라지지 않고 남아 있습니다. 시간 이상 현상은 장애물과 탈출구가 없는 빈 공간으로만 확산되며, 더 이상 확산할 수 없을 경우 멈춥니다. 모든 시간 이상 현상은 서로 독립적이며 동시에 확산됩니다. 방향 는 동(0), 서(1), 남(2), 북(3)으로 표시됩니다.

당신의 타임머신은 매 턴마다 상하좌우로 한 칸씩 이동할 수 있으며, 장애물과 시간 이상 현상을 피해 탈출구까지 도달해야 합니다. 타임머신이 시작점에서 탈출구까지 이동하는 데 필요한 최소 시간(턴 수)을 출력하는 프로그램을 작성해야 합니다. 만약 탈출할 수 없다면 -1을 출력합니다. 시간 이상 현상이 확산된 직후 타임머신이 이동하기 때문에, 타임머신은 시간 이상 현상이 확산되는 곳으로 이동할 수 없음에 유의합니다.

 


입력

첫 번째 줄에 미지의 공간의 한 변의 길이 , 시간의 벽 한 변의 길이 , 시간 이상 현상의 개수 가 공백을 사이에 두고 차례로 주어집니다.

다음 개의 줄에 걸쳐 미지의 공간의 평면도가 주어집니다.

다음 줄부터 시간의 벽의 동, 서, 남, 북, 윗면의 단면도가 각각  줄에 걸쳐 차례로 주어집니다.

그 다음  줄에 걸쳐 각 시간 이상 현상의 초기 위치 , 와 확산방향 , 확산상수 가 공백을 사이에 두고 차례로 주어집니다.


출력

타임머신이 시작점에서 탈출구까지 이동하는 데 필요한 최소 시간(턴 수)을 출력하세요.

만약 탈출할 수 없다면 -1을 출력합니다.


예제 1

8 3 2
4 0 0 0 0 0 0 0
0 1 1 1 1 1 0 0
0 1 3 3 3 1 0 1
0 1 3 3 3 1 0 1
0 1 3 3 3 0 0 0
0 1 1 1 1 1 1 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 1
1 1 1
0 0 0
0 1 1
1 1 1
1 0 1
1 1 1
0 0 1
1 0 0
1 0 1
0 0 0
1 0 0
1 1 1
2 0 0
0 1 0
0 0 0
0 7 1 14
6 3 3 2

 

출력

28

 

미지의 공간은 <왼쪽 그림>처럼 생겼고, <오른쪽 그림> 최단거리로 나가려 합니다.

하지만 t=14일 때, <왼쪽 그림>처럼 시간 이동 현상 때문에 위로 갈 수 없다, 따라서 <오른쪽 그림> 처럼 28 이 정답입니다.


해설

주요포인트

- 3차원 "시간의 벽"을 어떻게 BFS 돌릴지 생각(측면 연결 방법)

- "시간이상현상"은 "미지의 공간"에서 시작

- "타임머신"은 "시간의 벽"에서 시작

- "탈출구"는 "미지의 공간"에만 있음

- "시간의 벽"탈출 시, "시간이상현상"이 막아서 못 나오는 경우

- "시간의 벽"의 출구는 오직 한 곳 

- "이상현상"이 시간초에서 타임머신보다 선행되어야 함

    => 14초가 되었을 때, 이상현상이 먼저 움직여야 함

         (BFS특성상 큐에 먼저 들어가버리면 알고리즘이 돌아가므로, 큐에 넣기전에 먼저 판별해야함⭐️)

 

필요지식

- 2차원 메트리스 돌리기

- 2차원 배열 hardcopy


개인해설

3차원 "시간의 벽"을 어떻게 구현하는지가 핵심입니다.

2차원으로 바꿔야겠다고 생각했고, 주사위 전개도처럼 펼쳐서 풀었습니다.

 

핵심

- 1) 인풋과 전개도 모양 달라서 남방향을 제외하고,(서,동,북) 전개도는 2차원 메트리스 돌리기 해야함

- 2) 시간의 벽 출구 매핑

- 3) 측면 이어주는거 해야함(어렵🔥)

 

1) 전개도 만들어서 시간의 벽 탈출하기 

1-1) 2차원 매트리스 돌리기

전개도가 똑바로 전개되도록 (남방향)제외하고, (북,서,동) 돌리기 

time_wall = [[5]*(3*m+2) for _ in range(3*m+2)]
for i in range(3*m+2):
    time_wall[0][i] = 9
    time_wall[3*m+1][i] = 9 
    time_wall[i][0] = 9
    time_wall[i][3*m+1] = 9

# 동
c_mat = [0]*m
cc_mat = [[0]*m for _ in range(m)]
for i in range(m): 
    c_mat[i] = list(map(int, input().split()))
for i in range(m):
    for j in range(m):
        cc_mat[m-1-j][i] = c_mat[i][j]
for i in range(m):
    for j in range(m):
        time_wall[m+1+i][2*m+1+j] = cc_mat[i][j]
    
# 서 
c_mat = [0]*m
cc_mat = [[0]*m for _ in range(m)]
for i in range(m): # 서
    c_mat[i] = list(map(int, input().split()))
for i in range(m):
    for j in range(m):
        cc_mat[j][m-1-i] = c_mat[i][j]
for i in range(m):
    for j in range(m):
        time_wall[m+1+i][1+j] = cc_mat[i][j]

# 남
for i in range(m): 
    arr = list(map(int, input().split()))
    for j in range(m):
        time_wall[2*m+1+i][m+1+j] = arr[j]

# 북
c_mat = [0]*m
cc_mat = [[0]*m for _ in range(m)]
for i in range(m): 
    c_mat[i] = list(map(int, input().split()))
for i in range(m):
    for j in range(m):
        cc_mat[m-1-i][m-1-j] = c_mat[i][j]
for i in range(m):
    for j in range(m):
        time_wall[i+1][m+1+j]  = cc_mat[i][j]
    
# 윗면
for i in range(m):  
    arr = list(map(int, input().split()))
    for j in range(m):
        time_wall[m+1+i][m+1+j] = arr[j]

 


2) 시간의 벽 출구 매핑

time_wall = [[5]*(3*m+2) for _ in range(3*m+2)]

저는 이런식으로 만들었고 +2 로 패딩을 줘서 9로 벽을 막았습니다.

그리고 따로 맵을 만든만큼, 해당 출구 7을 매핑해주어야 했습니다.

빨강부분만 탈출 가능하기에 

start_x, start_y는 좌상단부터 순차탐색을 하므로 주어진 2차원 매트리스에서 3(= 시간의 벽)을 찾았을 때

항상 시간의 벽의 최상단좌를 먼저 발견합니다. 그에 따라서 상대범위를 측청하여 <오른쪽 그림> 처럼 매핑했습니다.

# 2) 시간의 벽에다가 값으로 매핑하기 
time_wall_mapping(time_exit[0]-start_x, time_exit[1]-start_y)

def time_wall_mapping(i ,j):
    if i<0: 
        time_wall[0][m+1+j] = 7 #북
    elif i>=m: 
        time_wall[3*m+1][m+1+j] = 7 #남
    elif j<0: 
        time_wall[m+1+i][0] = 7 # 서 
    else: 
        time_wall[m+1+i][3*m+1] = 7 # 동

 


3) 측면 이어주기

이제 2차원으로 전개한 시간의 벽을 BFS 돌아서 탈출구(7)로 탈출해야함. -> 측면 간다면, side_mapping()으로 가서 측면이동 실행

이때 패딩전략과 2차원 매트리스에 대한 이해도가 문제에 도움이 될 것이다.

<왼쪽 그림>처럼 임의로 숫자를 배정해서 자기만의 스토리를 구사한다.

<오른쪽 그림>처럼 초록선을 기준으로 이동하는데 

(m+1), (2*m)가 경계선이다. 나는 둘 다 +1이 붙는지 알고 틀렸었다.

 

디버깅 빠르게 하는 법

- 직접 해당 벽면들 숫자매칭해보며 값이 제대로 이동하는 지 확인하기

이유: 노가다 작업에서 휴먼에러 가장 많이 발생.

def time_bfs(i, j):
    que = deque()
    que.append((i,j,0))
    visited = [[False]*(3*m+2) for _ in range(3*m+2)]
    visited[i][j] = True
    flag = 0
    sec = -1

    while que:
        x, y, cnt = que.popleft()
        
        for dx, dy in move:
            px, py = x+dx, y+dy 
            if 0<=px<3*m+2 and 0<=py<3*m+2 and not visited[px][py]:
                
                if time_wall[px][py] == 5: # 측면이동     
                    visited[px][py] = True # 방문 처리 
                    px, py = side_mapping(x, y) # 옆면으로
                    if not visited[px][py]:
                        if time_wall[px][py] == 0:
                            que.append((px, py, cnt+1))
                            visited[px][py] = True
                        elif time_wall[px][py] == 7: # 시간의 벽 탈출 
                            flag = 1
                            sec = cnt # 시간초 
                            break 

                elif time_wall[px][py] == 0:
                    que.append((px, py, cnt+1))
                    visited[px][py] = True 
                elif time_wall[px][py] == 7: # 시간의 벽 탈출 
                    flag = 1
                    sec = cnt # 시간초 
                    break 
        if flag == 1:
            break    
    return sec

 

def side_mapping(x, y):
    if x == m+1:
        if y < m+1: # 1 -> 2
            return y, x
        elif y > 2*m: # 4 -> 3
            return m+1-(y-(2*m)),2*m

    elif x == 2*m:
        if y < m+1: # 5 -> 6
            return 2*m+y,m+1
        elif y > 2*m: # 7 -> 8
            return y, x
            
    elif y == m+1:
        if x < m+1: # 2 -> 1
            return y, x
        elif x > 2*m: # 6 -> 5
            return 2*m, x-(2*m)
                    
    elif y == 2*m:
        if x < m+1: # 3 -> 4
            return m+1, 2*m+x
        elif x > 2*m: # 8 -> 7
            return y, x

2) 미지의 공간 탈출구로 탈출하기

시간의 벽을 탈출할 수 있는지 체크한다.

 

1) 시간의 벽 탈출 실패: 못하면 flag=1

                    or

2) 이상현상이 탈출구 막음

 

이때 2차원 배열 지우는 지식 필요

1) idx를 저장했다가 한 번에 복사하는 방법 택함

# 3) 시간의 벽 탈출하기
result = -1 # 시간초 
flag = 0
for i in range(3*m+2):
    for j in range(3*m+2):
        if time_wall[i][j] == 2: # 타임머신 장소 
            temp_sec = time_bfs(i, j)
            if temp_sec == -1: # 장애물로 탈출 불가능
                flag = 1
            else:
                result = temp_sec

# 4) 시간의 벽에서 나왔는데 이상현상이 막으면 탈출실패
delete_num = []
for idx, stop in enumerate(stop_spread):
    r, c, d, v = stop 
    value = result//v # 움직인 거리 
    if value > 0: # 확산해야 한다면 
        for i in range(1, value+1):
            px, py = r+(move[d][0]*i), c+(move[d][1]*i)
            if 0<=px<n and 0<=py<n and mat[px][py]==0:
                mat[px][py] = 1 # 장애물
            else:
               delete_num.append(idx) # 삭제
               break # 탈출
        stop_spread[idx] = (r+(move[d][0]*value), c+(move[d][1]*value), d, v) # x,y,d

temp = []
for idx in range(len(stop_spread)):
    if idx not in delete_num:
        temp.append(stop_spread[idx])
stop_spread = temp[:]
          
if flag == 1 or mat[time_exit[0]][time_exit[1]] == 1: # 시간의 벽 탈출못하면 or 이상현상이 막으면
    print(result)

 

탈출구 BFS

def bfs(i, j, c):
    que = deque()
    que.append((i,j,c))
    visited = [[False]*n for _ in range(n)]
    visited[i][j] = True
    g_cnt = c # 글로벌 시간초 

    while que:
        # print("que", que)
        x, y, cnt = que.popleft()

        for dx, dy in move:
            px, py = x+dx, y+dy 
            if 0<=px<n and 0<=py<n and not visited[px][py]:
                if cnt+1 > g_cnt: # 다음초로 넘어갔다면
                    g_cnt += 1 # 시간초 증가
                    for idx, stop in enumerate(stop_spread):# 이상현상 발생
                        r, c, d, v = stop
                        if g_cnt%v == 0: # 움직일 차례면
                            mx, my = r+move[d][0], c+move[d][1]
                            if 0<=mx<n and 0<=my<n and mat[mx][my]==0:
                                mat[mx][my] = 1 # 장애물
                                stop_spread[idx] = (r+move[d][0], c+move[d][1], d, v) # x,y,d,v
                            else:
                                del stop_spread[idx] # 제거 

                if mat[px][py]==0: # 이동가능
                    que.append((px, py, cnt+1))
                    visited[px][py] = True
                elif mat[px][py]==4: # 탈출구 
                    return cnt+1
    return -1

 

아래 처럼 

if 0<=px<n and 0<=py<n and not visited[px][py]:
    if cnt+1 > g_cnt: # 다음초로 넘어갔다면
        g_cnt += 1 # 시간초 증가
        for idx, stop in enumerate(stop_spread):
            r, c, d, v = stop
            if g_cnt%v == 0: # 움직일 차례면
                mx, my = r+move[d][0], c+move[d][1]
                if 0<=mx<n and 0<=my<n and mat[mx][my]==0:
                    mat[mx][my] = 1 # 장애물
                    stop_spread[idx] = (r+move[d][0], c+move[d][1], d, v) # x,y,d,v
                else:
                    del stop_spread[idx] # 제거

global_cnt인 g_cnt를 두어서, 현재 시간초가 종료하여 다음 시간초가 진행된다면

미리 "이상현상"을 진행하여 막기 


전체코드

# d: 0(동), 서(1), 남(2), 북(3)
# 목표: (장애물, 시간 이상 현상)을 피해 탈출구로, 최소 시간, -1
# 만약에 시간이 지나면 탈출구가 잠길 수 있음, 그러면 탈출 실패 

from collections import deque 
move = [(0,1),(0,-1),(1,0),(-1,0)]
n, m, f = map(int, input().split())
mat = [0]*n

for i in range(n):
    mat[i] = list(map(int, input().split()))

time_wall = [[5]*(3*m+2) for _ in range(3*m+2)]
for i in range(3*m+2):
    time_wall[0][i] = 9
    time_wall[3*m+1][i] = 9 
    time_wall[i][0] = 9
    time_wall[i][3*m+1] = 9
# 동
c_mat = [0]*m
cc_mat = [[0]*m for _ in range(m)]
for i in range(m): 
    c_mat[i] = list(map(int, input().split()))
for i in range(m):
    for j in range(m):
        cc_mat[m-1-j][i] = c_mat[i][j]
for i in range(m):
    for j in range(m):
        time_wall[m+1+i][2*m+1+j] = cc_mat[i][j]
  
# 서 
c_mat = [0]*m
cc_mat = [[0]*m for _ in range(m)]
for i in range(m): # 서
    c_mat[i] = list(map(int, input().split()))
for i in range(m):
    for j in range(m):
        cc_mat[j][m-1-i] = c_mat[i][j]
for i in range(m):
    for j in range(m):
        time_wall[m+1+i][1+j] = cc_mat[i][j]

# 남
for i in range(m): 
    arr = list(map(int, input().split()))
    for j in range(m):
        time_wall[2*m+1+i][m+1+j] = arr[j]

# 북
c_mat = [0]*m
cc_mat = [[0]*m for _ in range(m)]
for i in range(m): 
    c_mat[i] = list(map(int, input().split()))
for i in range(m):
    for j in range(m):
        cc_mat[m-1-i][m-1-j] = c_mat[i][j]
for i in range(m):
    for j in range(m):
        time_wall[i+1][m+1+j]  = cc_mat[i][j]
    
# 윗면 
for i in range(m): 
    arr = list(map(int, input().split()))
    for j in range(m):
        time_wall[m+1+i][m+1+j] = arr[j]

stop_spread = []
for i in range(f): # 시간 이상 현상 초기 위치
    r,c,d,v = map(int, input().split()) # 위치, 방향, 확산상수 
    mat[r][c] = 1
    stop_spread.append((r,c,d,v)) 

def time_exit_bfs(i, j):
    que = deque()
    que.append((i,j))
    visited = [[False]*n for _ in range(n)]
    visited[i][j] = True
    exit_x, exit_y = 0, 0

    while que:
        x, y = que.popleft()
        for dx, dy in move:
            px, py = x+dx, y+dy 
            if 0<=px<n and 0<=py<n and not visited[px][py]:
                if mat[px][py] == 3: 
                    que.append((px, py))
                    visited[px][py] = True
                elif mat[px][py] == 0: # 탈출구 
                    exit_x, exit_y = px, py 
                    
    return [exit_x, exit_y]

def side_mapping(x, y):
    if x == m+1:
        if y < m+1: # 1 -> 2
            return y, x
        elif y > 2*m: # 4 -> 3
            return m+1-(y-(2*m)),2*m

    elif x == 2*m:
        if y < m+1: # 5 -> 6
            return 2*m+y,m+1
        elif y > 2*m: # 7 -> 8
            return y, x
            
    elif y == m+1:
        if x < m+1: # 2 -> 1
            return y, x
        elif x > 2*m: # 6 -> 5
            return 2*m, x-(2*m)
                    
    elif y == 2*m:
        if x < m+1: # 3 -> 4
            return m+1, 2*m+x
        elif x > 2*m: # 8 -> 7
            return y, x

def time_bfs(i, j):
    que = deque()
    que.append((i,j,0))
    visited = [[False]*(3*m+2) for _ in range(3*m+2)]
    visited[i][j] = True
    flag = 0
    sec = -1

    while que:
        x, y, cnt = que.popleft()
        
        for dx, dy in move:
            px, py = x+dx, y+dy 
            if 0<=px<3*m+2 and 0<=py<3*m+2 and not visited[px][py]:
                
                if time_wall[px][py] == 5: # 측면이동     
                    visited[px][py] = True # 방문 처리 
                    px, py = side_mapping(x, y) # 옆면으로
                    if not visited[px][py]:
                        if time_wall[px][py] == 0:
                            que.append((px, py, cnt+1))
                            visited[px][py] = True
                        elif time_wall[px][py] == 7: # 시간의 벽 탈출 
                            flag = 1
                            sec = cnt # 시간초 
                            break 

                elif time_wall[px][py] == 0:
                    que.append((px, py, cnt+1))
                    visited[px][py] = True 
                elif time_wall[px][py] == 7: # 시간의 벽 탈출 
                    flag = 1
                    sec = cnt # 시간초 
                    break 
        if flag == 1:
            break    
    return sec

def time_wall_mapping(i ,j):
    if i<0: 
        time_wall[0][m+1+j] = 7 #북
    elif i>=m: 
        time_wall[3*m+1][m+1+j] = 7 #남
    elif j<0: 
        time_wall[m+1+i][0] = 7 # 서 
    else: 
        time_wall[m+1+i][3*m+1] = 7 # 동

def bfs(i, j, c):
    que = deque()
    que.append((i,j,c))
    visited = [[False]*n for _ in range(n)]
    visited[i][j] = True
    g_cnt = c # 글로벌 시간초 

    while que:
        x, y, cnt = que.popleft()

        for dx, dy in move:
            px, py = x+dx, y+dy 
            if 0<=px<n and 0<=py<n and not visited[px][py]:
                if cnt+1 > g_cnt: # 다음초로 넘어갔다면
                    g_cnt += 1 # 시간초 증가
                    for idx, stop in enumerate(stop_spread):
                        r, c, d, v = stop
                        if g_cnt%v == 0: # 움직일 차례면
                            mx, my = r+move[d][0], c+move[d][1]
                            if 0<=mx<n and 0<=my<n and mat[mx][my]==0:
                                mat[mx][my] = 1 # 장애물
                                stop_spread[idx] = (r+move[d][0], c+move[d][1], d, v) # x,y,d,v
                            else:
                                del stop_spread[idx] # 제거 

                if mat[px][py]==0: # 이동가능
                    que.append((px, py, cnt+1))
                    visited[px][py] = True
                elif mat[px][py]==4: # 탈출구 
                    return cnt+1
    return -1

# 1) 나가는 출구 찾기
flag = 0
time_exit = 0
start_x, start_y = 0, 0
for i in range(n):
    for j in range(n):
        if mat[i][j] == 3: 
            time_exit = time_exit_bfs(i, j)
            start_x, start_y = i, j
            flag = 1
            break
    if flag == 1:
        break 

# 2) 시간의 벽에다가 값으로 매핑하기 
time_wall_mapping(time_exit[0]-start_x, time_exit[1]-start_y)

# 3) 시간의 벽 탈출하기
result = -1 # 시간초 
flag = 0
for i in range(3*m+2):
    for j in range(3*m+2):
        if time_wall[i][j] == 2: # 타임머신 장소 
            temp_sec = time_bfs(i, j)
            if temp_sec == -1: # 장애물로 탈출 불가능
                flag = 1
            else:
                result = temp_sec

# 4) 시간의 벽에서 나왔는데 이상현상이 막으면 탈출실패
delete_num = []
for idx, stop in enumerate(stop_spread):
    r, c, d, v = stop 
    value = result//v # 움직인 거리 
    if value > 0: # 확산해야 한다면 
        for i in range(1, value+1):
            px, py = r+(move[d][0]*i), c+(move[d][1]*i)
            if 0<=px<n and 0<=py<n and mat[px][py]==0:
                mat[px][py] = 1 # 장애물
            else:
               delete_num.append(idx) # 삭제
               break # 탈출
        stop_spread[idx] = (r+(move[d][0]*value), c+(move[d][1]*value), d, v) # x,y,d

temp = []
for idx in range(len(stop_spread)):
    if idx not in delete_num:
        temp.append(stop_spread[idx])
stop_spread = temp[:]
          
if flag == 1 or mat[time_exit[0]][time_exit[1]] == 1: # 시간의 벽 탈출못하면 or 이상현상이 막으면
    print(result)
else:
    # 5) 미지의 벽 탈출하기(이상현상 고려하면서)
    result = bfs(time_exit[0], time_exit[1], result+1)
    print(result)

실수한 내용 + 자가 피드백

- (3*m+2)*(3*m+2) 배열, n*n 배열 => 2개가 있었는데 BFS돌릴 때 복붙하다가 0<= px < n조건도 복붙같이 돼서 틀렸음.

- 변수의 혼합 사용(px,py남발하다가, bfs()에서 px변수가 겹쳐서 mx로 고침)

- 미지의 영역을 움직일 때, 현재 움직인 거리도 넣었는데 문제를 잘 읽어보면 그냥 해당 주기될때마다(%v==0) +1만 이동하면 됨.

- 패딩전략 좋았고, 2차원 전개도 전략 좋았지만 구현에서 시간 많이 잡아먹음, 따라서 손으로 바로 그리고 숫자로 직접 대입할 것

- 2차원 돌리기는 그림그려서 직접 숫자 매칭해보는게 가장 빠름

- 중간중간 더 적극적으로 디버깅 시행하는게, 전체 해결 시간에 더 이로움, 문제가 절차적 구현일수록 더욱 함수화해서 쪼개서 문제 바라볼 것(side_mapping에서 틀렸던 점을 하나하나씩 다 디버깅해서 보는게 더 오래걸렸음, 미리 직접 숫자대입으로 노가다처럼 휴먼에러 많이 터지는 과정을 (함수화->숫자매핑)하고 넘어가자