[그리디] 조이스틱

yejichoi·2023년 7월 25일
0

알고리즘 스터디

목록 보기
79/153
post-thumbnail

조이스틱

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

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

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

  • 첫 번째 위치에서 조이스틱을 위로 9번 조작하여 J를 완성합니다.
  • 조이스틱을 왼쪽으로 1번 조작하여 커서를 마지막 문자 위치로 이동시킵니다.
  • 마지막 위치에서 조이스틱을 아래로 1번 조작하여 Z를 완성합니다.
    따라서 11번 이동시켜 "JAZ"를 만들 수 있고, 이때가 최소 이동입니다.
    만들고자 하는 이름 name이 매개변수로 주어질 때, 이름에 대해 조이스틱 조작 횟수의 최솟값을 return 하도록 solution 함수를 만드세요.

제한사항

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

입출력 예

namereturn
"JEROEN"56
"JAN"3

풀이


def solution(name):
    
    # 알파벳 변경 횟수( 상하 이동 ) 
    spell_move = 0
    
    # 커서 이동 횟수, 이름의 길이 - 1( 좌우 이동 )
    cursor_move = len(name) - 1  
    
    
    for i, spell in enumerate(name):
        print(i,spell,ord(spell),ord('Z'))
    	# 알파벳 변경 횟수, 위아래 중 최소 이동 값 ( 상하 이동 )
        spell_move += min(ord(spell) - ord('A'), 
        ord('Z') - ord(spell) + 1)
        #'Z'에서부터 이동하여 'B'를 만나는 경우 'Z'에서부터 2번 이동
        #이후에 'B'에서부터 'A'로 이동하는 경우 1번 이동, 
        #전체  2 + 1 = 3
        
        # 해당 알파벳 다음부터 연속된 A 문자열 찾기
        next = i + 1
        print("netx", next)
        while next < len(name) and name[next] == 'A':
            next += 1
            
        # 아래 3가지 경우 중 최소 이동 값으로 갱신
        # 1. 이전 커서 이동 값 ( 초기값 - 이름의 길이 - 1 )
        # 2. 연속된 A의 왼쪽 시작
        # 3. 연속된 A의 오른쪽 시작
        
        cursor_move = min([ cursor_move, 
        2 * i + len(name) - next, 
        i + 2 * (len(name) - next) ])
        
        
    # 조이스틱 조작 횟수 =
    #알파벳 변경 횟수( 상하 이동 ) + 커서 이동 횟수( 좌우 이동 )    
    print(spell_move , cursor_move)
    return spell_move + cursor_move

TIL

deque.rotate()

rotate() 메서드는 인자로 정수 값을 받음
만약 인자로 양수 값을 주면 덱의 요소들이 오른쪽으로 주어진 개수만큼 회전하며, 음수 값을 주면 왼쪽으로 주어진 개수만큼 회전

from collections import deque

# 덱 생성
my_deque = deque([1, 2, 3, 4, 5])

# 오른쪽으로 2번 회전
my_deque.rotate(2)
print(my_deque)  # 출력: deque([4, 5, 1, 2, 3])

# 왼쪽으로 3번 회전
my_deque.rotate(-3)
print(my_deque)  # 출력: deque([2, 3, 4, 5, 1])

from itertools import product

주어진 여러 개의 반복 가능한(iterable) 객체들로부터 가능한 모든 조합을 생성 => 데카르트 곱(cartesian product)
🐲 product((-1, 1), repeat=3) => (-1, 1) 두 개의 요소로 구성된 3개의 원소로 이루어진 가능한 모든 조합

from itertools import product

# 두 개의 리스트로 가능한 모든 조합 생성
list1 = [1, 2, 3]
list2 = ['a', 'b']
combinations = list(product(list1, list2))
print(combinations)
# 출력: [(1, 'a'), (1, 'b'), (2, 'a'),
#(2, 'b'), (3, 'a'), (3, 'b')]

# 세 개의 문자열로 가능한 모든 조합 생성
string1 = 'abc'
string2 = '12'
string3 = 'XYZ'
combinations = list(product(string1, string2, string3))
print(combinations)
# 출력: [('a', '1', 'X'), ('a', '1', 'Y'), ('a', '1', 'Z'),
#('a', '2', 'X'), ('a', '2', 'Y'), ... ]

enumerate(iterable, start=0)

인덱스와 해당 원소를 포함하는 enumerate 객체를 반환

🌾 ord('A')

주어진 문자의 유니코드 코드 포인트 값을 반환
유니코드 코드 포인트는 각 문자에 할당된 숫자 값으로, 예를 들어 'A'의 유니코드 코드 포인트는 65이고 'Z'의 유니코드 코드 포인트는 90

0개의 댓글