오랑우탄의 반란

프로그래머스 | 시저 암호 (Python3) 리스트, ORD, CHR 본문

PYTHON/프로그래머스

프로그래머스 | 시저 암호 (Python3) 리스트, ORD, CHR

5&2 2024. 7. 11. 21:48
반응형

 

오늘도 오랑이는 문제를 풉니다.

 

시저 암호

 

풀이 과정

알파벳 str 을 직접 만들어서 써야 하는 문제입니다. 

저는 대문자, 소문자 둘 다 만들기 귀찮아서 하나만 만들어서 활용했습니다. 

나중에 다른 사람들의 풀이를 보니 따로 str 작성 없이 함수를 활용해서 간단하게 푸는 방법이 있더군요 ! (정석풀이)

 

역시 오랑이는 아직 갈 길이 멉니다~

 

1차 풀이를 살펴봅시다.

각각 소문자, 대문자, 공백에 대한 경우를 나눠서 계산하도록 해야 합니다. 

이때 z → a 로 알파벳이 이어지게 하는 게 중요한데, 처음에는 25를 기준으로 25보다 작으면 j, 아니면 (j-26) 형식으로 생각했는데 필요 이상으로 if문이 많아져서 ('아 이렇게 지저분할 일이 없어' 라는 생각으로 풀었읍니다..그보다 간단하게 26으로 나눈 나머지의 개념으로 접근했습니다. 

def solution(s, n):
    answer = ''
    abc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    for i in s:
        if i == i.lower():
            abc = abc.lower()
            j = abc.find(i)+n
            answer += abc[j%26]
        if i == i.upper():
            j = abc.find(i)+n
            answer += abc[j%26]
        else:
            answer += ' '
    return answer

 

하지만 어김없이 틀려버렸고 그것도 한 두 개가 아니더군요 ㅎㅎ

첫번째 if 문에서 abc.lower() 를 했는데 이렇게 되면 조건문을 충족하는 모든 letter에 대해서 저 함수가 반복돼서 부정확한 결과를 출력합니다.  

해당 부분을 올바르게 수정하면 아래와 같습니다. 

i == i.lower() 대신 .islower() 로 소문자 여부를 확인해주고, 문자열 메서드를 중첩해서 필요할 때만 적용되게 합니다.

if i.islower():
    j = abc.lower().find(i) + n
    answer += abc.lower()[j % 26]

 

이렇게 수정해서 돌렸는데 일부만 제대로 출력되고 중간에 대문자가 들어가있는 문자열에 대해서는 제대로 출력을 못하는 오류를 발견했습니다. 그 이유는 바로 if 문의 형식 때문이었는데요, 평소에 잘만 쓰던 if - elif - else 형식을 잠시 잊고 if - if - else 로 작성했더니 바로 작동오류가 났습니다. 

for i in s:
    if i.islower():
        j = abc.lower().find(i) + n
        answer += abc.lower()[j % 26]
    elif i.isupper():
        j = abc.find(i) + n
        answer += abc[j % 26]
    else:
        answer += i

 

또한 마지막에 answer += ' ' 대신에 바로 answer += i 로 써도 무방하다는 사실 (s 는 소문자, 대문자, 공백으로만 주어진다는 조건 때문이지요)

 

최종 코드

def solution(s, n):
    answer = ''
    abc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    for i in s:
        if i.islower():
            j = abc.lower().find(i)+n
            answer += abc.lower()[j%26]
        elif i.isupper():
            j = abc.find(i)+n
            answer += abc[j%26]
        else:
            answer += ' '
    return answer

 

 

chr(), ord() 를 활용한 다른 풀이

이번에 처음 보는 함수인데요! 문자와 거기에 해당하는 ASCII 값을 연결해서 각각 출력해주는 함수인데 ASCII 값이 어디에 쓰이나 했는데 여기에 쓰이는 거였군요.

 

ORD() : 문자를 ASCII 값으로 변환 ('A' → 65)

CHR() : ASCII 값을 문자로 변환 (65 'A')

def solution(s, n):
    s = list(s) # 리스트로 변환 
    for i in range(len(s)): # 리스트 인덱스 값 i에 대해
    
        if s[i].isupper():# 인덱스 i 위치의 문자 s[i]가 대문자면
            s[i] = chr((ord(s[i]) - ord('A') + n) % 26 + ord('A'))
            # s[i]는 (s[i]의 ASCII 값 - 'A' 의 ASCII 값 + n) [즉 j] 을 26으로 나눈 나머지에 
              원래 'A' ASCII 값을 더해 위치 조정 후 다시 문자열로 변환 
              
        elif s[i].islower():
            s[i] = chr((ord(s[i]) - ord('a') + n) % 26 + ord('a'))
            # 위와 동일
 
    return "".join(s)  # 마지막에 하나씩 출력된 문자열 이어주기

 

 

 

오랑우탄이 영어를 하고 오랑이가 코드마스터가 되는 그날까지~

 

 

 

프로그래머스

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

programmers.co.kr

반응형