import Foundation
func solution(_ name:String) -> Int {
var result = 0
var nameArr = name.map { Int(UnicodeScalar(String($0))!.value) - 65 } // A = 0, B = 1 이런식으로 값으로 변환
// 전부 A일 경우의 예외처리
var isAllA = true
for name in nameArr {
if name != 0 {
isAllA = false
break
}
}
if isAllA {
return 0
}
// 조이스틱 왼/오른쪽의 경우에 소요되는 값만 계산
var greedyVal = nameArr.count - 1 // 어느 식으로 돌아야 최선일지 찾는다.
// 먼저 뒤로갔다 앞으로 갈 경우 체크
for index in stride(from: nameArr.count - 1, to: 1, by: -1) {
if nameArr[index] == 0 // 지금 순번이 A인 경우이거나
|| nameArr[index - 1] != 0 { // 다음게 A가 아닐경우 체크할 필요 없다.
continue
}
// 거꾸로 갔을 때 몇번째까지 가야하는지 체크
var moveMore = 0
for i in 1..<index {
if nameArr[i] == 0 {
continue
} else {
moveMore = i
}
}
var backMove = ((nameArr.count - index) * 2)
if moveMore == 0 { // 앞으로 다시갈 일이 없다면
backMove = nameArr.count - index
}
let moveVal = backMove + moveMore
if greedyVal > moveVal {
greedyVal = moveVal
}
}
// 먼저 앞으로 갔다 뒤로 갈 경우 체크
for index in 0..<nameArr.count - 1 {
if nameArr[index] == 0 // 지금 순번이 A인 경우이거나
|| nameArr[index + 1] != 0 { // 다음게 A가 아닐경우 체크할 필요 없다.
continue
}
var moveMore = 0
for i in stride(from: nameArr.count - 1, to: index + 1, by: -1) {
if nameArr[i] == 0 {
continue
} else {
moveMore = nameArr.count - i
}
}
var backMove = index * 2
if moveMore == 0 { // 뒤로 다시갈 일이 없다면
backMove = index
}
let moveVal = backMove + moveMore
if greedyVal > moveVal {
greedyVal = moveVal
}
}
//print(greedyVal)
result = greedyVal
// 조이스틱 위 아래의 경우에 소요되는 값만 계산
for (index, name) in nameArr.enumerated() {
if name > 12 { // 조이스틱 아래쪽으로 이동하는게 빠른 경우
result += 26 - name
} else { // 조이스틱 위쪽으로 이동하는게 빠른 경우
result += name
}
}
return result
}
아스키코드로 변경하고 비교하는 그런 부분은 아무것도 아니다...
조이스틱을 왼쪽 오른쪽 이동을 최소화하는 방법을 찾는게 관건인 문제.
처음에는 조이스틱 앞으로 갔다 뒤로가는 경우만 생각해서 풀다가 아니라는걸 깨닫고
그 반대의 경우도 코드로 짜느라 코드 양이 상당히 많아졌다..
그냥 완전 탐색을 했으면 코드가 더 깔끔했을듯 하다.