Lv1. 공원산책

zz·2023년 5월 13일
0

프로그래머스

목록 보기
33/36
post-custom-banner

[Lv1. 공원산책]

문제 설명

지나다니는 길을 'O', 장애물을 'X'로 나타낸 직사각형 격자 모양의 공원에서 로봇 강아지가 산책을 하려합니다. 산책은 로봇 강아지에 미리 입력된 명령에 따라 진행하며, 명령은 다음과 같은 형식으로 주어집니다.

["방향 거리", "방향 거리" … ]
예를 들어 "E 5"는 로봇 강아지가 현재 위치에서 동쪽으로 5칸 이동했다는 의미입니다. 로봇 강아지는 명령을 수행하기 전에 다음 두 가지를 먼저 확인합니다.

주어진 방향으로 이동할 때 공원을 벗어나는지 확인합니다.
주어진 방향으로 이동 중 장애물을 만나는지 확인합니다.
위 두 가지중 어느 하나라도 해당된다면, 로봇 강아지는 해당 명령을 무시하고 다음 명령을 수행합니다.
공원의 가로 길이가 W, 세로 길이가 H라고 할 때, 공원의 좌측 상단의 좌표는 (0, 0), 우측 하단의 좌표는 (H - 1, W - 1) 입니다.

park

공원을 나타내는 문자열 배열 park, 로봇 강아지가 수행할 명령이 담긴 문자열 배열 routes가 매개변수로 주어질 때, 로봇 강아지가 모든 명령을 수행 후 놓인 위치를 [세로 방향 좌표, 가로 방향 좌표] 순으로 배열에 담아 return 하도록 solution 함수를 완성해주세요.

제한사항

  • 3 ≤ park의 길이 ≤ 50
    - 3 ≤ park[i]의 길이 ≤ 50
  • park[i]는 다음 문자들로 이루어져 있으며 시작지점은 하나만 주어집니다.
    - S : 시작 지점
    - O : 이동 가능한 통로
    - X : 장애물
  • park는 직사각형 모양입니다.
    - 1 ≤ routes의 길이 ≤ 50
    - routes의 각 원소는 로봇 강아지가 수행할 명령어를 나타냅니다.
    - 로봇 강아지는 routes의 첫 번째 원소부터 순서대로 명령을 수행합니다.
    - routes의 원소는 "op n"과 같은 구조로 이루어져 있으며, op는 이동할 방향, n은 이동할 칸의 수를 의미합니다.
  • op는 다음 네 가지중 하나로 이루어져 있습니다.
    - N : 북쪽으로 주어진 칸만큼 이동합니다.
    - S : 남쪽으로 주어진 칸만큼 이동합니다.
    - W : 서쪽으로 주어진 칸만큼 이동합니다.
    - E : 동쪽으로 주어진 칸만큼 이동합니다.
  • 1 ≤ n ≤ 9

입출력 예

parkroutesresult
["SOO","OOO","OOO"]["E 2","S 2","W 1"][2,1]
["SOO","OXX","OOO"]["E 2","S 2","W 1"][0,1]
["OSO","OOO","OXO","OOO"]["E 2","S 3","W 1"][0,0]

내 풀이

def solution(park, routes):
    
    # pos = currPos
    pos = [0,0] # row, column = dy, dx
    
    # find S
    for idx, row in enumerate(park): 
        if "S" in row:
            pos[0] = idx
            pos[1] = row.find("S")
    # print("S pos: ", pos)
    # nx dx
    dx = {"N" : 0, "S" :  0, "E" : 1, "W" : -1}
    dy = {"N" : -1, "S" : 1, "E" : 0, "W" : 0}
    
    # execute oper
    for route in routes:
        direc, step = route.split(" ")
        if isValid(pos, direc, step, park):
            pos[1] = pos[1] + int(step) * dx[direc] 
            pos[0] = pos[0] + int(step) * dy[direc] 
            # print("pos after move :", pos)
        else:
            # print(direc, step , " is not valid oper")
            continue
            
    return pos

def isValid(pos, direc, step, park):

    # w, h, dx, dy
    dx = {"N" : 0, "S" :  0, "E" : 1, "W" : -1}
    dy = {"N" : -1, "S" : 1, "E" : 0, "W" : 0}
    # size
    width, height = len(park[0]),len(park) 
    
    ny, nx = pos
    print(direc, step)
    for i in range(int(step)):
        nx = nx + dx[direc]
        ny = ny + dy[direc]
        # if nx/ny in the right pos (inner)
        if 0 <= nx < width and 0 <= ny < height :
            if ((park[ny][nx] == "X")) :
                return False
        # if nx < 0 or ny < 0 or ny >= height or nx >= width :   (outer) 
        else:
            return False
        # print("    curPos moving: ", pos, direc, step, " nx, ny : ", nx, ny)
        # printPark(park)
    return True

# def printPark(park):
#     for i in park:
#         print(i)

굉장히 조잡하다..! 처음 짜 본 미로 탐색 코드라서 그럴지도요
미로에서 가장 주의해야할 점은 우리가 평소에 다르던 좌표랑 다르다는 것이다..! 문제만 잘 읽었어도 눈치 챌 수 있었을지도 모르겠는데

  • pos = [0,0]

이라고 적은 후에 당연히 x, y 좌표라고 생각하고 다뤘는데 알고 보니 y,x였다 matrix 를 다루는 법을.. 잊어버린거죠.. 네.. ㅋㅋㅋ ㅋ
진행 방향에 따라 달라지는 것이니 이걸 주의해서 해야겠다

그리고 또 놀라운 점.. dx, dy 를 함수마다 설정해줬는데 그냥 global variable로 주고 싶으면 def solution 위에.. 그냥.. 정의해주면 되는거였어요 멍청아

자꾸 에러가 나서 여러가지 프린트를 해가면서 오류를 고쳐나갔다
print park 함수를 따로 짜서 X를 잘 피해가는지도 확인해주었다

풀 때는 자꾸 에러 나서 너무너무너무너무 짜증났는데 하고 나니까 행복하네요
그리고 풀 때는 아.. 코드 너무 긴가? 이런 생각만 계속 했었는데 다 끝내고 다른사람들 풀이 구경하니까 다들 저만큼 길게 풀었더라고요 너무 걱정하지 말자 좋은 코드는 예쁜 코드나 읽기 쉬운 코드가 아니라 작동하는 코드 일뿐.. !

다른 사람 풀이

from collections import deque

def solution(park, routes):
    answer = []

    x = len(park)
    y = len(park[0])

    new_park = []

    for i in range(x):
        new_park.append(list(park[i]))
        if "S" in park[i]:
            start_x, start_y = i,park[i].index("S")

    for i in routes:
        where, how = i.split(' ')
        flag = 0

        if where == "E":
            if 0<=start_y+int(how)<y:
                for i in range(start_y,start_y+int(how)+1):
                    if new_park[start_x][i]=='X':
                        flag = 1
                        break
                if flag == 0:
                    start_y = start_y+int(how)

        elif where == "W":
            if 0<=start_y-int(how)<y:
                for i in range(start_y-int(how),start_y+1):
                    if new_park[start_x][i]=='X':
                        flag = 1
                        break
                if flag == 0:
                    start_y = start_y-int(how)

        elif where == "S":
            if 0<=start_x+int(how)<x:
                for i in range(start_x,start_x+int(how)+1):
                    if new_park[i][start_y]=='X':
                        flag = 1
                        break
                if flag == 0:
                    start_x = start_x+int(how)

        else:
            if 0<=start_x-int(how)<x:
                for i in range(start_x-int(how),start_x+1):
                    if new_park[i][start_y]=='X':
                        flag = 1
                        break
                if flag == 0:
                    start_x = start_x-int(how)

    return [start_x,start_y]

deque 를 사용했길래 눈에 들어왔던 문제

profile
응애 나 애기개발자
post-custom-banner

0개의 댓글