[JS]_daily coding #18

seul·2022년 6월 18일
0

Algorithm

목록 보기
17/31

코플릿 데일리코딩 17_computeSquareRoot


문제에 제시된 힌트를 찾고 이해하는데만도 한 세월 걸렸다.. 바빌로니아 점화식, 각 자리수마다 근사값을 구하는 방식.... 결론적으로 오늘은 혼자 힘으로 코드를 시간 안에 짜지 못했다. 아래의 내용은 레퍼런스 코드, 다른 블로그에서 제시한 풀이를 보고 이해해본 과정을 적어놓은 것이다.


바빌로니아 법은 임의의 수의 제곱근에 수렴하는 수열을 만들어서 제곱근의 근삿값을 구하는 방법이다.

수도 코드 (바빌로니아 점화식 이용)

  1. 2이상의 정수를 입력받아 제곱근 값을 반환(최대 소수점 둘째 자리까지)한다. 이때, Math.sqrt() 사용하지 않는다.
  2. 임의의 근사값(approx)을 변수로 선언하고 1을 할당한다.
  3. approx를 제곱한 값이 num과 같지 않을 경우 바빌로니아 점화식 (approx + (num /approx)) /2 반복해서 approx에 할당한다. while문
  4. 점화식 반복을 통해서 구하는 값은 근사값이기 때문에 num이 정수의 제곱이 아닐 경우에는 완벽히 같아질 수 없다 -> 무한 루프에 빠지지 않으려면 반복문 안에서 조건을 걸어서 break로 빠져나올 수 있게 한다.
  5. 점화식을 통해 구한 근사값을 제곱하여 소수점 셋째 자리에서 반올림한 값이 num과 같아지는 경우에 반복문을 빠져 나올 수 있도록 한다.
  6. 반복문을 빠져나온 근사값을 소수점 둘째 자리까지 구해서 리턴한다.

코드

toFixed()메서드는 고정 소수점 표기법을 사용하여 나타낸 수를 문자열로 바꾼 값을 리턴하기 때문에 리턴된 문자열을 숫자로 만들어주기 위해서 Number() 함수를 이용해야 한다.

function computeSquareRoot(num) {
  let approx = 1;

  while(approx ** 2 !== num) { 
    if ( Number((approx ** 2).toFixed(2)) === num) { //무한루프에 빠지지 않기 위한 조건식
    break;
    }
    approx = (approx + (num /approx)) /2 //바빌로니아 점화식을 반복해서 approx에 할당한다.
  }
  return Number(approx.toFixed(2)) // 소수점 세번째자리에서 반올림한 값을 반환 

}

수도코드 (각 자리수마다 근사값을 구하는 방식)

  1. 임의의 근사값(approx)을 변수로 선언하고 1을 할당한다.
  2. 1의 자리부터 소수점 셋째 자리까지 근사값을 구하기 위해서 각 자리수의 값(1, 0.1, 0.01, 0.001)을 배열로 담는다.
  3. 배열을 순회하면(각 각자리수마다) 근사값을 구해나간다.
  4. approx를 제곱한 값이 num 보다 작은 경우(크지 않을때까지는) digit을 더해서 근사값을 찾는다. while문
  5. while문을 빠져나와서 approx를 제곱한 값이 num 과 같은 경우는 우리가 구한 근사값이 num의 제곱근인 것이기 때문에 approx를 그대로 리턴한다.
  6. approx를 제곱한 값이 num 과 같지 않은 경우는 while반복문을 빠져나오기 전에 마지막에 한번 더 digit이 더해졌기 때문에 다시 빼준다.
  7. 자리수 배열의 순회를 마치고 소수점 셋째 자리까지 근사값을 구한 approx를 소수점 둘째 자리까지 구해서 리턴한다.

코드

function computeSquareRoot(num) {
  const digits = [1, 0.1, 0.01, 0.001];
  let approx = 1; 
  for (let digit of digits) {
    // approx의 제곱이 num 보다 크지 않을때까지 digit을 더해서 근사값을 찾는다
    while (approx ** 2 < num) {
      approx += digit;
    }
    if (approx ** 2 === num) {
      return approx;
    } else {
      approx -= digit; //approx에 한번 더 digit이 더해졌기 때문에 다시 빼준다
    }
  }  
  return Number(approx.toFixed(2)) // 소수점 세번째자리에서 반올림한 값을 반환 
}

참고

profile
Connecting dots

0개의 댓글