coding test

[파이썬] 조이스틱

잔망루피 2020. 12. 31. 21:32

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 하도록 solution 함수를 만드세요.

 

제한 사항

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

입출력 예

name return
JEROEN 56
JAN 23

출처

※ 공지 - 2019년 2월 28일 테스트케이스가 추가되었습니다.

 

 

나의 풀이

# 실패
import string

uppercase=list(string.ascii_uppercase)

def calculation(name, answer) :
    idx=uppercase.index(name)
    if 13 < idx :      # 아래로 움직이기
        answer+=(26-idx)
    elif idx != 0 :          # 위로 움직이기
        answer+=idx
    return answer

        
def solution(name):
    answer = 0
    size=len(name)
    make_name="A" * size
    
    for i in range(1, size-1) :
        answer=calculation(name[i], answer)
        answer += 1         # 방향키
    
    if answer == size-2 :       # 가운데에 A만 있음
        answer-=1
    
    answer=calculation(name[0], answer)
    
    answer=calculation(name[-1], answer)
        
    return answer+1      # 조작 횟수의 최솟값

가운데랑 처음, 끝은 따로 계산

 

 

# 3, 4, 5, 7, 11 실패 = 총점 54.5
def solution(name):
    answer = 0
    length=len(name)
    alpha=['A']*length
    direction=[1, -1, -1, 1]
    position=[i for i, j in enumerate(name) if j != 'A']
    
    
    for i in range(length):
        if name[i] == 'A':
            continue
        desc=abs(ord('Z')-ord(name[i]))+1
        asc=abs(ord('A')-ord(name[i]))
        #print(desc, asc)
        if asc < desc :
            answer+=asc
        else:
            
            answer+=desc
        #desc=abs(ord('Z')-ord(n))
        
    return answer+len(position)-1

문제 자체를 이해못했음.

테스트케이스의 "JEROEN"이 56이 나오는게 이해안됨ㅋ

 

"JEROEN"= 51, 기댓값은 56

J=9

E=4

R=9 

O=12 

E=4 

N=13

 

그 다음 알파벳으로 이동하니까 51+5=56

# 모르겠는 것

커서를 왼쪽으로 이동하는 경우를 구해야함.

목표 위치까지의 거리를 계산한다(앞뒤로).

 

 

🗝 다른사람 풀이

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

모두 A로 이루어진 경우 0을 바로 리턴해준다는 점을 주의하자.

1) left_moved='JEROEN'

right_moved='JEROEN'

right_moved[:0:-1]='NEORE'은 0번째 인덱스를 제외하고 거꾸로 뒤집은 것

n='JEROEN'

row_move는 방향키 이동 횟수

col_move에 a에서 시작했을 때와 z에서 시작했을 때 둘중에 차이가 더 작은 값을 더한다.

1-1) n='JNEORE'

 

2) left_moved='NJEROE'

right_moved='EROENJ'

n='NJEROE'

row_move=6

2-1) n='EJNEOR'

row_move=6

 

left_moved는 인덱스 0에서 왼쪽으로 가는 것

right_moved는 인덱스 0에서 오른쪽으로 가는 것

출발점의 방향이다.

while n and n[-1] == 'A'는 'A'를 제외시키는 부분이다.

'A'가 있는 곳은 바꿀 필요가 없으니까

row_move에 i를 더하는 이유는 인덱스 0이 아닌 다른 위치에서 시작하는 방향키 이동 횟수

 

'JEROEN'같은 경우는

left_moved right_moved right_moved[0] + right_moved[:0:-1]
JEROEN JEROEN JNEORE
NJEROE EROENJ EJNEOR
ENJERO ROENJE REJNEO

right_moved[0] + right_moved[:0:-1]은 <- 방향

 

 

 

문제 출처 👉 프로그래머스

반응형

'coding test' 카테고리의 다른 글

[파이썬] 4831. 전기버스  (0) 2021.01.04
[파이썬] 풍선 터트리기  (0) 2021.01.04
[파이썬, Java] 다리를 지나는 트럭  (0) 2020.12.28
[파이썬] 약수의 합  (0) 2020.12.24
[파이썬] 이진 변환 반복하기  (0) 2020.12.24