ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [python] 🏑프로그래머스 조이스틱 🏑
    파이썬/알고리즘 공부 2021. 10. 27. 23:03
    728x90

    조이스틱💢


    ❓문제설명

    조이스틱으로 알파벳 이름을 완성하세요. 맨 처음엔 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

    ➰문제접근방식

    • ✅알파벳은 상하로 조정하면서 MIN함수를 이용해 A로부터 가까운지, Z로부터 가까운지 판단해 담아두는 배열을 만들어 준다
     move = [min(ord(i) - ord("A"), ord("Z") - ord(i)) for i in name]
    [9, 4, 9, 8, 12, 13]
    • ✅왼쪽으로 가는게 효율적인지, 오른쪽으로 가는것이 효율적인지를 판단해 idx값을 변화시켜주고, 그 인덱스 변화에따른 이동횟수를 answer변수에 누적시켜 담아준다. 좌우로 이동한 횟수역시 answer에 같이 담아준다.
        answer += move[idx]
        .
        .
        .
    
        answer += left if left < right else right
    
        idx += -left if left < right else right
    • ✅answer함수에 이동횟수를 누적시켜 처리가 끝난 인덱스는 0 값으로 초기화를 시켜 move라는 리스트 함수안에 합이 0이되면 break를 시킬 수 있도록 구현을 한다
        move[idx] = 0
        if sum(move) == 0:
            break
    >>>[9, 4, 9, 8, 12, 13]
    >>>[0, 4, 9, 8, 12, 13]
    >>>[0, 0, 9, 8, 12, 13]
    >>>[0, 0, 0, 8, 12, 13]
         .
         .
         .
         .
    >>>[0, 0, 0, 0, 0, 0] 모두가 0이 돼었을때break를 해준다    
    • ✅left와 right에 이동횟수인 1을 넣어준다. 여기서 왼쪽으로 갈지 오른쪽으로 갈지를 결정하게 되는데 이미 처리된 인덱스 값인 0에 접근하는 것은 의미없는 루트이므로 이동한 곳에 값이 먄약 0인경우 1을 추가해 그 반대방향(1을 추가한 반대방향)으로 이동할 수 있도록 유도한다.
      ex) 왼쪽으로 접근했는데 그 값이 이미 처리되어 0일 경우 +1을 해주어 반대방향이 최소이동으로 채택될 수 있도록 하는 것이다
    left, right = 1, 1
            while move[idx - left] == 0:
                left += 1
                # print("move: ",move, "left :", left)
            while move[idx + right] == 0:
                right += 1
                # print("move:", move, "right :", right)
    
    >>> idx: 2 answer2: 15 left : 2 right : 1
    >>> idx: 3 answer2: 25 left : 3 right : 1
    >>> idx: 4 answer2: 34 left : 4 right : 1
    >>> idx: 5 answer2: 47 left : 5 right : 1
    >>>

    최종코드

    def solution(name):
        move = [min(ord(i) - ord("A"), ord("Z") - ord(i)+1) for i in name]
        idx, answer = 0, 0
    
        while True:
            answer += move[idx]
            move[idx] = 0
            if sum(move) == 0:
                break
    
            left, right = 1, 1
    
            while move[idx - left] == 0:
                left += 1
            while move[idx + right] == 0:
                right += 1
    
            answer += left if left < right else right
            idx += -left if left < right else right
    
        return answer
    print(solution("CBX"))

    '파이썬 > 알고리즘 공부' 카테고리의 다른 글

    [백준] 태권왕🦿  (0) 2021.11.03
    [python] 프로그래머스 K번째 수 🖖  (0) 2021.10.28
    [python] 🚨 다이나믹 프로그래밍  (0) 2021.10.26
    [python]Algo - 구현🔑  (0) 2021.10.21
    [python]Algo-Greedy💢  (0) 2021.10.21

    댓글

Designed by Tistory.