소수점 아래 숫자가 계속되지 않고 유한개인 소수를 유한소수라고 합니다. 분수를 소수로 고칠 때 유한소수로 나타낼 수 있는 분수인지 판별하려고 합니다. 유한소수가 되기 위한 분수의 조건은 다음과 같습니다.
기약분수로 나타내었을 때, 분모의 소인수가 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
}