코딩테스트/PYTHON

[프로그래머스][PYTHON] Lv. 1 시저 암호

_알파카 2024. 8. 20. 16:43
728x90

문제 설명

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

 

프로그래머스

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

programmers.co.kr

예전에 풀었던 문제와 비슷한 문제여서 어렵지 않게 풀 수 있었다. 

https://yeonnys.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4PYTHON-Lv-1-%EB%91%98%EB%A7%8C%EC%9D%98-%EC%95%94%ED%98%B8

 

[프로그래머스][PYTHON] Lv. 1 둘만의 암호

문제 설명https://school.programmers.co.kr/learn/courses/30/lessons/155652 프로그래머스코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합

yeonnys.tistory.com

위의 문제와 굉장히 유사하다!!

 

내 풀이

def solution(s, n):
    answer = ''
    lower_alpha = 'abcdefghijklmnopqrstuvwxyz'
    upper_alpha = lower_alpha.upper()
    for i in s:
        
        # 소문자일 때
        if i in lower_alpha:
            idx = lower_alpha.index(i)
            new_idx = (idx + n) % len(lower_alpha)
            answer += lower_alpha[new_idx]
        
        # 대문자일 때
        elif i in upper_alpha:
            idx = upper_alpha.index(i)
            new_idx = (idx + n) % len(upper_alpha)
            answer += upper_alpha[new_idx]
        
        # 공백일 때
        elif i == " ":
            answer += " "
    return answer

 

먼저, 알파벳 문자열을 만들었다. 리스트로 만들 수도 있지만, 그렇게 만드려면

["a", "b", ...] 와 같이 복잡하기 때문에

간단하게 문자열로 만들었다. 

 

이 후, 이를 대문자로 바꾼 문자열 'upper_alpha' 문자열도 함께 만들었다. 

 

다음으로, 주어진 문자열 s를 순회하며

각 단어가 소문자인지, 대문자인지, 공백인지 판단하고

문자일 경우에는 현재 문자의 인덱스를 찾아 idx로 저장하며, 

여기서 n 만큼 민 새로운 위치(new_idx)를 찾는다. 

이때 주의할 점은 문자열의 길이만큼 나머지 연산을 하지 않을 때는 범위를 넘어갈 수 있기 때문에

나머지 연산( % len(upper_alpha)를 해야한다. 

 

유사하게 대문자일 때도 계산하고, 공백일 경우에는 단순하게 공백만을 추가한다. 

 

개선한 풀이

문제를 풀고난 후, 좀 더 효율적으로 바꿀 수 있을듯하여 코드를 수정해보았다. 

def solution(s, n):
    answer = ''
    lower_alpha = 'abcdefghijklmnopqrstuvwxyz'
    
    for i in s:
        # 공백일 때
        if i == " ":
            answer += " "
        
        # 문자일 때(소문자, 대문자 모두)
        else:
            # 현재 문자를 소문자로 바꿔 위치를 찾음
            idx = lower_alpha.index(i.lower())
            # 새로운 위치 찾기
            new_idx = (idx + n) % len(lower_alpha)
            # 새로운 문자 찾기
            tmp = lower_alpha[new_idx]
            # 소문자일 때
            if i in lower_alpha:
                answer += tmp
            # 대문자일 때
            else:
                answer += tmp.upper()
        
    return answer

 

굳이 대문자 문자열을 따로 만들 필요가 없다고 생각하여, 

좀 더 효과적으로 바꿔보았지만, 

큰 차이는 없기 때문에 좀 더 직관적인 첫 번째 풀이가 더 좋은듯하다!

 

다른 사람 풀이

def solution(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)

 

위는 아스키 코드를 사용한 풀이이다. 

난 아직 아스키 코드가 어렵기 때문에..

꼭 이렇게 풀어야할까..?

 

 

def caesar(s, n):
    lower_list = "abcdefghijklmnopqrstuvwxyz"
    upper_list = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

    result = []

    for i in s:
        if i is " ":
            result.append(" ")
        elif i.islower() is True:
            new_ = lower_list.find(i) + n
            result.append(lower_list[new_ % 26])
        else:
            new_ = upper_list.find(i) + n
            result.append(upper_list[new_ % 26])
    return "".join(result)

 

 

728x90