시저암호

KSang·2023년 12월 11일
0

[Kotlin]코드카타

목록 보기
44/100

🕵️문제설명

어떤 문장의 각 알파벳을 일정한 거리만큼 밀어서 다른 알파벳으로 바꾸는 암호화 방식을 시저 암호라고 합니다. 예를 들어 "AB"는 1만큼 밀면 "BC"가 되고, 3만큼 밀면 "DE"가 됩니다. "z"는 1만큼 밀면 "a"가 됩니다. 문자열 s와 거리 n을 입력받아 s를 n만큼 민 암호문을 만드는 함수, solution을 완성해 보세요.

⚠️제한사항

공백은 아무리 밀어도 공백입니다.
s는 알파벳 소문자, 대문자, 공백으로만 이루어져 있습니다.
s의 길이는 8000이하입니다.
n은 1 이상, 25이하인 자연수입니다.

🔎로직설명

처음 코드

fun solution(s: String, n: Int): String {
    val answer = s.toCharArray()
    for (i in 0 until answer.size) {
        var asc = answer[i].toInt()
        if (asc in 'A'.toInt()..'Z'.toInt() || asc in 'a'.toInt()..'z'.toInt()) {
            asc += n

            while (true) {
                if (asc !in 'A'.toInt()..'Z'.toInt() && asc !in 'a'.toInt()..'z'.toInt()) {
                    asc -= 26
                } else {
                    answer[i] = asc.toChar()
                    break
                }
            }
        }
    }
    return answer.joinToString("")
}

String 타입 문장을 Char로 받아 아스키 코드 값으로 N만큼 더해서 밀어내려 했다

s의 원소를 int값으로 asc에 널고 알파벳이면 += n 만큼 더해주고

알파벳을 넘어서 다른 문자가 될경우 26만큼 빼줘서 다시 알파벳이 되도록 만들었다

1차 수정

fun solution(s: String, n: Int): String {
    val answer = s.toCharArray()
    
    for (i in 0 until answer.size) {
        var asc = answer[i].toInt()

        if (answer[i].isLetter()) {
            asc += n

            while (true) {
                if (answer[i].isUpperCase() && asc > 'Z'.toInt()) {
                    asc -= 26
                } else if (answer[i].isLowerCase() && asc > 'z'.toInt()) {
                    asc -= 26
                } else {
                    answer[i] = asc.toChar()
                    break
                }
            }
        }
    }
    return answer.joinToString("")
}

실행중에 오류가 몇개 발생했다

왜 그럴까? 생각해보니 n이 100 200 이런식으로 아주 클경우 대문자 알파벳이 전부 소문자로 바뀌게 될걸 생각하지 못했다

if문을 이용해 대 소문자 구분해주고 따로 계산하게 만들었다

위에 알파벳 범위 나타낸것도 isLetter()를 써 알파벳을 구분하게 만들어 더 간결하게 만들었다

2차 수정

fun solution(s: String, n: Int): String =
        s.toList().joinToString(separator = "") {
            when (it) {
                in 'A'..'Z' -> ('A'.toInt() + (it.toInt() - 'A'.toInt() + n) % ('Z' - 'A' + 1)).toChar()
                in 'a'..'z' -> ('a'.toInt() + (it.toInt() - 'a'.toInt() + n) % ('z' - 'a' + 1)).toChar()
                else -> it
            }.toString()
        }

사람들이 사용한 코드

s를 리스트로 변환하고 리스트의 각 요소들을 문자열로 결합 sparator를 공백으로 설정해 구분자가 안나오게 했다

it(각 요소)들의 상태에 따라 대소문자 알파벳외 문자를 나눈후

요소에 A의 아스키 코드 만큼 빼주고 밀만큼 이동시켜준뒤 26으로 나눈 나머지를 구해 알파벳 범위를 안벗어 나게한다음 다시 A만큼 더해준다

0개의 댓글