두 문자열 s와 skip, 그리고 자연수 index가 주어질 때, 다음 규칙에 따라 문자열을 만들려 함
암호의 규칙
문자열 s의각 알파벳을 index만큼 뒤의 알파벳으로바꿔줌
index만큼의 뒤의 알파벳이 z를 넘어갈 경우 다시 a로 돌아감
skip에 있는 알파벳은 제외하고 건너뜀
예를 들어 s = "aukks", skip = "wbqd", index = 5일 때,
a에서 5만큼 뒤에 있는 알파벳은 f지만 [b, c, d, e, f]에서 'b'와 'd'는 skip에 포함되므로 세지 않음
따라서 'b', 'd'를 제외하고 'a'에서 5만큼 뒤에 있는 알파벳은 [c, e, f, g, h] 순서에 의해 'h'가 됨
나머지 "ukks" 또한 위 규칙대로 바꾸면 "appy"
두 문자열 s와 skip, 그리고 자연수 index가 매개변수로 주어질 때 위 규칙대로 s를 변환한 결과를 return
제한사항
5 ≤ s의 길이 ≤ 50
1 ≤ skip의 길이 ≤ 10
s와 skip은 알파벳 소문자로만 이루어져 있음
skip에 포함되는 알파벳은 s에 포함되지 않음
1 ≤ index ≤ 20
"""
입출력 예시)
s = "aukks", skip = "wbqd", index = 5 -> "happy"
"""
## 의사코드 ##
# index만큼 뒤의 알파벳으로 변환
# chr(ord(알파벳)+index)
# index만큼의 뒤의 알파벳이 z를 넘어갈 경우 다시 a로 돌아감
# 최종 변환될 문자
# chr(ord('a') + ((s의 현재 알파벳 + (index + 스킵한 횟수)) - ord('a')) % 26)
첫 번째 시도
def solution(s, skip, index):
answer = ''
# 아스키코드 값으로 변환한 s 리스트
ord_s = [ord(chr) for chr in s]
# 아스키코드 값으로 변환한 skip 리스트
ord_skip = sorted([ord(s) for s in skip])
for i in range(len(ord_s)):
skip_cnt = 0 # 스킵한 횟수
for j in ord_skip:
# skip의 현재 알파벳이 현재 s의 알파벳과 index만큼 뒤의 알파벳 사이에 포함되면 스킵한 횟수 + 1
if j > ord_s[i] and j <= ord_s[i]+index:
skip_cnt += 1
# index + 스킵한 횟수
new = index + skip_cnt
answer += chr(ord('a') + ((ord_s[i] + new) - ord('a')) % 26)
return answer
-> 추가 테스트 케이스 실패
skip의 현재 알파벳이 현재 s의 알파벳과 index만큼 뒤의 알파벳 사이에 포함되면 스킵한 횟수를 1씩 증가시켜 index에 스킵한 횟수를 더한 값이 최종 변환될 문자가 되도록 구현
과정 확인
s = "aukks"
skip = "wbqd"
index = 5
"""
s: aukks
ord_s: [97, 117, 107, 107, 115]
skip: wbqd
ord_skip: [98, 100, 113, 119]
index: 5
--------------------------------------------------
현재 s의 알파벳: a
스킵한 횟수 = 0
현재 skip의 알파벳: b
스킵
스킵한 횟수 = 1
현재 skip의 알파벳: d
스킵
스킵한 횟수 = 2
현재 skip의 알파벳: q
현재 skip의 알파벳: w
index + 스킵한 횟수 = 7
answer: h
--------------------------------------------------
현재 s의 알파벳: u
스킵한 횟수 = 0
현재 skip의 알파벳: b
현재 skip의 알파벳: d
현재 skip의 알파벳: q
현재 skip의 알파벳: w
스킵
스킵한 횟수 = 1
index + 스킵한 횟수 = 6
answer: ha
--------------------------------------------------
현재 s의 알파벳: k
스킵한 횟수 = 0
현재 skip의 알파벳: b
현재 skip의 알파벳: d
현재 skip의 알파벳: q
현재 skip의 알파벳: w
index + 스킵한 횟수 = 5
answer: hap
--------------------------------------------------
현재 s의 알파벳: k
스킵한 횟수 = 0
현재 skip의 알파벳: b
현재 skip의 알파벳: d
현재 skip의 알파벳: q
현재 skip의 알파벳: w
index + 스킵한 횟수 = 5
answer: happ
--------------------------------------------------
현재 s의 알파벳: s
스킵한 횟수 = 0
현재 skip의 알파벳: b
현재 skip의 알파벳: d
현재 skip의 알파벳: q
현재 skip의 알파벳: w
스킵
스킵한 횟수 = 1
index + 스킵한 횟수 = 6
answer: happy
--------------------------------------------------
'happy'
"""
통과한 코드
def solution(s, skip, index):
answer = ''
alpha = [chr(i) for i in range(ord('a'), ord('z')+1) if chr(i) not in skip]*10
for a in s:
answer += alpha[alpha.index(a) + index]
return answer
-> skip에 포함된 알파벳을 제외한 알파벳들을 담은 리스트 alpha를 만들고, z를 넘어갈 경우 다시 a로 돌아오도록 리스트 alpha를 10번 반복
다른 풀이
def solution(s, skip, index):
alphas = [chr(a) for a in range(ord("a"), ord("z")+1) if chr(a) not in skip]
return "".join([alphas[(alphas.index(a) + index) % len(alphas)] for a in s])
-> skip에 포함된 알파벳을 제외한 알파벳들을 담은 리스트 alphas를 하나만 만들고, s의 현재 알파벳의 index 만큼 뒤인 문자의 인덱스 값을 alphas 리스트의 길이만큼으로 나눈 나머지를 인덱스로 가지는 값