프로그래머스 Summer/Winter Coding(~2018) - 방문 길이

이환희·2021년 4월 22일
0

Algorithm

목록 보기
8/47

https://programmers.co.kr/learn/courses/30/lessons/49994

문제 설명

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

U: 위쪽으로 한 칸 가기

D: 아래쪽으로 한 칸 가기

R: 오른쪽으로 한 칸 가기

L: 왼쪽으로 한 칸 가기

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


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



이때, 우리는 게임 캐릭터가 지나간 길 중 캐릭터가 처음 걸어본 길의 길이를 구하려고 합니다. 예를 들어 위의 예시에서 게임 캐릭터가 움직인 길이는 9이지만, 캐릭터가 처음 걸어본 길의 길이는 7이 됩니다. (8, 9번 명령어에서 움직인 길은 2, 3번 명령어에서 이미 거쳐 간 길입니다)

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

제한사항

  • dirs는 string형으로 주어지며, 'U', 'D', 'R', 'L' 이외에 문자는 주어지지 않습니다.
  • dirs의 길이는 500 이하의 자연수입니다.

풀이

import copy

def solution(dirs):
    answer = 0
    curPos = [5, 5]
    histories = []
    for command in dirs:
        prePos = copy.deepcopy(curPos)
        if command == 'D':
            if curPos[1]+1 <= 10:
                curPos[1] += 1
                if [prePos, curPos] not in histories:
                    histories.append([copy.deepcopy(prePos), copy.deepcopy(curPos)])
                    histories.append([copy.deepcopy(curPos), copy.deepcopy(prePos)])
                    answer += 1
        elif command == 'U':
            if curPos[1]-1 >= 0:
                curPos[1] -= 1
                if [prePos, curPos] not in histories:
                    histories.append([copy.deepcopy(prePos), copy.deepcopy(curPos)])
                    histories.append([copy.deepcopy(curPos), copy.deepcopy(prePos)])
                    answer += 1
        elif command == 'R':
            if curPos[0]+1 <= 10:
                curPos[0] += 1
                if [prePos, curPos] not in histories:
                    histories.append([copy.deepcopy(prePos), copy.deepcopy(curPos)])
                    histories.append([copy.deepcopy(curPos), copy.deepcopy(prePos)])
                    answer += 1
        else:
            if curPos[0]-1 >= 0:
                curPos[0] -= 1
                if [prePos, curPos] not in histories:
                    histories.append([copy.deepcopy(prePos), copy.deepcopy(curPos)])
                    histories.append([copy.deepcopy(curPos), copy.deepcopy(prePos)])
                    answer += 1
    return answer
  • 현재 포지션을 curPos에 리스트로 넣어주고
  • 이전 포지션을 prePos에 리스트에 넣어줘서
  • 히스토리라는 리스트를 만들어 중복확인을 하고 [curPos, prePos] 인 길을 저장한다
  • 이때 [prePos, curPos]도 반대방향이지만 같은 길이므로 같이 저장해야하고
  • 저대로 저장하면 얕은 복사가 이루어져서 매번 바뀔때 마다 히스토리 안에 값도 바뀌기 때문에
  • copy의 deepcopy를 이용해 깊은복사를 해줘서 히스토리에 넣어준다
  • 넣어줬으면 answer를 하나 올려준다

다른 사람의 풀이

def solution2(dirs):
    s = set()
    d = {'U': (0, 1), 'D': (0, -1), 'R': (1, 0), 'L': (-1, 0)}
    x, y = 0, 0
    for i in dirs:
        nx, ny = x + d[i][0], y + d[i][1]
        if -5 <= nx <= 5 and -5 <= ny <= 5:
            s.add((x, y, nx, ny))
            s.add((nx, ny, x, y))
            x, y = nx, ny
    return len(s)//2
  • set을 사용하면 알아서 중복되는거 없애주고
  • 딕셔너리를 이용해 case 대신 활용한다
    이렇게 간편하게 풀 수 있다니 더 분발해야겠다

0개의 댓글