A 출현 횟수와 상관없이 한 방향으로만 검사하면 되는 줄 알았다.
"BBAAAAAC" 같은 케이스의 경우 방향 전환 (좌->우 or 좌 <- 우)이 더 짧은 이동 횟수를 갖는다.
CASE 별로 나누어 보자.
[CASE 1] A가 없거나 1개씩 나오는 경우
한방향으로만 이동하면 된다. (이름 길이 - 1)
※ 단, 두번째 자리나 끝자리에 A가 오면 1번의 이동이 더 절약된다.
두번째 자리 A -> 왼쪽으로만, 끝자리 A -> 오른쪽으로만
[CASE2] A가 연속등장하는 경우
(한방향 케이스), (좌->우), (좌 <-우) 방향 전환 케이스 총 3개 중 최소 값을 취한다. 방향 전환 기점은 연속된 A secquence
class Solution {
fun solution(name: String): Int {
// Up, Down 기준은 반올림 기준 알파뱃 14번째 'N'
// 'A' -> 'N' == 13, 'N' <- 'A' == 13 (왼, 오른방향 모두 13회)
val getUpDownCount : (Char) -> (Int) = { nameAlphabet: Char ->
if (nameAlphabet <= 'N') nameAlphabet - 'A'
else 13 - ((nameAlphabet - 'A') % 13)
}
if (!name.contains("AA")){
// 2번째 자리 || 마지막자리 A
return if (name.last() == 'A' || name[1]?.let{it == 'A'}) name.fold(0){ sum, alphabet -> sum + getUpDownCount(alphabet)} + name.length - 1 - 1 // 마지막 자리 이동 X || 좌방향 검사로 해결
// 아니면 길이 - 1 (One way move)
else name.fold(0){ sum, alphabet -> sum + getUpDownCount(alphabet)} + name.length - 1 // -1 : 첫자리는 이동 X
} else {
// considering shift of direction (좌->우, 좌<-우)
// 방향전환의 기점은 가장 긴 A 연속 지점 이전, 이후
val numberOfA = ArrayList<Int>()
val startIndex = name.indexOf("AA")
var index = startIndex // 첫 AA 시퀀스 등장 index 로 초기화
var count: Int = 0
// A sequence keep in ArrayList
while (index < name.length) {
if(name[index] != 'A') {
index++
continue
} else {
while(name[index++] == 'A') count++
numberOfA.add(count)
count = 0
}
}
val sequenceA = "A".repeat(Collections.max(numberOfA)) // 가장 긴 A 시퀀스를 얻어냄.
val shiftRightToLeft = (name.substringBefore(sequenceA).length - 1) * 2 + name.substringAfterLast(sequenceA).length
val shiftLeftToRight = name.substringBefore(sequenceA).length + (name.substringAfterLast(sequenceA).length * 2 - 1)
/* answer 1 : one-way solution with reaching 'A'(case2) */
val answer1 = name.fold(0){sum, alphabet -> sum + getUpDownCount(alphabet)} + name.length - 1
// answer 2 : MIN_VALUE of shift direction (좌->우 or 좌<-우)
var answer2 = Integer.min(shiftRightToLeft, shiftLeftToRight)
for (alphabet in name) answer2 += getUpDownCount(alphabet)
return Integer.min(answer1, answer2)
}
}
}