Programmers

[프로그래머스] 조이스틱 / Python

개발하는 사막여우 2021. 1. 18. 15:50
반응형

문제주소 :programmers.co.kr/learn/courses/30/lessons/42860

 


<문제 설명>

더보기

문제 설명

조이스틱으로 알파벳 이름을 완성하세요. 맨 처음엔 A로만 이루어져 있습니다.
ex) 완성해야 하는 이름이 세 글자면 AAA, 네 글자면 AAAA

조이스틱을 각 방향으로 움직이면 아래와 같습니다.

▲ - 다음 알파벳 ▼ - 이전 알파벳 (A에서 아래쪽으로 이동하면 Z로) ◀ - 커서를 왼쪽으로 이동 (첫 번째 위치에서 왼쪽으로 이동하면 마지막 문자에 커서) ▶ - 커서를 오른쪽으로 이동

예를 들어 아래의 방법으로 JAZ를 만들 수 있습니다.

- 첫 번째 위치에서 조이스틱을 위로 9번 조작하여 J를 완성합니다. - 조이스틱을 왼쪽으로 1번 조작하여 커서를 마지막 문자 위치로 이동시킵니다. - 마지막 위치에서 조이스틱을 아래로 1번 조작하여 Z를 완성합니다. 따라서 11번 이동시켜 "JAZ"를 만들 수 있고, 이때가 최소 이동입니다.

만들고자 하는 이름 name이 매개변수로 주어질 때, 이름에 대해 조이스틱 조작 횟수의 최솟값을 return 하도록 solution 함수를 만드세요.

제한 사항

  • name은 알파벳 대문자로만 이루어져 있습니다.
  • name의 길이는 1 이상 20 이하입니다.

입출력 예

name                                                                  return
JEROEN 56
JAN 23

 

<풀이법>

▒ 한줄 개념: 탐욕법? ▒ 

이 문제는 탐욕법에 분류되어 있습니다. 하지만 탐욕법이라고 하기엔 애매한 문제입니다.

탐욕법으로 풀 수는 있지만, 탐욕법으로 풀 경우 최적해가 나오지 않는 경우가 존재합니다.

완전한 최적해를 풀기 위해서는 조건이 많이 필요하므로, DFS나 BFS 등의 완전탐색 기법이 요구될 것 같습니다.

저 같은 경우는 완전한 최적해를 탐욕적으로 풀려고 하다 시간을 많이 낭비했습니다.

 

일단 탐욕법으로 푸는 방식은 다음과 같습니다.

  • 모든 target 문자에 대해 A로부터의 거리Z로부터의 거리작은 값 저장( target문자 A일 경우 변환 필요없으므로 값 0 넣어줌)
  • left, right 각각 1씩 늘려가며 target 문자 A가 아닌 문자에 먼저 도달하는 경우 찾기.
  • left, right 중 더 짧은 거리의 위치로 이동하여 반복

 

<코드(Python)>


def solution(name):  # 65~90(A~Z)
    moves = [min(ord(s) - ord('A'), ord('Z') - ord(s) + 1) for s in name]

    pos = 0
    answer = 0
    while True:
        answer += moves[pos]
        moves[pos] = 0

        if sum(moves) == 0: break

        left = 1
        right = 1

        while moves[pos - left] == 0:
            left += 1

        while moves[pos + right] == 0:
            right += 1

        if left >= right:
            pos += right
            answer += right

        else:
            pos -= left
            answer += left

    return answer

 

 

더 많은 코드 보기(GitHub) : github.com/dwkim-97/CodingTest

 

 

반응형