[연습문제] 둘만의 암호

2024. 12. 17. 18:00입문문제

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

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr


문제 설명
두 문자열 sskip, 그리고 자연수 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"가 되며 결과는 "happy"가 됩니다.

두 문자열 s와 skip, 그리고 자연수 index가 매개변수로 주어질 때 위 규칙대로 s를 변환한 결과를 return하도록 solution 함수를 완성해주세요.


제한사항

  • 5 ≤ s의 길이 ≤ 50
  • 1 ≤ skip의 길이 ≤ 10
  • sskip은 알파벳 소문자로만 이루어져 있습니다.
    • skip에 포함되는 알파벳은 s에 포함되지 않습니다.
  • 1 ≤ index ≤ 20

입출력 예

s skip index result
"aukks" "wbqd" 5 "happy"

입출력 예 설명
입출력 예 #1

  • 본문 내용과 일치합니다.

암호화된 문자열 s, 사용하지 않는 문자 집합 skip, 그리고 해독을 위해 넘겨야할 순번 index가 주어졌을 때, 암호화된 문자열을 원래 문자열로 되돌리는 문제입니다.

 

문제에 나온 것처럼, a는 원래대로라면 5를 넘겼을 때 f가 되어야 하지만, b와 d가 skip 문자열에 속하기 때문에 2칸을 더 밀어서 h가 됩니다.

이 문제를 생각을 해봤을 때, 저는 모든 영문자를 가진 "abcdef...wxyz" 문자열을 하나 생성하고 skip 문자열을 삭제한다면 쉽게 풀 수 있을 것 같네요.

그리고 z의 다음이 a로 되돌아온다는 것을 생각해본다면, 문자열의 사이즈로 나누어준다면 이 역시 구현할 수 있습니다.

 

정답 코드를 작성해보겠습니다.

 

1. 자바

class Solution {
    public String solution(String s, String skip, int index) {
        String answer = "";
        String filtered = "abcdefghijklmnopqrstuvwxyz";
        
        // skip에 포함된 문자를 filtered에서 제거
        for (int i = 0; i < skip.length(); i++) {
            filtered = filtered.replace(String.valueOf(skip.charAt(i)), "");
        }
        
        // 각 문자를 index만큼 이동하여 answer 생성
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            int currentIndex = filtered.indexOf(c);
            int newIndex = (currentIndex + index) % filtered.length();
            answer += filtered.charAt(newIndex);
        }
        
        return answer;
    }
}

 

2. 파이썬

def solution(s, skip, index):
    answer = ''
    # 기본 문자열 a-z
    keywords = "abcdefghijklmnopqrstuvwxyz"
    # skip 문자열의 값들을 삭제합니다.
    filtered = [k for k in keywords if k not in skip]
    # 암호를 해독합니다.
    answer = ''.join(filtered[(filtered.index(c) + index) % len(filtered)] for c in s)
    return answer

 

사용할 수 있는 문자열이 모든 알파벳 소문자에서 skip 문자열에 포함된 알파벳을 제거한 케이스란 걸 생각하니 풀기 쉬웠습니다.