코딩테스트/PYTHON

[프로그래머스][PYTHON] Lv. 1 공원 산책

_알파카 2024. 8. 13. 15:45
728x90

문제 설명

https://school.programmers.co.kr/learn/courses/30/lessons/172928

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

이 문제는 주어진 캐릭터가 명령에 따라 이동하는 시뮬레이션 문제이다.

 

처음 풀이 (오답)

처음에 푼 풀이는 아래와 같다. 

def solution(park, routes):
    answer = []
    # 동, 서, 남, 북 방향을 표시함
    dx = [0, 0, 1, -1]
    dy = [1, -1, 0, 0]
    types = ["E", "W", "S", "N"]
    
    # 시작 지점은 S
    x, y = 0, 0
    
    # 공원의 길이
    h = len(park)
    w = len(park[0])
    
    # 시작 지점은 S
    # for i in range(h):
    #     if "S" in park[i]:
    #         x = i
    #         y = park[i].index("S")
    #         break
    x, y = 0, 0
    
    for r in routes:
        r = r.split(' ')
        op = r[0]
        n = int(r[1])
        
        print("어디로 이동?: ", op, n)

        for _ in range(n):
            nx = x + dx[types.index(op)]
            ny = y + dy[types.index(op)]

            
            # 장애물을 만난 경우 무시
            if park[nx][ny] == "X":
                break
            else:
                # 공간을 벗어나는 경우 무시
                if nx < 0 or ny < 0 or nx >= h or ny >= w:
                    break
                # 명령 수행
                x, y = nx, ny
                
        print(nx, ny)
        print("---------")
    
    answer.append(x)
    answer.append(y)

    return answer

 

첫 시작점 x, y를 0, 0으로 지정하면 테스트 케이스 1번과 2번에 대해서는 정답이 나온다. 

 

그러나 3번째 테스트케이스에서 범위를 벗어난다고 오답이라고 한다. 

# 공간을 벗어나는 경우 무시
if nx < 0 or ny < 0 or nx >= h or ny >= w:
    break

 

이 부분에서 오류가 나오는 것인데, 

어떻게 해결해야할지 잘 모르겠어서 GPT의 힘을 빌려 풀어보았다ㅠㅠ

 

 

정답 풀이

def solution(park, routes):
    answer = []
    # 동, 서, 남, 북 방향을 표시함
    dx = [0, 0, 1, -1]
    dy = [1, -1, 0, 0]
    types = ["E", "W", "S", "N"]
    
    # 공원의 길이
    h = len(park)
    w = len(park[0])
    
    # 시작 지점은 S
    for i in range(h):
        if "S" in park[i]:
            x = i
            y = park[i].index("S")
            break
    
    for r in routes:
        r = r.split(' ')
        op = r[0]
        n = int(r[1])
        
        print("어디로 이동?: ", op, n)
        
        # 변화할 좌표 저장(nx, ny)
        nx, ny = x, y
        for _ in range(n):
            # 한 번씩 이동 진행하며, 공원을 벗어나거나 장애물 있는 경우 판단
            nx += dx[types.index(op)]
            ny += dy[types.index(op)]

            
            # 공간을 벗어나는 경우 무시
            if nx < 0 or ny < 0 or nx >= h or ny >= w:
                break
                
            # 장애물을 만난 경우 무시
            if park[nx][ny] == "X":
                break

        else:
            # 명령 수행
            x, y = nx, ny
                
        print(nx, ny)
        print("---------")
    
    answer.append(x)
    answer.append(y)

    return answer

 

위의 풀이 방법은 먼저 공간을 벗어나는지 확인한 다음 장애물을 확인한다. 

또한, for-else 구문을 이용해 모든 이동이 유효한 경우에만 (break를 실행하지 않은 경우) 위치를 업데이트 하는 것이다! 

 

이제 모든 이동이 정상적으로 이동되는 것을 확인할 수 있다!

 

다른 사람 풀이

def solution(park, routes):
    # 위치 index
    x = 0
    y = 0 
    
    # 시작 위치 찾기
    for i in range(len(park)):
        for j in range(len(park[i])):
            if park[i][j] == 'S':
                x = j
                y = i
                break
    
    # 이동
    for route in routes:
        # 위치 초기화
        xx = x
        yy = y
        # 이동 - 장애물이 있거나 공원을 벗어나면 명령 무시
        for step in range(int(route[2])):
            # 동쪽 : 현재 위치가 map 가장 오른쪽이면 안됨, 이동할 곳이 장애물이면 안됨
            if route[0] == 'E' and xx != len(park[0])-1 and park[yy][xx+1] != 'X':
                xx += 1
                if step == int(route[2])-1:
                    x = xx # step만큼 움직였으면 위치 초기화
            # 서쪽 : 현재 위치가 map 가장 왼쪽이면 안됨, 이동할 곳이 장애물이면 안됨
            elif route[0] == 'W' and xx != 0 and park[yy][xx-1] != 'X':
                xx -= 1
                if step == int(route[2])-1:
                    x = xx
            # 남쪽 : 현재 위치가 map 가장 아래쪽이면 안됨, 이동할 곳이 장애물이면 안됨
            elif route[0] == 'S' and yy != len(park)-1 and park[yy+1][xx] != 'X':
                yy += 1
                if step == int(route[2])-1:
                    y = yy
            # 북쪽 : 현재 위치가 map 가장 위쪽이면 안됨, 이동할 곳이 장애물이면 안됨
            elif route[0] == 'N' and yy != 0 and park[yy-1][xx] != 'X':
                yy -= 1
                if step == int(route[2])-1:
                    y = yy
                    
    return [y, x]

 

def solution(park, routes):
    # 시작점('S') 찾기
    x, y = 0, 0
    for row in range(len(park)):
        for col in range(len(park[row])):
            if park[row][col] == 'S':  # 시작 지점 'S'
                x, y = row, col
    
    # 이동 방향 정의
    op = {'N':(-1, 0), 'S':(1, 0), 'W':(0, -1), 'E':(0, 1)}
    
    # 이동
    for i in routes:
        dx, dy = op[i.split()[0]]  # op에서 해당 방향에 맞는 이동 값 dx, dy로 가져오기
        n = int(i.split()[1])  # 이동 횟수
        
        xx, yy = x, y  # n번의 이동 동안 변하는 좌표 저장 xx, yy
        canmove = True  # 이동할 수 있는 route인지 확인
        
        # n번 이동해보기
        for _ in range(n):
            nx = xx + dx  # 이동한 위치
            ny = yy + dy  # 이동한 위치
            
            # 공원 안에 있고, 장애물이 아니면 이동 가능(True)
            if 0 <= nx <= len(park)-1 and 0 <= ny <= len(park[0])-1 and park[nx][ny] != 'X':
                canmove = True
                xx, yy = nx, ny
            else:  # 공원을 벗어낫거나, 장애물이면 이동 불가(False)
                canmove = False
                break
                
        if canmove:  # 이동이 가능하면 위치 반영해주기
            x, y = nx, ny  
        
    return [x, y]

 

위는 나와 비슷한 풀이이다. 

 

 

느낀점

끝까지 다 풀지는 못했지만, 그래도 어느정도 정답에 가깝게 풀 수 있어서 좋았던 문제였다. 

좀 더 노력해봐야겠다. 

728x90