이번주 문제
조이스틱으로 알파벳 이름을 완성하는 문제. 맨 처음엔 A로만 이루어져 있음.
ex) 완성해야 하는 이름이 세 글자면 AAA, 네 글자면 AAAA
조이스틱 방향에 따른 의미
▲ - 다음 알파벳
▼ - 이전 알파벳 (A에서 아래쪽으로 이동하면 Z로)
◀ - 커서를 왼쪽으로 이동 (첫 번째 위치에서 왼쪽으로 이동하면 마지막 문자에 커서)
▶ - 커서를 오른쪽으로 이동 (마지막 위치에서 오른쪽으로 이동하면 첫 번째 문자에 커서)
ex) "JAZ"를 만드는 방법
- 첫 번째 위치에서 조이스틱을 위로 9번 조작하여 J를 완성합니다.
- 조이스틱을 왼쪽으로 1번 조작하여 커서를 마지막 문자 위치로 이동시킵니다.
- 마지막 위치에서 조이스틱을 아래로 1번 조작하여 Z를 완성합니다.
따라서 11번 이동시켜 "JAZ"를 만들 수 있고, 이때가 최소 이동입니다.
만들고자 하는 이름 name
이 매개변수로 주어질 때, 이름에 대해 조이스틱 조작 횟수의 최솟값을 return 하도록 solution 함수 만들기.
제한 사항
name
은 알파벳 대문자로만 이루어져 있음name
의 길이는 1 이상 20 이하입출력 예
name | return |
---|---|
"JEROEN" | 56 |
"JAN" | 23 |
처음에 생각한 풀이
name
한 글자씩 돌아가면서 A가 아닌 위치를 찾음 → 배열최종 풀이
처음에 생각한 풀이와 거의 동일
2번은 "현재 위치"를 고려해야 하고, 3번은 고려하지 않아도 됨(항상 'A'에서 시작하니까)
def solution(name):
answer = 0
locaiton = 0
wrongPos = []
for i in range(len(name)):
if name[i] == 'A':
pass
else:
wrongPos.append(i)
if len(wrongPos) > 0:
for j in range(len(wrongPos)):
location = wrongPos[j]
answer += calculateLessAdd(ord('A'), ord(name[wrongPos[j]]), ord('Z'))
if(j < len(wrongPos) - 1):
answer += calculateLessMove(j, wrongPos[j+1], len(name) - 1)
return answer
def calculateLessAdd(curVal, nextVal, lastVal):
front = nextVal - curVal
back = lastVal - nextVal + 1
return front if front < back else back
def calculateLessMove(curLoc, nextLoc, lastLoc):
front = nextLoc - curLoc
back = curLoc + (lastLoc - nextLoc) + 1
return front if front < back else back
44.4점...(;;)
wrongPos
배열 생성back
에서 curLoc
을 더해줄지 말지로 분리해도 상관없을 것 같다chatgpt의 풀이
def solution(name):
# 각 문자를 변경하는 데 필요한 조작 횟수를 계산
def char_to_move_count(c):
return min(ord(c) - ord('A'), ord('Z') - ord(c) + 1)
total_moves = 0
n = len(name)
# 각 문자의 조작 횟수를 더해줌
for char in name:
total_moves += char_to_move_count(char)
# 좌우 이동 최적 경로 계산
min_move = n - 1 # 초기값: 오른쪽으로 쭉 가는 경우
for i in range(n):
next_index = i + 1
while next_index < n and name[next_index] == 'A':
next_index += 1
# (왼쪽으로 갔다가 돌아오는 경우 vs 오른쪽으로 쭉 가는 경우) + 중간의 A 갯수 고려
min_move = min(min_move, i + i + n - next_index, i + (n - next_index) * 2)
total_moves += min_move
return total_moves
min_move
next_index
)min_move
왼쪽으로 갔다가 돌아오는 경우: 현재 위치까지 이동 + 다시 왼쪽 끝까지 이동 + 다음 위치로 이동
오른쪽으로 쭉 가는 경우: 현재 위치까지 이동 + 다음 위치로 이동 + 다시 현재 위치로 돌아옴
중에 최소값으로 갱신
프로그래머스에 있는 다른 풀이
def solution(name):
answer = 0
n = len(name)
def alphabet_to_num(char):
num_char = [i for i in range(14)] + [j for j in range(12, 0, -1)]
return num_char[ord(char) - ord('A')]
for ch in name:
answer += alphabet_to_num(ch)
move = n - 1
for idx in range(n):
next_idx = idx + 1
while (next_idx < n) and (name[next_idx] == 'A'):
next_idx += 1
distance = min(idx, n - next_idx)
move = min(move, idx + n - next_idx + distance)
answer += move
return answer
chatgpt