알고리즘

[프로그래머스 lv2] 조이스틱.py

파뱁 2022. 4. 27. 23:01
728x90

<문제 설명>

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

 

코딩테스트 연습 - 조이스틱

조이스틱으로 알파벳 이름을 완성하세요. 맨 처음엔 A로만 이루어져 있습니다. ex) 완성해야 하는 이름이 세 글자면 AAA, 네 글자면 AAAA 조이스틱을 각 방향으로 움직이면 아래와 같습니다. ▲ - 다

programmers.co.kr

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

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

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

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

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

만들고자 하는 이름 name이 매개변수로 주어질 때, 이름에 대해 조이스틱 조작 횟수의 최솟값을 return 하면 되는 문제 이다.

 

입출력의 예는 다음과 같다.

name return
"JEROEN" 56
"JAN" 23

 

<문제 풀이 아이디어>

솔직히 탐욕법으로 풀었는데 안 풀려서 뭔가 하고 다른 사람의 풀이를 보니 거의 브루트포스에 가까운 문제 였다.

오른쪽으로 가다가 왼쪽으로 가는경우, 왼쪽으로 가다가 오른쪽으로 가는 모든 경우의 name 조합을 만들어서 풀었다.

(i가 0부터 시작하기 때문에 한쪽으로만 가는 경우도 포함)

 

출처 : https://programmers.co.kr/questions/26014

 

<문제 풀이 코드>

def solution(name):
    if set(name) == {'A'}:
        return 0

    answer = float('inf')
    for i in range(len(name) // 2): # 반 이상 움직일 필요 없음
        left_moved = name[-i:]+name[:-i]
        right_moved = name[i:]+name[:i]
        for n in [left_moved, right_moved[0]+right_moved[:0:-1]]:
            while n and n[-1] == 'A':
                n = n[:-1]

            row_move = i + len(n)-1
            col_move = 0
            for c in map(ord, n):
                col_move += min(c - 65, 91 - c)

            answer = min(answer, row_move + col_move)

    return answer

채점 결과

728x90
반응형