https://programmers.co.kr/learn/courses/30/lessons/42860
LENGTH는 문자열의 길이이고 상수이다. names는 주어진 name을 Character타입으로 쪼갠 배열로 name이 "JAZ"일때 names는 ["J", "A", "Z"]이다. upDown은 알파벳을 A로 만들기 위한 위아래 조작 횟수를, leftRight는 왼쪽오른쪽 조작 횟수를 나타낸다. leftRight의 처음 값은 LENGTH에서 1을 뺀 값이다(길이가 3일때 첫글자에서 마지막 글자까지 이동하려면 2번이 필요하므로).
let name = "JAZ"
func solution(_ name:String) -> Int {
let LENGTH = name.count
let names = Array(name)
var upDown = 0
var leftRight = LENGTH - 1
for name in names {
upDown += getLength(name)
}
...
}
우선 각 알파벳을 A로 만들기 위한 횟수를 누적하며 upDown값을 구한다. 그리고 leftRight의 최솟값을 구한다. 예를 들어 "BBAAAB"인 경우에, 처음과 같이 기본적으로 다섯번(길이 - 1) 이동하는 경우도 있다. 하지만 두번째 B까지 갔다가 되돌아와서 마지막 C에 도달하는 경우도 있다. 두 값를 비교하여 최소 값을 leftRight에 넣는다. 그 후 upDown과 leftRight를 따로 구한 후 더해 반환한다.
B B A A A C
→ → → → →
B B A A A C
→ →
← ←
←
func solution(_ name:String) -> Int {
...
for (index, name) in names.enumerated() {
if name != Character("A") {
var nextIndex = index + 1
while nextIndex < LENGTH && names[nextIndex] == Character("A") {
nextIndex += 1
}
let length = (2 * index) + LENGTH - nextIndex
leftRight = min(leftRight, length)
}
}
return upDown + leftRight
}
getLength 함수는 알파벳을 받아서, A까지의 최소 조작 횟수를 반환한다. 아스키코드를 이용해 구한다. 단 Z로부터의 거리를 구할 때는, A → Z의 조작횟수인 1을 더해야 한다.
func getLength(_ alphabet: Character) -> Int {
let aValue = Character("A").asciiValue!
let zValue = Character("Z").asciiValue!
let value = alphabet.asciiValue!
return Int(min(value - aValue, zValue - value + 1))
}