programming

프로그래머스 시즈 시저 암호 파이썬 풀이 및 해설


by Kitle · 2020. 07. 19.



퀴즈 출처 프로그래머스 : https://programmers.co.kr/learn/courses/30/lessons/12926


문제 설명

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


제한 조건

공백은 아무리 밀어도 공백입니다.

s는 알파벳 소문자, 대문자, 공백으로만 이루어져 있습니다.

s의 길이는 8000이하입니다.

n은 1 이상, 25이하인 자연수입니다.

입출력 예

s n result

AB 1 BC

z 1 a

a B z 4 e F d


이번 문제도 큰 어려움은 없어 보이죠? 바로 풀이 들어가겠습니다.
def solution(s, n):
answer = ''
pos_lower = 'abcdefghijklmnopqrstuvwxyz'
lower = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
'v', 'w', 'x', 'y', 'z']

for item in s:
if item == ' ':
answer += item
elif item.islower():
answer += lower[(pos_lower.find(item)+n) % 26]
else:
answer += lower[(pos_lower.find(item.lower())+n) % 26].upper()

return answer

[해설]
이번 풀이는 정공법이 아닌 약간의 변칙 법으로 되어 있습니다.
이번에도 결국 문자열 iteration 관련 문제입니다. 해설을 하다보니 거의 문자열 처리가 대다수인것 같네요.
첫번째 조건으로 공백은 변환없이 그대로 공백 추가해주면 되겠습니다.

두번째 조건으로 소문자인 경우 처리 방법입니다. 문자열에서 현재 위치 문자의 현재 위치(index)를 찾고 이동할 칸(n)만큼 더해주고, 26보다 크면 다시 처음으로 돌아가서... 는 결국 또 % 나머지를 찾으면 되겠죠.
현재 인덱스를 찾으려면 a=1, b=2 등으로 각각 할당해줄 필요 있겠지만 여기는 약간의 변칙법으로 문자열내 위치 찾기방식을 써보겠습니다. 문자열(리스트 아님)의 find()를 사용하면 현재 위치를 얻을 수 있습니다. a의 경우 0이 나올테고 주어진 n칸 이동이 2라면 0+2 = 2 즉 0,1,2 -> a,b,c 순이죠 두칸이동한 c 를 출력하면 됩니다. 출력부는 해당 list로 접근하여 위치찾는 부분과, 실제 이동값 찾는 방법을 살짝 다르게 해보았습니다. 두개를 한번에 처리하는 더 좋은방법도 있을거에요.

대문자의 경우는 똑같이 또 대문자 리스트, 문자열을 만들 수도 있지만, 대문자의 경우 소문자로 변환해서 구하고 다시 대문자로 바꿔줘도 문제가 없기 때문에 소문자/대문자인지 판단은 islower() 의 결과 True False로 한번에 해결할 수 있습니다.
islower()가 False면 대문자라는 뜻이므로 대문자는 lower() 를 통해 소문자로 변환해 처리하고 마지막 결과만 upper() 로 대문자로 변환하여 결과값에 추가해주면 되겠죠?