본문 바로가기

TLI/코드카타

2024.05.30 TIL 코트카타 67번(둘만의 암호)

    fun solution(s: String, skip: String, index: Int): String {
        var answer = StringBuilder()

        var isSkipAlphabets = BooleanArray(26)

        for(skipAlphabet in skip) {
            isSkipAlphabets[skipAlphabet.code-97] = true
        }

        for(sChar in s) {
            var endIndex = sChar.code - 97
            var numSkip = index
            while(numSkip > 0) {
                var startIndex = endIndex+1
                endIndex += numSkip
                numSkip = 0
                for(skipIndex in startIndex..endIndex) {
                    if(isSkipAlphabets[skipIndex % 26])
                        numSkip++
                }
            }
            endIndex %= 26
            answer.append((endIndex+97).toChar())
        }

        return answer.toString()
    }

 

풀이 과정

1. skip에 포함된 알파벳을 Boolean 배열(isSkipAlphabets)에 true값으로 초기화한다.(인덱스 = 아스키코드)

2. s에서 한 글자씩 읽으면서 index만큼 이동한다.

3. 이동한 범위 안에 skip에 해당하는 알파벳이 있으면 카운트하고 카운트 한 만큼 또 이동한다.

4. 카운트 되지 않을 때까지 3번을 반복한다.

5. 최종적으로 이동한 값(endIndex)에 해당하는 알파벳을 answer에 추가한다.

 

포인트

- skip의 최대 길이 10, index는 최대 20

- 20만큼 이동했는데 그 범위에 skip에 있는 모든 알파벳이 포함된다면 총 30을 이동하게 된다.

- 알파벳은 26개 이므로 한바퀴를 초과해 이동하게 되는 것이다.

- 그렇기 때문에 최종적으로 나온 이동 거리(endIndex)를 26으로 나눈 나머지(endIndex%26)를 해줘야 정확히 이동한 알파벳을 찾을 수 있다.

- 단순히 26을 빼기만 하면 알파벳의 아스키코드를 초과한 값으로 인덱스에 접근해 IndexOutOfBoundException이 발생할 수 있다.