Level 0) 유한소수 판별하기 ⭐️

Doozuu·2023년 1월 24일
0

프로그래머스 (JS)

목록 보기
23/183

문제 설명

소수점 아래 숫자가 계속되지 않고 유한개인 소수를 유한소수라고 합니다. 분수를 소수로 고칠 때 유한소수로 나타낼 수 있는 분수인지 판별하려고 합니다. 유한소수가 되기 위한 분수의 조건은 다음과 같습니다.

기약분수로 나타내었을 때, 분모의 소인수가 2와 5만 존재해야 합니다.
두 정수 a와 b가 매개변수로 주어질 때, a/b가 유한소수이면 1을, 무한소수라면 2를 return하도록 solution 함수를 완성해주세요.

힌트

  • 분자와 분모의 최대공약수로 약분하면 기약분수를 만들 수 있습니다.
  • 정수도 유한소수로 분류합니다.

풀이

원래 분모를 최대공약수로 나눈 후에 while을 통해 2나 5로 계속 나누어서 나머지가 1이 되면 2, 0이 되면 1을 return하려고 했는데 잘 풀리지 않았다.
그래서 어쩔수없이 분모를 소인수분해해서 배열에 담아 2나 5가 아닌 다른 수가 있는지 체크했다.

function solution(a, b) {
    let arr = [];
  // 정수일 경우
    if(a%b === 0){
        return 1;
    }
  // 최대공약수
    function fnGCD(c,d){
        return (c%d) ? fnGCD(d, c%d) : d;
    }
  // 소인수분해
    function primeFactors(n){
      while (n % 2 === 0) {
        arr.push(2);
        n /= 2;
      }
      for (let i = 3; i * i <= n; i += 2) {
        while (n % i === 0) {
          arr.push(i);
          n /= i;
        }
      }
      if (n > 2) arr.push(n);
      return arr;
    };
  // 분모 소인수분해한 것 체크하기
    return primeFactors(b/fnGCD(a,b)).map(n => n == 2 || n == 5 ? "o" : "x").includes("x") ? 2 : 1;
}

원래 생각했던 방향으로 풀기

분모를 2와 5로 나누어떨어질 때까지 나눈 다음, 분자와 나누었을 때 나누어떨어지면 유한소수 아니면 무한소수이다.
(분모를 2와 5로 먼저 다 나눠버린 다음에 분자와 나누면, 원래 정수인 경우와 기약분수로 나타냈을 때 유한소수가 되는 경우를 한 번에 다룰 수 있다.)

function solution(a, b) {
    while (b % 2 === 0) b /= 2;
    while (b % 5 === 0) b /= 5;
    return a % b === 0 ? 1 : 2;
}

신박한 풀이

Number.toFixed(n)는 소수점 n자리까지의 숫자를 반환해준다.
테스트 케이스의 유한소수가 소수점 아래 10자리 이하일 때까지 구분하기 좋다.
(단, 그 보다 더 큰 극단적인 케이스가 있을 때는 틀릴 수 있다.)

function solution(a, b) {
    return Number((a/b).toFixed(10)) == a/b ? 1 : 2
}
profile
모든게 새롭고 재밌는 프론트엔드 새싹

0개의 댓글