[프로그래머스>그리디>Lv2] 조이스틱

Woonil·2022년 1월 6일
0

알고리즘

목록 보기
5/25

문제설명

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

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

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

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

접근

▲ - 다음 알파벳
▼ - 이전 알파벳 (A에서 아래쪽으로 이동하면 Z로)

두 가지 이동 방법 중에 최솟값을 찾아야함> min()> 알파벳 간의 거리를 알아야함> 아스키코드> ord()
◀ - 커서를 왼쪽으로 이동 (첫 번째 위치에서 왼쪽으로 이동하면 마지막 문자에 커서)
▶ - 커서를 오른쪽으로 이동

특정 위치에서 매번 좌우방향을 바꿀 수 있음>
마지막으로 바꿔야할 알파벳까지 가기 위해 이동해야 할 거리를 전체 이동거리라 할 수 있음>
현재 알파벳에서 다음 바꿔야 할 알파벳까지 가는 거리가 매번 최소가 되면 전체 이동거리가 최소가 됨>
그리디

풀이

def solution(name):
  // 각 알파벳에서의 위아래 방향스틱 조작횟수를 담은 리스트 upDown 
  (각 원소는 위방향으로 간 경우 아스키코드 차이와 아래방향으로 간 경우 아스키코드 차이 중 최솟값)
  upDown=[min(ord(_char)-ord('A'), ord('Z')-ord(_char)+1) for _char in name]
  // 인덱스, 전체 조작횟수 초기화
  index, move= 0, 0

  // 무한반복문 (break 조건: 모든 알파벳을 바꾼 경우)
  while True:
    // 전체 조작횟수에 현재 위아래 방향스틱 조작횟수 합함
    move+= upDown[index]
    // 현재 위치의 값을 0으로 초기화하여 나중에 다시 방문하지 못하도록 함
    upDown[index]=0

    if sum(upDown)==0:
      break

    right= 1
    left= 1
    
    // 알파벳이 'A'인 경우 계속해서 왼쪽 또는 오른쪽으로 이동
    while upDown[index-left]==0:
      left+=1
    while upDown[index+right]==0:
      right+=1
      
    // 둘 중 최솟값을 전체 조작횟수에 합함
    move+= left if left<right else right
    // 인덱스 이동
    index+= -left if left<right else right
  return move
profile
우니리개발일지

0개의 댓글