아스키코드값으로 접근
z
, Z
인 경우 1만큼 밀면 a
, A
가 되므로 조건문 달아주고, 공백은 아무리 밀어도 공백이니까 조건문에서 그냥 pass
, 그 외의 경우 아스키코드값에 그냥 +n
해주는 방식으로 코드를 짰다.
def solution(s, n):
answer = ''
# A=65 Z=90 a=97 z=122 공백=32
s = list(s)
ord_list = []
for i in s:
ord_list.append(ord(i))
to_chr_list = [] # 다시 알파벳으로 바꿔야하는 아스키코드값 리스트
for ordnum in ord_list:
if ordnum == 90 or ordnum == 122: # z나 Z인 경우
ordnum += -26 +n
# ordnum -= 26-n
elif ordnum == 32: # 공백은 아무리 밀어도 공백
pass
else: # 보통의 경우 그냥 +n
ordnum += n
to_chr_list.append(ordnum)
for to_chr in to_chr_list:
new_alpha = chr(to_chr)
answer += new_alpha
return answer
이렇게 작성하면 코드실행
시 나오는 테스트케이스 3개는 통과하는데 채점을 하면 테스트 9
빼고 모조리 실패로 뜸.. 그래서 질문하기 탭에서 다른 사람들이 질문하고 알려준 풀이를 좀 봤는데 내가 Z
의 경우만 생각했다는걸 깨달음..!!
y
에서 2만큼 밀면 또 a
가 나옴.. 이런 경우의 수를 생각해야함..
또 n
은 1 이상 25 이하이다!
def solution(s, n):
answer = ''
# A=65 Z=90 a=97 z=122 공백=32
# 대문자 65~90 소문자 97~122
s = list(s)
ord_list = []
for i in s:
ord_list.append(ord(i))
to_chr_list = [] # 다시 알파벳으로 바꿔야하는 아스키코드값 리스트
for ordnum in ord_list:
if ordnum == 32:
pass
elif 65 <= ordnum+n <= 90 or 97 <= ordnum+n <= 122:
ordnum += n
else:
ordnum += (n-26)
to_chr_list.append(ordnum)
for to_chr in to_chr_list:
new_alpha = chr(to_chr)
answer += new_alpha
return answer
ord_num
에서 n
을 더했을때 소문자 범위와 대문자 범위 안에 있다면 Z
에서 1을 더했을때 A
로 넘어가는것 같은 일이 없다는 것이니 그냥 ord_num += n
을 해주고 그렇지 않으면 ordnum += (n-26)
을 해주는 방식으로 했다.. 이러면 y
에서 2만큼 밀면 a
가 나오는 것과 같은.. 이런것도 다 해결해주리라 믿었다.
근데 또 생각하다보니 대문자와 소문자의 범위가 겹치는..게..
n
이 25일 경우를 생각해보자면요?
Y
(89)에서 +25
를 해주면 114
가 나오는데 이때 -26
을 해줘야 정상적인 값이 나오거든요? 근데 이제 114
는 97 <= ordnum+n <= 122
이 조건문에 걸려서 그냥 +25
만 해주는 불상사가 생기게 됨요.. (그래서 엉뚱한 소문자 값이 나오게 되는 것)
그렇다면 아예 문자가 대문자일 경우 대문자에서만 놀도록, 소문자일 경우 소문자에서만 놀도록 다시 코드를 짜보기로 했다.
(ordnum-65+n)%26
를 하면 대문자에서 몇번째의 값인지를 반환해줌A
)부터 아스키코드값이 시작하니까 +65
를 해준다. (몇번째 대문자인지의 그 수가 필요한게 아니라 그거에 해당하는 아스키값이 필요한 것이기 때문에 +65
)a
)부터 시작하니까 65자리에 97을 넣어주면 됨def solution(s, n):
answer = ''
# A=65 Z=90 a=97 z=122 공백=32
# 대문자 65~90 소문자 97~122
s = list(s)
ord_list = []
for i in s:
ord_list.append(ord(i))
to_chr_list = [] # 다시 알파벳으로 바꿔야하는 아스키코드값 리스트
for ordnum in ord_list:
if ordnum == 32:
pass
# 대문자인 경우
elif 65 <= ordnum <= 90:
ordnum = (ordnum-65+n)%26 + 65
# 소문자인 경우
elif 97 <= ordnum+n <= 122:
ordnum = (ordnum-97+n)%26 + 97
else:
ordnum += (n-26)
to_chr_list.append(ordnum)
for to_chr in to_chr_list:
new_alpha = chr(to_chr)
answer += new_alpha
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)
내 과정을 이렇게 간략하게 표현할 수가.. 있답니다?
나는 chr(ord(i))
이런식으로 함수 중첩해서 쓰면 어떤값이 나오는지 아직 헷갈려서.. 저렇게 일일이 다 풀어썼당.. 그래도 내 풀이가 더 직관적으로 이해가 된다고..위안을 삼아본다..
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)
대문자, 소문자를 다 문자열로 두고 s
안에 있는 문자들을 조건문 돌리는 방법.. 만약에 소문자라면 lower_list
에서 해당 문자가 있는 인덱스를 찾아주고(.find(i)
) 그 인덱스 번호에 +n
한 인덱스 번호에 해당하는 알파벳을 append
해주는 방식인듯! 이게 더 간단해 보이기도 하고...?
개인적으로 테스트케이스가 헷갈릴만한거를 하나 더 알려줬으면 사람들이 덜헤매지 않을까..라는 생각이!