Python Programming/[Programmers] Algorithm

[프로그래머스] 공원 산책 Python 풀이

간토끼 2023. 8. 8. 12:00
728x90

# 해당 포스팅은 이제 막 알고리즘 공부를 시작한 초보 수준에서 작성했음을 이해해주시고, 비난보다는 따뜻한 조언을 부탁드립니다.


안녕하십니까, 간토끼입니다.

오늘은 프로그래머스(Programmers) 공원 산책 문제를 다뤄보겠습니다.

첫 프로그래머스 문제라 난이도를 볼 겸 Lv.1 문제 중 정답률이 제일 낮은 문제로 골라봤습니다.

 

1. 문제 링크

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

 

프로그래머스

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

programmers.co.kr

지나다니는 길을 O, 장애물을 X로 나타낸 직사각형 격자 모양의 공원에서 로봇 강아지가 산책을 할 때, 주어진 명령에 따라서 산책 후 도착하는 좌표를 출력하는 문제입니다.

입력은 park와 routes 라는 list로 주어지고, 이때 park는 공원의 사이즈와 출발지점(S), 길(O), 장애물(X)로 이루어져 있으며, 만약 list의 첫 원소가 "SOO" 이면 (0,0)이 출발지점(S), (0,1),(0,2)는 지나갈 수 있는 길입니다.

즉 park의 각 원소의 길이는 열의 개수를 의미하고, park의 길이(len(park))는 행의 개수를 의미합니다.

routes는 방향(동서남북)과 걸음 수를 알려주고, "E 5"는 동쪽으로 5칸 이동하라는 의미입니다.

이때 가려는 방향에 장애물이 있다면 해당 이동 명령은 무시하게 됩니다.

생각보다 문제를 이해하는 게 어렵더라고요.

 

2. 접근 방법

다음과 같이 접근하였습니다.

먼저 주어진 park에 맞게 직사각형 NxM 사이즈의 맵(map)을 구성합니다. 이때 2차원 배열을 활용해야겠죠.

그리고 주어진 문자열(S,O,X)에 따라 맵을 채워주되, S는 별 다른 변형을 하지 않고 O면 0, X면 1로 채워줬습니다.

이후 배열 내 S의 인덱스를 출발 위치의 좌표 r,s로 설정했습니다.

그리고 routes의 각 원소는 "E 5" 형태의 문자열로 돼있으므로 0번째 원소는 방향, 2번째 원소는 걸음 수입니다.

이를 각각 direction과 step으로 구분하여 저장합니다.

그리고 행 번호의 움직임(N, S)과 열 번호의 움직임(E, W)를 구분해서 걸음 수를 산정했습니다.

"E 5"면 동쪽으로 5걸음이니 행 번호는 바뀌지 않고 열 번호만 +5로 바뀌겠죠.

이때 바뀐 위치가 Map을 초과하는지, 혹은 장애물을 만나는지를 따져줘야 합니다.

어려운 부분이 장애물을 만나는지 여부인데요.

만약 동쪽으로 5걸음을 이동하다가 중간에 장애물이 있는 경우(Ex. 3걸음째)에도 이 이동명령은 무효가 됩니다.

이를 구현하기 위해 5걸음을 한번에 이동하지 않고 1걸음씩 이동하면서 장애물을 만나는지 따져주었고, 만약 만날 경우 error라는 변수로 count를 해줬습니다.

최종적으로 error가 존재하면 해당 이동명령은 무효고, 그렇지 않으면 이동하는 방식으로 구현했는데요.

솔직히 아직 알고리즘 짜는 게 어렵네요. 파이썬 기본 문법도 많이 흔들리는 것 같고요.

아무튼 어찌어찌 굴러는 가는데 코드가 굉장히 지저분한 게 단점입니다.

알고리즘 공부 5일차인 만큼 보완해야 할 점이 눈에 보이는 문제였습니다 ... ㅜㅜ

 

3. 코드

# 프로그래머스
# 공원 산책
def solution(park, routes):
# park 구성
# 출발 지점 : S
# 길 0, 장애물 1로 코딩
    map_array = []
    park_list = ["S", "O", "X"]
    for i in range(len(park)):
        park_i = park[i]
        len_i = len(park_i) #park[i] 원소의 길이
        i_list = []
        for j in range(len_i):
            if park_i[j] == "S":
                i_list.append("S")
                r, c = i, j # r,c : 출발지점 좌표(r,c)
            elif park_i[j] == "O":
                i_list.append(0)
            else:
                i_list.append(1)
        map_array.append(i_list)

    directions = ["N", "S", "W", "E"]
    d_row = [-1, 1, 0, 0]
    d_col = [0, 0, -1, 1]

    for k in routes:
        error = 0
        d = k[0] # 방향 : N S W E
        step = int(k[2]) # 걸음수

        if d in directions:
            idx = directions.index(d)
            next_row = r + d_row[idx]*step
            next_col = c + d_col[idx]*step

            if next_row < 0 or next_row > (len(map_array)-1):
                continue

            elif next_col < 0 or next_col > (len(map_array[1])-1):
                continue

            elif d_row[idx]*step != 0:
                for l in range(1, step+1):
                    next_row = r + d_row[idx]*l
                    if map_array[next_row][next_col] == 1:
                        error += 1

            elif d_col[idx]*step != 0:
                for l in range(1, step+1):
                    next_col = c + d_col[idx]*l
                    if map_array[next_row][next_col] == 1:
                        error += 1
            if error > 0:
                r,c = r,c
            elif error == 0:
                r = next_row
                c = next_col

    result = [r,c]
    return result

 

감사합니다.

잘 읽으셨다면 게시글 하단에 ♡(좋아요) 눌러주시면 감사하겠습니다 :)

(구독이면 더욱 좋습니다 ^_^)

* 본 블로그는 학부생이 운영하는 블로그입니다.

따라서 포스팅에 학문적 오류가 있을 수 있으며, 이를 감안해서 봐주시면 감사하겠습니다.

 


- 간토끼(DataLabbit)

- B.A. in Economics, Data Science at University of Seoul

728x90