문제
어떤 문장의 각 알파벳을 일정한 거리만큼 밀어서 다른 알파벳으로 바꾸는 암호화 방식을 시저 암호라고 합니다.
A를 3만큼 밀면 D가 되고 z를 1만큼 밀면 a가 됩니다. 공백은 수정하지 않습니다.
보낼 문자열 s와 얼마나 밀지 알려주는 n을 입력받아 암호문을 만드는 ceasar 함수를 완성해 보세요.
“a B z”,4를 입력받았다면 “e F d”를 리턴합니다.
나의 접근법
이상하게 쉽게 풀릴 것 같았는데, 하루정도 걸려서 풀었다. 가장 직관적으로 떠오른 생각은 아스키코드(ASCII)
코드를 활용하자는 것이다. 아스키코드가 뭔지 잘 모른다면, 쑥쓰러운 나의 블로그 포스팅 아스키코드와 유니코드의 이해 을 소개한다.
문제를 풀 때 가장 먼저 고려했던 것은
-
공백을 반영해야 한다는 것.
- 즉
a b c
라고 입력한 뒤, 2칸을 밀어야 한다면cde
가 아닌c d e
로 출력되어야 한다.
- 즉
-
대문자와 소문자를 구별해야 한다.
- 즉
a b c
는c d e
로,A B C
는D E F
로 출력되어야 한다.
- 즉
-
알파벳의 개수는 26개다. 그런데 30칸을 밀어야 할 때도 고려해야 한다.
새롭게 배운 메서드
입력받은 문자의 아스키코드 값(int)를 알아내는 메서드를 익혀야 했고, 역으로 아스키코드 값(int)를 문자로 출력하는 메서드도 익혀야 했다.
-
문자 --> 아스키코드
ord
구글에python string to ascii
로 검색했다. 다음 스택오버플로를 참고했다.
ord()안에는 문자가 들어가야 한다.
-
아스키코드 --> 문자
chr
chr()안에는 숫자가 들어가야 한다.
부딪혔던 난관들
-
caesar(s, n)에서
n
이 26이 넘는 걸 먼저 고려했다.n = n % 26
으로 반영했다. -
z
에서 2칸을 밀면b
가 출력되어야 한다. 이 경우에는 알파벳의 범위를 넘어서니까a
부터 시작하면 되겠네! 라고 생각했다. -
chr(ord('a') + n)
이라고 생각했다.- 이 경우에 "x y z"를 입력하고
n = 5
이면f f f
가 출력되는 불상사가 생겼다. z
의 범위가 넘어서게 되면a
에서 똑같이n
을 더해주기 때문이다.
- 이 경우에 "x y z"를 입력하고
-
생각을 다시 고쳐먹어야 했다. 입력받은 문자가 몇번째인지 순서 를 알아내야 했다!
-
알파벳이 몇번째 있는 값인지를 고려해서 코드를 수정했다.
caesar = chr((ord(s[char]) + n - 26))
일단 입력받은 값을
n
만큼 밀어주고, 알파벳 개수만큼 빼주면 순서가 반영된다.
나의 풀이
def caesar(s, n): n = n % 26 caesar_list = [] for char in range(0, len(s)): caesar = chr(ord(s[char]) + n) # 'Z' 또는 'z'를 넘어서는 것인지 확인하기 위함 if s[char] == " ": # 공백 처리 caesar_list.append(" ") continue if s[char].isupper(): # 대문자 처리 if caesar > chr(ord("Z")): caesar = chr((ord(s[char]) + n - 26)) else: # 소문자 처리 if caesar > chr(ord("z")): caesar = chr((ord(s[char]) + n - 26)) caesar_list.append(caesar) result = "".join(caesar_list) # 리스트를 문자열로 만들어줌 return result # 실행을 위한 테스트코드입니다. print('s는 "a B z", n은 4인 경우: ' + caesar("a B z", 4))
문제 출처
'프로그래밍 > 코드분석' 카테고리의 다른 글
[파이썬] (level4) 가장 큰 정사각형 찾기 (0) | 2017.10.22 |
---|---|
[파이썬] 카카오 블라인드 공채 1번 문제 (1) | 2017.09.19 |
[파이썬] level3 야근지수 (0) | 2017.08.30 |
[파이썬] 사각형의 나머지 한 좌표값 반환하기 (1) | 2017.06.10 |
[파이썬] 다음 큰 숫자(next big number) (0) | 2017.06.10 |