알고리즘/프로그래머스

[프로그래머스 | Lv2] 조이스틱 (Python)

sssbin 2023. 4. 11. 23:04

 

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

1. 상하이동 더하기 (A-Z)

- 아스키코드를 이용해 앞에서부터 더한 것과 뒤에서부터 더한 것 중 최솟값을 찾아준다.

 

2. 좌우이동의 최소 구하기

 1) 'A'가 연속해서 나오는 위치를 찾아준다.

   - temp 리스트를 만들어서 연속된 인덱스들을 리스트로 묶어서 넣어줬다.

 2) 기존 방식(앞으로 쭉 가기) / 앞으로 갔다가 뒤로 돌아가기 / 뒤로 갔다가 앞으로 돌아가기 중 최솟값

   - 기존 방식(앞으로 쭉 가기): len(name) - 1

   - 앞으로 갔다가 뒤로 돌아가기: ('A'가 처음 나오는 곳 앞의 알파벳 개수 - 1) * 2 + 'A'가 마지막으로 나오는 곳 뒤의 알파벳 개수

   - 뒤로 갔다가 앞으로 돌아가기: 'A'가 마지막으로 나오는 곳 뒤의 알파벳 개수 * 2 + ('A'가 처음 나오는 곳 앞의 알파벳 개수 - 1)

 

3. answer = 1 + 2

 

# 프로그래머스 42860: 조이스틱

def solution(name):
    answer = 0
    for i in name: # 상하이동 먼저 다 더하기
        answer += min(ord(i) - 65, 91 - ord(i))
    
    temp = [] # 연속된 A의 인덱스를 저장할 리스트
    for i in range(1, len(name)):
        if name[i] == 'A':
            if temp and temp[-1][-1] == i-1:
                temp[-1].append(i)
                continue
            temp.append([i])
    
    res = len(name) - 1 # 기존 방식
    for i in temp:
        # (기존 방식, 앞으로 갔다가 뒤로 돌아가기, 뒤로 갔다가 앞으로 돌아가기)의 최솟값
        res = min(res, 2 * (i[0] - 1) + len(name) - 1 - i[-1], 2 * (len(name) - 1 - i[-1]) + i[0] - 1)
            
    return answer + res

 

예외 케이스를 잡기가 힘들었던 문제다.

맞는 거 같은데 자꾸 실패해서 질문하기를 뒤져서 테스트케이스들을 모조리 넣어보고 수정하면서 성공했다..