프론트엔드✏️/코드캠프

알고리즘 - 시저암호, 아스키코드 두시간 걸렸다...

당근먹는하니 2022. 6. 14. 15:43
728x90
반응형

 

 

시저암호

 

// 짱 많이 틀림... 
function solution(s, n) {
    var answer = '';
  let arr = [];
  console.log(s, n); // a b c d e 
  
	for(let i = 0; i<s.length; ++i) {
  	arr.push(s[i].charCodeAt());
    (arr[i]!==32) ? arr[i] += n : arr[i] += 0;
    if((arr[i]>90 && arr[i]<97) || (arr[i]>122)){
      arr[i] -= 26;
    } 
    console.log(arr)
    answer += String.fromCharCode(arr[i]);
    console.log(answer)
  }
    return answer;
}

6,7,8,10,12 틀림

  • n은 1 이상, 25이하인 자연수입니다. 

라는데 질문하기방에 보니까 25넘어도 통과해야 한다고 한다. =ㅅ=? 

 

그래서 

    (arr[i]!==32) ? arr[i] += n%25 : arr[i] += 0;

로 n%25를 했고 27넣으면 2 넣은거랑 똑같이 값이 나오는ㄷㅔ,... 이게 아닌가? 

 

댓글에서 발견,, "아스키코드를 다루신다고 가정을 했을때,
n이 20정도로 크게 넘어가면 어떻게 될지 생각 해보시면 됩니다.
대문자는 대문자로 소문자는 소문자로 루프가 되야 할텐데
대문자에서 갑자기 소문자로 바뀌게 되는 이슈 때문에 생기는 오류에요!
이에 대응할 알고리즘을 구현하시면 됩니다 :)"

 

그런가...그런가////????

오헐 실제로 Z랑 Y가 소문자가 됐어...

Z의 아스키코드 : 90

Y의 아스키코드 : 89

r의 아스키코드 : 114

q의 아스키코드 : 113

 

24를 더하니 97-122 사이의 아스키코드로 들어가서 소문자가 되었다. 그것도 아예 다른 문자...음

대문자는 65-90범위 내에서, 소문자는 97-122 범위에서 놀게 해줘야 한다. 

 

Z의 아스키코드 90에 24를 더하면 114지만 내가 원하는 결과는 Y..야? X야? 이런 계산 잘 안돼..ㅎㅎ  X가 나와야함!

X의 아스키코드는 88. 114랑 88 차이는 26이다. 

 

 (arr[i]!==32) ? arr[i] += n%25 : arr[i] += 0;
    if((arr[i]>90 && arr[i]<97) || (arr[i]>122)){
      arr[i] -= 26;
    }

26만큼 빼긴 빼야하는데, 그 빼는 타임이 안 맞는 것 같다...

n이 24면 n%25를 +=했을 때 값이 114로 유효한 값이긴 하기 때문에 -26에 걸러지지 못한다.

아~₩~~~어덕하지 ...

처음부터 그 값에 못 가게 하는 거다. 아스키코드 + n이 90을 넘으면 -26을 한다. 정확히는 아스키코드가 90을 넘지 않고, 아스키코드 + n이 90을 넘으면 -26한다. (대문자인데 n을 더했을 땐 소문자로 넘어가버리는 경우 -26) 소문자도 마찬가지로 아스키코드 + n이 122를 초과하면 -26해준다. 

 

코드를 밑에처럼 수정했다. 

 

if((arr[i]<90 && arr[i] + n >90) || (arr[i]+n>122)){
      arr[i] -= 26;
    } 
    (arr[i]!==32) ? arr[i] += n%25 : arr[i] += 0;

6,7,9,11,12,13 이 틀림 

더 많이 틀리는 것 같은데...?? ? 

 

아, 저 조건에만 -= 하고 n을 더하고... 그래서 안됐던 것!!

 

 

아 드디어ㅠㅠㅠㅠㅠ

 

 

// 전체 코드
function solution(s, n) {
    var answer = '';
  let arr = [];
  console.log(s, n);
	for(let i = 0; i<s.length; ++i) {
  	arr.push(s[i].charCodeAt(0));
    if((arr[i]<=90 && arr[i] + n >90) || (arr[i]+n>122)){
      arr[i] = arr[i]+n-26;
    } else {
      arr[i]!==32 ? arr[i] += n: arr[i] += 0;
    }
    answer += String.fromCharCode(arr[i]);
  }
    return answer;
}
// 잠깨는껌
solution("zZ Yy y z bB", 24);
solution("zZ Yy y z bB", 2)

드디어 통과 코드.... 테스트 케이스 이런 걸 해보면서 예외처리 하는 게 중요한 것 같다.

진짜 알고리즘 문제 풀면서 제일 오래걸렸다. 아침에 50분 정도 풀고 점심 먹고 한 시간, 짬내서 10분 정도 총 두시간 걸렸다ㅋㅋ...ㅋㅋㅋ 

그래도 어렵게 푸니까 너무 뿌듯해🥹 

그리고 다들 옆에서 숙제하는 소리가 들려서... 나 너무 숙제 안 하고 알고리즘 푸는 거 아닌가 약간 그런 생각도 들었다. 아니ㅣ~~생각해보면.... 수능도 같은 시험 치는거지만 다들 동시에 같은 거 공부하나????아니잖,아,, 신경쓰지말자~~~~~~ 

 

밑에는 그냥 아예 틀림.. 시도에 의의를 두고... ㅎㅎ  

// 실패..>! 

function solution(s, n) {
    var answer = '';

  // Big = ['A', 'B', 'C', 'D', 'E', 'F', 'G','H']
  let Big = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
  let Bigarr = [];
  Bigarr = Big.split('')
	let Small = 'abcdefghijklmnopqrstuvwyz';
  Smallarr = Small.split('');
  let split = s.toLowerCase().split('');
  console.log(Small.indexOf(split[4]))
    let idx = [];  
  	let arr = [];
  for(let i = 0; i < s.length; ++i) {
    idx.push(Smallarr.indexOf(split[i]))
    console.log(idx);
    (idx[i] >= 24 || idx[i] === -1) ? idx[i] %= 24 : idx[i] += n;
  arr[i] = (Small
  }
  
  
  
  console.log(Bigarr)  
  return answer;
}

 


멘토님 코드 

진짜 대천재같아,,, 

 

 


else에는 문자열만 들어오게 된다.

word라는 상수값을 두고, lowerCase 문자열을 가져와서 includes 검사

const word = lowerCase.inludes(s[i]); true가 떴다는 건 → 소문자니까 lowerCase 저장, false면 upperCase 저장

그 후에 idx로 찾아옴

 

이 상태에서 n만큼 밀어본다.

26자를 넘어갔을 때 조건식을 준다.

if(idx ≥ 26) { idx -= 26; }


메서드로 풀기

 

 

lowerCase에 cur이 있다면, lowerCase, 없다면 upperCase

근데 ' '도 대문자로 갖고오게 돼.(else로 빠졌기 때문에)

 

let idx = word.indexOf(cur) 몇번째 위치에 있는지 찾는다. 그럼 공백은 -1을 가져오게 됨(대문자에 없으니까~)

 

그리고 n만큼 밀어주면 몇번째 인덱스를 가져오는지 확인!

 

그리고 알파벳 범위를 넘어섰는지 판단해준다. 26이상이면 26을 빼준다. 

 

누적값에 해당 알파벳을 더해서 넘겨줘야함!

 

acc + (cur === " "? " " : word[idx]);

 

 

성급하게 문자로 바꿀 생각 안 해두 되고 몇번째 인덱스 가져오는지 확인하고!

reduce는 배열이 필요하단 것 기억하고! 문자열에도 쓸 수 있다는 것 기억하고!!

 

 

완전 다른 방식으로 풀기~ 

 

"a".charCodeAt() 97

 

 

728x90
반응형