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

Rose Jang·2022년 11월 23일
0
post-thumbnail


하루에 하나 이상 잔디를 심겠다고 프로그래머스에서 문제를 풀고 깃헙에 올리기 시작한지 일주일째
시작이 힘들지 일단 연속으로 며칠 올리니까 저게 아까워서라도 계속 올리려고 문제를 풀게된다👍
아직은 0, 1레벨 번갈아가며 푸는 중이라 하나 푸는데 시간이 얼마 안걸린다. 얼른 1단계 다 풀고 2단계 가야지😎 (비동기 공부하다가 프로그래머스 문제 푸니까 이게 엄청 재미있게 느껴진다..)

맨날 문제 푼 거 블로그 올려야지 올려야지 하다가 48문제 풀고서야 처음 남기는 문제 푼 기록.. 오늘 푼 시저 암호 문제가 되게 재밌어서 드디어 블로그를 올린다😂


☑️ 시저 암호

❓문제 설명

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

❗️제한 조건

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

❗️입출력 예

snresult
"AB"1"BC"
"z"1"a"
"a B z"4"e F d"

🧐 내 풀이

function solution(s, n) {
    const alpha = 'abcdefghijklmnopqrstuvwxyz';
    let result = '';
    
    for (let i = 0; i < s.length; i++) {
        if (s[i] !== ' ') {
            let a = s[i].toLowerCase();
            let sIdx = alpha.indexOf(a);
            let nIdx = sIdx + n <= alpha.length - 1 ? sIdx + n : (sIdx + n) - alpha.length;

            if (s[i] === a) result += alpha[nIdx];
            else result += alpha[nIdx].toUpperCase();
        } 
        else result += ' ';
    }
    
    return result;
}

➕ 바꿀 점, 추가할 점

아직 어떤 방식이 더 빠르게 돌아가는가에 대한 건 잘 모르겠다.. 생각을 해보긴 하는데, 일단은 코드가 돌아가게 만드는 거 자체가 목표라.. 레벨 1을 정복하면 풀었던 문제들을 다시 한 번 들여다 보긴 해야겠다.

let nIdx = sIdx + n <= alpha.length - 1 ? sIdx + n : (sIdx + n) - alpha.length;

nIdx (n만큼 밀었을때 인덱스값)을 구할때 조건이 falsy일 경우 저장되는 값을 (sIdx + n) - alpha.length로 지정했는데, (sIdx + n) % 26 혹은 (sIdx + n) - 26으로 해도 됐을 것 같다.(어짜피 알파벳의 개수는 항상 26개니까...)

갑자기 코드를 보다가 "for문 안에서 alpha = 알파벳.repeat((sIdx + n) / 26 + 1)를 해주면 nIdx = sIdx + n으로만 깔끔하게 써도 되고, n이 26 이상의 숫자가 들어오더라도 문제가 없지 않을까?" 라는 생각이 들었다. 그래서 다시 한 번 짜봤다.

🧐 또다른 풀이 (n에 26 이상의 수가 들어온다면?)

function solution(s, n) {
    const alphabet = 'abcdefghijklmnopqrstuvwxyz';
    let result = '';
    
    for (let i = 0; i < s.length; i++) {
        if (s[i] !== ' ') {
            let a = s[i].toLowerCase();
            let sIdx = alphabet.indexOf(a);
            let nIdx = sIdx + n;
            let alpha = alphabet.repeat((sIdx + n)/26 + 1);

            if (s[i] === a) result += alpha[nIdx];
            else result += alpha[nIdx].toUpperCase();
        } 
        else result += ' ';
    }
    
    return result;
}

잘 작동한다! 뭐가 더 효율적인지는 모르겠으나 이 방법도 마음에 든다 👏


🤦🏻‍♀️ 필요성을 느낀것

변수명을 지정할 때, 길어지는 게 싫어서 최대한 짧게 하려고 a, sIdx, nIdx와 같이 지정했다. 쓸 때는 알아보기 쉽겠지~ 했는데 변수명이 헷갈려 잘못쓴걸로 오류를 여러번 냈다😞
겨우 레벨 1에 길지 않은 이런 코드에서도 헷갈리는데 나중에 긴 코드 쓸 때 변수명 대충 지정하면 얼마나 헷갈릴까 싶었다. 간결하면서 알아보기 쉬운 변수명 짓는 능력이 필요해🥲

+ 다른 사람의 풀이를 볼 때마다 항상 느끼는 점. 정규표현식 공부해야겠다. 속도가 빠른지는 모르겠지만 코드가 어마어마하게 간결해서 항상 탐난다 🤣

0개의 댓글