일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- Best of the Best
- 논문리뷰
- 철학
- 사회적 사실
- 코드엔진
- 코드엔진 basic 5
- BoB 12기
- bob
- codeengn basic rce 01
- malware
- CodeEngn Basic 5
- 디지털 포렌식 트랙
- CodeEngn Basic 01
- 리버싱
- h4ckinggame
- CodeEngn
- 사회분업론
- BoB 12기 최종합격 후기
- 자살론
- 코드엔진 베이직
- 에밀 뒤르켐
Archives
- Today
- Total
SEO
[프로그래머스/파이썬] 조이스틱 본문
반응형
문제 설명
조이스틱으로 알파벳 이름을 완성하세요. 맨 처음엔 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 |
제 문제 풀이에서 핵심(?)은 문자 변경과 커서 이동이 서로 영향을 미치지 않는다는 점입니다.
문자 변경과 커서 이동 각각의 최소 비용을 구하는 방법은 바로 생각이 났는데, 이걸 순서대로 문자 변경하고, 커서 이동하고… 이런식으로 계산하려고 하다 보니 풀이가 너무 복잡해지더라고요.
알고보니 문자 변경(↑, ↓)과 커서 이동(←, →)은 서로 영향을 미치지 않았습니다.
그래서 각각의 비용은 다음과 같이 계산하였습니다.
- 문자 조작 비용 계산
- 특정 위치에서 문자를 변경하는 비용은 A-Z 간 최소 이동 거리로 결정됩니다. 그래서 A에서 목표 문자로 가는 거리와 Z에서 문자로 가는 거리 +1 중 최솟값을 선택하도록 합니다.
- 커서 이동 비용 계산
- 기본적으로 오른쪽으로 한 칸씩 이동하면서 끝까지 가는 경우가 최악의 경우인데, 중간에 ‘A’가 연속으로 등장한다면 뒤로 돌아가는 방법이 효율적일 수도 있습니다.
- 따라서 오른쪽으로 끝까지 가는 경우(len(name) - 1)를 초기값을 설정하고, A를 만났을 경우를 대비하여 앞으로 갔다가 뒤로 가는 것과 뒤로 갔다가 앞으로 가는 것 중 어떤 것이 효율적인지 비교하였습니다.
⇒ 두가지 경우의 수가 같은 목표일 필요는 없습니다. 그냥 “현재”의 경우에서 가장 최소로 이동하여 도착할 수 있는, 탐색하지 않은, A가 아닌 문자까지의 거리를 구하는 과정입니다.
def solution(name):
answer = 0
compare = list(name)
compare_length = len(compare)
for i in range(compare_length):
res = ord(compare[i])
answer += min(abs(res - 65), abs(90 - res + 1))
min_move = compare_length - 1
for i in range(compare_length):
next_idx = i + 1
while next_idx < compare_length and compare[next_idx] == 'A':
next_idx += 1
move = min(2 * i + (compare_length - next_idx), i + 2 * (compare_length - next_idx))
min_move = min(min_move, move)
answer += min_move
return answer
반응형
'코딩테스트 > 문제 풀이' 카테고리의 다른 글
[프로그래머스/파이썬] 3월에 태어난 여성 회원 목록 출력하기 (0) | 2025.02.11 |
---|---|
[프로그래머스/파이썬] 평균 일일 대여 요금 구하기 (1) | 2025.02.11 |
[프로그래머스/파이썬] 체육복 (0) | 2025.02.06 |
[프로그래머스/파이썬] 모음사전 (0) | 2025.02.02 |
[프로그래머스/파이썬] 전력망을 둘로 나누기 (1) | 2025.02.01 |