SteadyDrills

[TIL] 코딩 테스트 연습문제 - 시저 암호 본문

PYTHON

[TIL] 코딩 테스트 연습문제 - 시저 암호

Drills 2024. 7. 31. 23:18

240731

https://school.programmers.co.kr/learn/courses/30/lessons/12926

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

1차 시기 - 문제 이해와 코드 설계 


"""
문제 이해
주어지는 문자열 s 를 n 만큼 밀어서
다른 알파벳으로 만드는 시저암호 함수를 만들어라.

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

코드 설계
1. 문자열 s와 밀어낼 자연수 n 을 받아서  활용
2. 문자열을 아스키 코드를 이용해서 숫자로 바꾼다.
3. 그 수에  n을 더하고 문자로 바꿈
4. 바꾼 문자를 하나의 문자열로 출력
"""


def solution(s, n):
    cc = []
    for i in s:
        # 빈칸도 아스키 코드로 변환 되기때문에
        if i == " ":
            cc.append(" ")

        else:
            i_num = ord(i)
            # 아스키 코드안에서 소문자를 출력하기 위해
            if i_num + n > 122:
                j = (i_num + n) - 122
                cc_word = chr(96 + j)
                cc.append(cc_word)
            # 아스키 코드안에서 대문자를 출력하기 위해
            elif 97 > i_num + n > 90:
                j = (i_num + n) - 90
                cc_word = chr(64 + j)
                cc.append(cc_word)
            else:
                cc_word = chr(i_num + n)
                cc.append(cc_word)
    result = ''.join(cc)
    return result

 테스트 3문제는 통과했지만 오답!

오답
61.5 / 100

공백 처리까지는 잘했으나, 자연수 n을 간과했다. 또한 아스키코드의 구조를 자세히 살펴보지 않아서 만들어진 오답이다.

제출한 코드를 뜯어보면, 반례로 s = "Z",n=25 일때, "Z"는 아스키 코드 상 90이고, n= 25이면 합은 115로 소문자 "s" 가 된다. 하지만 문제에서 요구한 것은 대문자는 대문자 안에서 소문자는 소문자 안에서 밀어 내는 것이므로 대문자 "Y"를 출력해야 하는 것이다. 이 부분을 해결하기 위해 아예 소문자와 대문자를 나눠서 작동하도록 했다.

 

2차 시기 -  반례에 맞는 수정 및 확인


 

def solution(s, n):
    cc = []
    for i in s:
        # 빈칸도 아스키 코드로 변환 되기때문에
        if i == " ":
            cc.append(" ")
        # 아스키 코드 안에서 소문자를 출력하기 위해
        else:
            i_num = ord(i)
            if 123 > i_num > 96:
                if i_num + n > 122:
                    j = (i_num + n) - 122
                    cc_word = chr(96 + j)
                    cc.append(cc_word)
                else:
                    cc_word = chr(i_num + n)
                    cc.append(cc_word)
            # 아스키 코드 안에서 대문자를 출력하기 위해
            elif 91 > i_num > 64:
                if i_num + n > 90:
                    j = (i_num + n) - 90
                    cc_word = chr(64 + j)
                    cc.append(cc_word)
                else:
                    cc_word = chr(i_num + n)
                    cc.append(cc_word)
            else:
                cc_word = chr(i_num + n)
                cc.append(cc_word)
    result = ''.join(cc)
    return result

 

정답

100/100

 

 

오답노트)

언뜻 단순한 문제 같아 쉬워 보였지만 아스키 코드를 알고 특성을 잘 이용해야 쉬운 문제인 거 같다. 또한 처음부터 문제를 소문자와 대문자로  작게 나누어 코드를 짰다면, 두 문자의 영역을 침범하지 않게 확실한 구분을 주는 게 더 좋지 않았을까 생각이 든다.