[프로그래머스/Lv2] 방문 길이

2022. 11. 17. 12:36

문제

게임 캐릭터를 4가지 명령어를 통해 움직이려 한다. 명령어는 다음과 같다.

 

- U: 위쪽으로 한 칸 가기

- D: 아래쪽으로 한 칸 가기

- R: 오른쪽으로 한 칸 가기

- L: 왼쪽으로 한 칸 가기

 

캐릭터는 좌표평면의 (0, 0) 위치에서 시작한다. 좌표평면의 경계는 왼쪽 위 (-5, 5), 왼쪽 아래 (-5, -5), 오른쪽 위 (5, 5), 오른쪽 아래 (5, -5)로 이루어져 있다.

 

그림 1

 

예를 들어, 'ULURRDLLU'로 명령했다면

그림 2

 

1번 명령어부터 7번 명령어까지 다음과 같이 움직인다.

 

그림 3

 

8번 명령어부터 9번 명령어까지 다음과 같이 움직인다.

그림 4

 

이때, 우리는 게임 캐릭터가 지나간 길 중 캐릭터가 처음 걸어본 길의 길이를 구하려고 한다.

예를 들어 위의 예시에서 게임 캐릭터가 움직인 길이는 9이지만, 캐릭터가 처음 걸어본 길의 길이는 7이 된다.

 

단, 좌표평면의 경계를 넘어가는 명령어는 무시한다.

 

명령어가 매개변수 dirs로 주어질 때, 게임 캐릭터가 처음 걸어본 길의 길이를 구하여 반환하는 함수를 만들어야 한다.

 

 

제한사항

1. dirs는 string형으로 주어지며, 'U', 'D', 'R', 'L' 이외에 문자는 주어지지 않는다.

2. dirs의 길이는 500 이하의 자연수이다.

 

 

코드

def solution(dirs):
    def U(x):
        if x[1]+1 > 5:
            return
        new_x = (x[0], x[1]+1)
        return new_x

    def D(x):
        if x[1]-1 < -5:
            return
        new_x = (x[0], x[1]-1)
        return new_x

    def R(x):
        if x[0]+1 > 5:
            return
        new_x = (x[0]+1, x[1])
        return new_x

    def L(x):
        if x[0]-1 < -5:
            return
        new_x = (x[0]-1, x[1])
        return new_x

    def tuple_add(t1, t2):
        return (t1[0]+t2[0], t1[1]+t2[1])

    x = (0, 0)
    route_list = []
    for c in dirs:
        if c == 'U':
            if U(x):
                new_x = U(x)
                route_list.append(tuple_add(x, new_x))
                x = new_x
        elif c == 'D':
            if D(x):
                new_x = D(x)
                route_list.append(tuple_add(x, new_x))
                x = new_x
        elif c =='R':
            if R(x):
                new_x = R(x)
                route_list.append(tuple_add(x, new_x))
                x = new_x
        else:
            if L(x):    
                new_x = L(x)
                route_list.append(tuple_add(x, new_x))
                x = new_x
    
    return len(set(route_list))

 

 

설명

특별한 방법없이 문제에서 주어진 대로 코드로 옮겼다.

그래서 그런지 코드 라인도 길고 지저분해 보이지만, 직관적이라고 생각한다.

 

우선 명령어에 해당하는 작업을 모두 함수로 만들어준다.

그 다음, 주어진 dirs배열의 명령어대로 게임 캐릭터를 이동시키는데 이미 지나갔던 길을 체크하기 위해

첫 좌표와 이동한 후의 좌표를 더한 값을 저장한다.

 

처음 코드를 짤 때는 (첫 좌표, 이동 후 좌표) 튜플로 표시했었는데 이렇게 기록하면 (A -> B)와 (B -> A)가 다른 길로 기록되기 때문에 더해서 비교하는게 더 정확하다고 생각했다.

 

def U(x):
    if x[1]+1 > 5:
        return
    new_x = (x[0], x[1]+1)
    return new_x

def D(x):
    if x[1]-1 < -5:
        return
    new_x = (x[0], x[1]-1)
    return new_x

def R(x):
    if x[0]+1 > 5:
        return
    new_x = (x[0]+1, x[1])
    return new_x

def L(x):
    if x[0]-1 < -5:
        return
    new_x = (x[0]-1, x[1])
    return new_x

각 명령어에 해당하는 작업을 함수로 만든 것이다.

좌표의 경계를 넘어가면 아무것도 반환하지 않는다.

 

def tuple_add(t1, t2):
    return (t1[0]+t2[0], t1[1]+t2[1])

튜플끼리의 합을 위해 만든 함수이다.

 

x = (0, 0)
route_list = []

x는 게임 캐릭터의 첫 좌표를 나타낸다.

route_list에 게임 캐릭터가 간 길을 기록해둘 것이다.

 

for c in dirs:
    if c == 'U':
        if U(x):
            new_x = U(x)
            route_list.append(tuple_add(x, new_x))
            x = new_x
    elif c == 'D':
        if D(x):
            new_x = D(x)
            route_list.append(tuple_add(x, new_x))
            x = new_x
    elif c =='R':
        if R(x):
            new_x = R(x)
            route_list.append(tuple_add(x, new_x))
            x = new_x
    else:
        if L(x):    
            new_x = L(x)
            route_list.append(tuple_add(x, new_x))
            x = new_x

dirs의 명령어 하나씩(c)을 꺼내며 반복한다.

c의 명령어를 확인하고 그에 해당하는 함수를 호출한다.

이때, 함수 결과가 아무것도 없다면(좌표 경계를 벗어난다면) 아무 작업을 하지 않는다.

그렇지 않다면 x(이전 좌표)와 new_x(새로운 좌표)를 더해서 route_list에 append한다.

 

return len(set(route_list))

route_list의 중복된 값들을 모두 제거하고 그 길이를 반환한다.

BELATED ARTICLES

more