1. 문제설명
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 |
2. 풀이
1) 나의 화려한 오답
alpha_list = list("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
def get_alpha_gap(x1, x2):
index_gap = abs(alpha_list.index(x1) - alpha_list.index(x2))
if index_gap > 13:
index_gap = abs(index_gap - 26)
return index_gap
def solution(name):
total_cnt = 0
len_str = len(name)
name = list(name)
last_point = 0
total_cnt_list = []
for idx, chk_tok in enumerate(name):
if chk_tok == 'A':
continue
else:
if idx == 0 :
button_cnt = (get_alpha_gap('A', chk_tok))
else:
idx_gap = abs(idx - last_point)
if idx_gap > (len_str // 2):
idx_gap = abs(idx_gap - len_str)
button_cnt = (get_alpha_gap('A', chk_tok) + idx_gap)
if button_cnt > 0:
total_cnt_list.append(button_cnt)
last_point = idx
return sum(total_cnt_list)
우선 좌에서 우만 탐색을 하는 접근 자체가 잘못된거 같다.
가령 변경 순서가 엉키는 경우 (5번째 글자를 먼저 고쳐주고 3번째를 고치는게 더 빠른경우가 있을수 있는데 이 경우를 간과했음)
따라서 좌 우를 동시에 살피는 방법이 필요하다.
2) 다른 사람 풀이 참고
프로그래머스 문제 풀이 조이스틱
문제 URL 조이스틱 Contents 문제 지문 파악하기 구르미의 알고리즘 풀이 문제 지문 파악하기 이번에도 문제의 입력을 통해서, 문제를 파악해보도록 하겠습니다. 다음은, 문제의 입력입니다. 입력:
gurumee92.tistory.com
def solution(name):
# 1. 알파벳을 맞추는 최소 횟수를 저장하는 배열 m을 만듭니다.
m = [ min(ord(c) - ord("A"), ord("Z") - ord(c) + 1) for c in name ]
answer = 0
where = 0
# 2. 위치 where를 0부터 시작해서, 다음을 반복합니다.
while True:
# 1. m[where]를 answer에 더합니다
answer += m[where]
# 2. m[where]를 0으로 만듭니다.
m[where] = 0
# 3. 만약, 현재 m이 모두 0이라면, 반복을 멈춥니다.
if sum(m) == 0:
break
# 4. 3이 만족하지 않을 때, left, right를 1로 만듭니다.
left, right = (1, 1)
# 5. m[where-left] <= 0일 때까지, left를 1씩 증가시킵니다.
while m[where - left] <= 0:
left += 1
# 6. m[where+right] <= 0일 때까지 right를 1씩 증가시킵니다.
while m[where + right] <= 0:
right += 1
# 7. left, right를 비교합니다.
# 7-1. left < right 라면, answer에 left를 더하고, where에 -left를 더합니다.
# 7-2. 반대라면, answer에 right를 더하고 where에 right를 더합니다.
answer += left if left < right else right
where += -left if left < right else right
return answer
'Study > Algorithm & Data structure' 카테고리의 다른 글
[프로그래머스] 입국심사 (0) | 2020.10.28 |
---|---|
[프로그래머스] 큰 수 만들기 (0) | 2020.10.27 |
[프로그래머스][greedy] 구명보트 (201019) (0) | 2020.10.19 |
[백준] 킹(201017) (0) | 2020.10.17 |
[프로그래머스][greedy] 최소스패닝트리 (크루스칼)(201016) (0) | 2020.10.17 |
댓글