조이스틱

Falcon·2021년 1월 3일
1

programmers

목록 보기
1/27
post-custom-banner

🔒 문제

😅 실수

A 출현 횟수와 상관없이 한 방향으로만 검사하면 되는 줄 알았다.

"BBAAAAAC" 같은 케이스의 경우 방향 전환 (좌->우 or 좌 <- 우)이 더 짧은 이동 횟수를 갖는다.

💡 생각의 흐름

return 값

CASE 별로 나누어 보자.

[CASE 1] A가 없거나 1개씩 나오는 경우
한방향으로만 이동하면 된다. (이름 길이 - 1)
※ 단, 두번째 자리나 끝자리에 A가 오면 1번의 이동이 더 절약된다.
두번째 자리 A -> 왼쪽으로만, 끝자리 A -> 오른쪽으로만
[CASE2] A가 연속등장하는 경우
(한방향 케이스), (좌->우), (좌 <-우) 방향 전환 케이스 총 3개 중 최소 값을 취한다. 방향 전환 기점은 연속된 A secquence

🔑풀이 (Kotlin)

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)
        }
    }
}
profile
I'm still hungry
post-custom-banner

0개의 댓글