[프로그래머스] 코딩테스트 풀이 - 조이스틱

Reference : 프로그래머스 코딩 테스트 연습

문제 설명

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

조이스틱을 각 방향으로 움직이면 아래와 같습니다.

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

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

1
2
3
4
- 첫 번째 위치에서 조이스틱을 위로 9번 조작하여 J를 완성합니다.
- 조이스틱을 왼쪽으로 1번 조작하여 커서를 마지막 문자 위치로 이동시킵니다.
- 마지막 위치에서 조이스틱을 아래로 1번 조작하여 Z를 완성합니다.
따라서 11번 이동시켜 "JAZ"를 만들 수 있고, 이때가 최소 이동입니다.

만들고자 하는 이름 name이 매개변수로 주어질 때, 이름에 대해 조이스틱 조작 횟수의 최솟값을 return 하도록 solution 함수를 만드세요.

제한 조건

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

입출력 예

name return
“JEROEN” 56
“JAN” 23

조건 분석

  • 나와야 하는 결과

    1
    조이스틱 조작 횟수의 [최솟값]
  • 문제를 풀기위해 주어진 데이터

    1
    2
    3
    4
    5
    6
    7
    8
    # 문제 해결에 필요한 데이터

    1. 조이스틱 조작방식에 대한 정보
    2. 만들어야하는 이름의 정보

    # 제한조건
    - 알파벳 대문자로만 이루어져 있음
    - 길이가 1~20까지
  • 간단 알고리즘

    1
    1. Greedy 알고리즘을 사용해서 각 칸의 최적해를 찾아낸다.

나의 풀이

사용언어 : Python 3

매 Case 마다 최적값이 달라지므로 Greedy 알고리즘을 사용해서 푸는 문제이다.
그때그때 최적의 해를 찾아서 푸는 문제이므로 각 칸에서의 최적해를 구하는 방식을 찾는다.

  • 왼쪽/오른쪽 중 어떤 조작을 해야 알파벳을 빨리 찾을 수 있는지 조건을 넣는다.

    • A가 아닌 알파벳에 가장 가까운 방향으로 진행시킨다.
      1. 현재값이 A가 아니면 위아래 조작으로 넘어간다
      2. 현재값이 A일 경우 A가 아닌 값이 왼쪽으로 몇번째에 있는지 찾는다.
      3. 현재값이 A일 경우 A가 아닌 값이 오른쪽으로 몇번째에 있는지 찾는다.
      4. 두 값을 비교하고 이동횟수가 적은쪽으로 이동하고 A 갯수만큼 answer에 값을 추가한다.
  • 위/아래 중 어떤 조작을 해야 알파벳을 빨리 찾을 수 있는지 조건을 넣는다.

    • A~Z의 중간값인 N(위 13회, 아래 13회) 을 기준으로 나눈다.
      1. name 문자가 N보다 크거나 같으면 아래, 작으면 위 if문으로 들어간다.
        1. name 문자가 N보다 작을 때 아스키코드와 A의 아스키코드를 빼서 차 값을 answer에 넣는다
        2. name 문자가 N보다 크거나 같을 때 아스키코드와 Z+1의 아스키코드를 빼서 차 값을 answer에 넣는다
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
29
30
31
32
33
34
def solution(name):
answer = 0
name = list(name)
base = ["A"] * len(name)
idx = 0

while True:
rIndex = 1
lIndex = 1
if name[idx] != "A":
if name[idx] < "N":
answer += ord(name[idx]) - 65
else:
answer += 91 - ord(name[idx])
name[idx]="A"
if name == base:
break
else:
for i in range(1, len(name)):
if name[idx + i] == "A":
rIndex += 1
else:
break
if name[idx - i] == "A":
lIndex += 1
else:
break
if rIndex > lIndex:
answer += lIndex
idx -= lIndex
else:
answer += rIndex
idx += rIndex
return answer
공유하기