07
13

1. Math.sqrt를 사용하지 않은 수숫점 구하기.

  • 입력받은 수를 제곱근 값을 소숫점 두 자리까지만 리턴한다.
  • 셋째 자리에서 반올림한다.
function computeSquareRoot(num) {
  // 기준을 잡아줄 소숫점 자리들의 가장 작은 수를 배열에 만든다.
  const decimal = [1, 0.1, 0.01, 0.001];
  //기준이 될 result를 1로 둔다.
  let result = 1;
  // 반복문으로 기준이 된 result를 제곱해서 num보다 작은 경우
  for (let i = 0; i < decimal.length; i++) {
    while (result * result < num) {
  //result에 소숫점 자리를 더한다. num가 더해진 기준의 제곱보다 커질때 까지 반복.
      result = result + decimal[i];
    }
  // 만약 result의 제곱이 num와 같을때 바로 리턴.
    if (result * result === num) {
      return result;
  // 아니면 소숫점 빼주고
    } else {
      result = result - decimal[i];
    }
  }
  //소숫점 3번째에서 반올림
  return Number(result.toFixed(2));
}
  • 다른 방법으로는 '바빌로니아 법의 점화식'이 있다고 한다. 나는 이해할 수 없다...

2. 카이사르 암호

  • 문자열과 숫자를 입력받아 입력받은 숫자만큼 평행 이동시킨 문자열을 리턴한다.
  • 공백은 무시한다.

[시도 1]

function decryptCaesarCipher(str, secret) {
  // 일단 스트링을 다 split으로 다 땐다.
  let newStr = str.split('');
  // 때어낸 문자를 아스키코드로 변환하여 넣는다.
  let arr = []
  for(let i = 0; i < newStr.length; i++) {
    arr.push(newStr[i].charCodeAt())
  }
  // 지금 이 배열이 아스키 코드로 바꾼 스트링이 들어있는 배열
  let ascii = arr.map(arr => arr - secret)
  let result = '';
  // 배열들을 돌면서 빈칸을 빈칸을 걸러내고
  for(let i = 0; i < ascii.length; i++) {
    if(ascii[i] === 29) {
      result = result + ' '
    } else {
    //남은건 다시 문자로 바꿔서 반환
      result = result + String.fromCharCode(ascii[i])
    }
  }
  return String(arr);
}
  • 실패
  • 아스키코드의 표에서 보면 secret으로 큰 수를 받을 경우, 소문자를 넘어 대문자까지 넘어간다.
  • 소문자 만을 범위로 secret을 정해주어서 97번부터 122번 사이에서만 secret이 변환되도록 만들어야 한다.

[시도 2]

function decryptCaesarCipher(str, secret) {
  let strArr = [abcdefghijklmnopqrstuvwxyz]
  let newStr = str.split('')
  let indexArr = [];
  for(let i = 0; i < newStr.length; i++) {
    indexArr.push(strArr.indexOf(newStr[i]))
    }
  return indexArr
  }
  • 완전히 틀린 코드이다.
  • 아예 나올 수 있는 알파벳을 모두 넣어서 그 배열 속에서 반복문으로 index를 매칭 시키려고 했지만 실패
  • 다시 아스키코드의 범위를 지정하는 방법으로 돌아가기로 하였다.

[시도 3]

function decryptCaesarCipher(str, secret) {
    let newStr = '';
    // str을 split으로 다 자른다.
    let splitStr = str.split('')
    // 자른 newStr에 for...of로 모든 배열들을 다 찾아서
    for(let i of splitStr) {
      // 만약 빈칸이면
        if(i === ' ') {
          // 빈칸을 넣고
          newStr = newStr + ' '
          } else {
            // 만약 아스키 코드 표에서 소문자가 되는 97을 넘으면 맞으면, secret이동 후에 - 122(최대 숫자) 총 알파벳 갯수가 26개 니까 나머지에 122 더한다.
            // 97보다 작으면, secret이동 후에 - 122 그리고 26 나눠서 나머지에 마찬가지 122 더한다.
            newStr = newStr + String.fromCharCode((i.charCodeAt(0) > 97) 
            	? (i.charCodeAt(0) - secret - 122) % 26 + 122 
                : (i.charCodeAt(0) - secret - 122) % 26 + 122)
            };
    }
    return newStr;
}
  • 문제 해결!
  • 조건을 걸 때, 총 알파벳 개수(26)와 최소 97, 최대 122가 나온다는 것을 바탕으로 범위를 정했다.
  • for... of와 삼항 연산자로 코드를 조금 더 간결하게도 바꿨다.
COMMENT