블록 이동하기 [프로그래머스 60063]

오준혁·2023년 6월 1일
0

알고리즘

목록 보기
17/29

문제


블록 이동하기 [프로그래머스 60063]
https://school.programmers.co.kr/learn/courses/30/lessons/60063

풀이


로봇의 길이가 2인 점과 회전할 수 있다는 점에서 다소 어려움을 느꼈다. 길이가 한 점일 때는 어떻게 풀었을까 생각을 해봤고 길이가 2이면 이터러블 객체에 2개의 좌표를 넣으면 된다고 생각했다. 다소 코드가 복잡해지고 변수가 많아지지만 꼼꼼히 작성하여 해결할 수 있었다

중요한점

  • 이동할 수 있는 좌표를 구하는 함수를 따로 구분했다
  • 항상 구현문제는 한번에 많은 조건들을 생각하려하니 코드 한줄 쓰기 어려울 때가 많다. 이 문제도 그러한 편이었다. 당황하지 말고 문제의 개념을 파악하여 전형적인 방법을 찾아보는 것이 필요하다고 느꼈다.

코드


from collections import deque

def get_next_pos(pos, board):
    next_pos = []   # 가능한 다음 위치
    pos = list(pos) # 현재 위치 
    pos1_x, pos1_y, pos2_x, pos2_y = pos[0][0], pos[0][1], pos[1][0], pos[1][1] # 2개 위치 x, y 좌표 
    
    dx = [0, 0, 1, -1]  #상하좌우
    dy = [1, -1, 0, 0]
    
    for i in range(4):
        #상하좌우로 가능한 좌표들
        pos1_next_x, pos1_next_y, pos2_next_x, pos2_next_y = pos1_x + dx[i], pos1_y + dy[i], pos2_x + dx[i], pos2_y + dy[i] 
        #가능한 좌표들이 비어있으면 리스트에 추가
        if board[pos1_next_x][pos1_next_y] == 0 and board[pos2_next_x][pos2_next_y] == 0:
            next_pos.append({(pos1_next_x, pos1_next_y), (pos2_next_x, pos2_next_y)})
    if pos1_x == pos2_x:    #가로로 있을 때
        for i in [-1, 1]:   #위로 회전 아래로 회전할 때
            if board[pos1_x + i][pos1_y] == 0 and board[pos2_x + i][pos2_y] == 0:
                next_pos.append({(pos1_x, pos1_y), (pos1_x + i, pos1_y)})
                next_pos.append({(pos2_x, pos2_y), (pos2_x + i, pos2_y)})
    elif pos1_y == pos2_y:  #세로로 있을 때
        for i in [-1, 1]:   #위로 회전 아래로 회전할 때
            if board[pos1_x][pos1_y  + i] == 0 and board[pos2_x][pos2_y + i] == 0:
                next_pos.append({(pos1_x, pos1_y), (pos1_x, pos1_y + i)})
                next_pos.append({(pos2_x, pos2_y), (pos2_x, pos2_y + i)})
    return next_pos
            
def solution(board):
    answer = 0
    n = len(board)
    new_board = [[1] * (n + 2) for _ in range(n + 2)]   # 벽을 바깥에 만들어줌
    for i in range(n):
        for j in range(n):
            new_board[i + 1][j + 1] = board[i][j]
    q = deque()
    visited = []    # 방문한 pos 등록
    pos = {(1, 1), (1, 2)}
    q.append((pos, 0))
    visited.append(pos)
    while q:
        pos, cost = q.popleft()
        if (n, n) in pos:   # 끝점에 도달하면 
            return cost     # 시간 반환
        for next_pos in get_next_pos(pos, new_board):   #이동 가능한 점들
            if next_pos not in visited:                 #들린 적 없으면
                q.append((next_pos, cost + 1))
                visited.append(next_pos)
    return 0

0개의 댓글