코딩테스트 | (JavaScript) 프로그래머스 : 시저 암호

trevor1107·2021년 8월 18일
0

✅문제

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

❕ 제한사항

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

🎹📢입출력 예제

✍풀어보기

function solution(s, n) {
    const ASCIICODE = {
        A : 'A'.charCodeAt(), // 65
        Z : 'Z'.charCodeAt(), // 90
        a : 'a'.charCodeAt(), // 97
        z : 'z'.charCodeAt(), // 122
        AtoZ_diffSize : 'Z'.charCodeAt() - 'A'.charCodeAt(), // 25
    }
    let answer = '';
    let charCode = '';
    
    for(let i = 0; i < s.length; ++i){
        if(s[i] === ' '){
            answer += s[i];
            continue;
        }
        charCode = s.charCodeAt(i);
   
        if(ASCIICODE.A <= charCode && charCode <= ASCIICODE.Z){
            charCode += n;
            if(ASCIICODE.Z < charCode){
                charCode -= (ASCIICODE.AtoZ_diffSize + 1);
            } 
        } else if(ASCIICODE.a <= charCode && charCode <= ASCIICODE.z){
            charCode += n;
            if(ASCIICODE.z < charCode){
                charCode -= (ASCIICODE.AtoZ_diffSize + 1);
            }
        }
      
        answer += String.fromCharCode(charCode);
    }
    
    return answer;
}

기본적이면서도 단순한 방법으로 풀었다. 누가 봐도 이해하기 쉬운 형태인 것 같다고 생각한다. 아스키코드로 변환시키고, 계산 후 코드를 다시 문자열로 변화시키는 과정에서 속도가 느려져서 아쉬운 부분도 있었다.


🎈다른 사람의 풀이

function solution(s, n) {
    var upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    var lower = "abcdefghijklmnopqrstuvwxyz";
    var answer= '';

    for(var i = 0; i <s.length; i++){
        var text = s[i];
        if(text == ' ') {
            answer += ' '; 
            continue;
        }
        var textArr = upper.includes(text) ? upper : lower;
        var index = textArr.indexOf(text)+n;
        if(index >= textArr.length) index -= textArr.length;
        answer += textArr[index];
    }
    return answer;
}

// 또 다른 풀이
function solution(s, n) {
    var chars = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXY                          "
    return s.split('').map(e => chars[chars.indexOf(e)+n]).join('');
}

다른 사람의 풀이를 보면 하드코딩 같아 보이지만 속도가 더 빠르다. 문제의 제한 범위안에서 아스키코드 관련 함수를 사용하지도 않고 풀 수 있는 효과적인 방법이라고 생각한다. 나도 이 방법을 생각 안 한 것은 아니지만 처음에 정의한 A~Z, a~z를 치는 것이 하드한 방법이라 생각해서 개인적으로 좀 꺼려졌다. 물론 저런 제한적인 상황 속에서 성능을 내야하고, 요청사항이 변경되어 수정해야 하는 상황 아니고서는 정말로 좋은 방법이다.

또 다른 두 번째 풀이를 보면 공백 26개를 포함하여 문자열에 담아 놓고 있다.. 그것을 배열로 순회하여 문자 하나하나 chars에 포함된 인덱스를 찾고 n만큼 더하고 있다. 이건 찐 하드코딩이다. 근데 정말 속도가 다른 풀이 방법들보다 빨랐다.. 결국은 멋진 풀이 방법이다.



참고 자료 및 사이트 (감사합니다)

profile
프론트엔드 개발자

0개의 댓글