본문 바로가기
Algorithm/Programmers

[Algorithm] 프로그래머스 - 시저 암호

by 홍월이_ 2022. 12. 28.

시작하며...

모든 알고리즘 문제 풀이는 제가 직접 짜서 정답을 맞춘 결과만을 공유합니다.

마지막 'More Solution'은 다른 정답자들 풀이 중 생각지 못했던 부분들이나 좋게 느껴진 풀이법 몇개를 가져와서 공유하였습니다.

 

[Level 1] 시저 암호

 

프로그래머스

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

programmers.co.kr

 

문제 설명

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

제한 조건

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

입출력 예

 

My Solution

def solution(s, n):
    answer = ''
    for i in s:
        if i != ' ':
            #  A-Z : 65-90 , a-z : 97-122
            ord_num = ord(i)
            if (ord_num <= 90 and ord_num + n > 90) or (ord_num <= 122 and ord_num + n > 122):
                answer += chr(ord_num + n - 26)
            else:
                answer += chr(ord_num + n)
        else:
            answer += ' '
    return answer

 

주어진 문자열 s의 각 원소를 n번째 거리만큼 이동시켜야 하는 문제이다.

각 문자열에 주어진 Ascii 코드를 이용하여 문제를 풀이하였다. (A-Z : 65-90 , a-z : 97-122)

  • 문자열을 iterator로 이용하여 반복문 구성
  • 첫 글자부터 i 로 차례대로 가져온다.
  • 문자열에 공백이 포함되어 있기때문에 i 가 공백이 아닐 경우와 공백인 경우를 조건문을 이용하여 분리
  • i 가 공백이 아니면 문자 i 를 ord() 함수를 이용해 아스키 코드의 숫자로 변환한다.
  • 변환된 아스키 코드의 숫자 ord_num에 이동시켜야 할 거리 n을 더해주고 chr() 을 이용해 다시 문자로 반환시켜주면 된다. 
    • 이때, 문제에서 주어진 조건을 생각해보아야 함
    • Z 에서 1칸을 이동하면 다시 처음인 A로 돌아가게 해야한다. 즉, + 1이 아닌 -25가 되어야 하는 상태
    • 이동한 후에 90과 122가 넘어간다면 다시 돌아가야한다.
    • 대문자와 소문자인 경우를 나누어서 조건을 추가로 주었다.
    • 대문자 Z 가 90이므로, ord_num이 90보다 작고 n을 더했을때 90을 넘어간다면 -26을 해주고 chr() 변환
    • 소문자 z가 122이므로, ord_numdl 122보다 작고 ord_num + n이 122보다 크다면 -26을 하고 chr() 변환
  • 공백일 경우는 answer에 공백을 추가한다.
  • 그리고 정답 문자열 answer에 하나씩 더해주고 리턴

 

More Solution

def caesar(s, n):
    s = list(s)
    for i in range(len(s)):
        if s[i].isupper():
            s[i]=chr((ord(s[i])-ord('A')+ n)%26+ord('A'))
        elif s[i].islower():
            s[i]=chr((ord(s[i])-ord('a')+ n)%26+ord('a'))

    return "".join(s)

이 풀이법은 mod를 이용, 이동하여 얻은 숫자를 26으로 나눈 나머지를 이용하였다.

이렇게 풀이하면 한바퀴를 돌았다고 해도 26으로 나눈 나머지는 같기때문에 몇 바퀴를 돌아도 같은 값을 얻을 수 있다. 

댓글