Python/CoTe

[programmers] 공원 산책 - 파이썬

joannekim0420 2024. 1. 24. 14:37
728x90

 

 

 

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

 

프로그래머스

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

programmers.co.kr

 

 

 

※ 주의사항

1. 흔히 우리가 수학에서 쓰는 좌표계를 (x,y)로 표시한다. 그러나 프로그래밍에서는 배열을 좌표로 생각한 접근은 보통 이중 for문으로 하게 되는데, Width 는 x 좌표, Height 는 y 좌표계로 접근한다. 

 

예를 들어, 아래와 같이 width 넓이가 4, height 높이가 3인 배열을 만들어서 이중 for 문으로 접근하면,

coordinate = [[0 for _ in range(4)] for i in range(3)]

# coordinate [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

for y in range(len(coordinate)):
	for x in range(len(coordinate[0]):
    	coordinate[y][x]

(x,y) 의 지점은 coordinate[y][x]로 접근하게 되는 것이다. 

len(coordinate)은 y축을 나타내고, len(coordinate[0])은 x축을 나타내기 때문.

 

어려운 것도 아니고 조금만 더 생각해보면 당연한 건데, 나는 너무 (x,y) 표현에 익숙해져서 [x][y] 이렇게 당연하게 쓰게 되는 실수가 있었다. 

 

2. 동서남북을 모르는 사람은 없겠지만, 그래도 역시 한 번 짚고 넘어가면, W 는 왼쪽, E 는 오른쪽, S 는 아래쪽, N 는 위쪽으로 이동하는 방향이다. 

 

3. 장애물의 확인

최종 도착 지점까지 이동하는 과정에 장애물이 한 개라도 있으면 그 명령을 시행하지 않는다. 

즉, 현재 출발 지점부터 목표지점 사이에 장애물이 있는지 모두 확인을 해야한다.

 

 

테스트 케이스 추가

park : ["SOOXO", "OOOXO", "OXOOO", "XOOOO"]

routes : ["E 2", "S 2", "W 2", "S 1", "W 1"]

return : [3, 1]

 

나 같은 경우는 2,3 번 모두 만족했는데 1번 주의사항을 헷갈려서 이 예제 테스트 케이스는 모두 통과해도 위 테스트 케이스에서 실패했다. 

 

 

※ 접근법

1. W/E/S/N 중 어떤 방향으로 이동하는지에 따라 목표 지점이 공원 구역을 벗어나는지 확인한다.
→ E 동쪽으로 이동하는 좌표는 x 값이 공원의 전체 길이보다 작으면 된다. 

→ N 북쪽으로 이동하는 좌표는 y 값이 0보다 크면 된다. 

...

...

 

2. 목표 지점이 공원 내라면, 이동 중에 장애물을 만나는지 확인한다. (함수 따로 정의)

  현재 지점 (x,y) 와 목표지점(x',y') 사이의 좌표를 for문으로 돌면서 해당 park[y][x]가 "X"라면 이동 자체를 하지 않는다. 

 

3. 위의 경우가 모두 True 인 조건에만 새로운 좌표로 업데이트

 

 






 

 

정답 코드

# 장애물이 있는지 확인하는 함수
def check_block(park, x, y, new, op):
	"""
    park : 공원 배열
    x, y : 현재 좌표
    new : 이동하려는 목표 지점. 이동은 한 방향으로만 이동하기 때문에 x 또는 y 값 하나만 받는다
    op : op 에 따라 이동하는 방향이 결정되므로 케이스를 나누기 위함
    """
    if op == "E":
        for i in range(x+1, new+1):
            if park[y][i] == "X":
                return False
    elif op == "S":
        for i in range(y+1, new+1):
            if park[i][x] == "X":
                return False
    elif op == "W":
        for i in range(new, x):
            if park[y][i] == "X":
                return False
    else:
        for i in range(new, y):
            if park[i][x] == "X":
                return False
    return True

def solution(park, routes):
    answer = []
    h,w = len(park), len(park[0])
    
    # 시작 지점 찾기
    for i, pos in enumerate(park):
        for j, p in enumerate(list(pos)):
            if p == "S":
                x, y = j,i
    
    for route in routes:
        op, n = route.split(" ")
        n = int(n)
        # and 로 차례대로 앞의 조건이 만족 될 때마다 그 다음 조건 확인
        if op == "E" and x+n < w and check_block(park, x, y, x+n, op):
            x += n	#목표 지점이 공원을 벗어나지 않고, 장애물이 없는 경우에만 좌표 업데이트
        elif op == "S" and y+n < h and check_block(park, x, y, y+n, op):
            y += n
        elif op == "W" and x-n >= 0 and check_block(park, x, y, x-n, op):
            x -= n
        elif op == "N" and y-n >= 0 and check_block(park, x, y, y-n, op):
            y -= n
    return [y,x]