소수점 아래 숫자가 계속되지 않고 유한개인 소수를 유한소수라고 합니다. 분수를 소수로 고칠 때 유한소수로 나타낼 수 있는 분수인지 판별하려고 합니다. 유한소수가 되기 위한 분수의 조건은 다음과 같습니다.
기약분수로 나타내었을 때, 분모의 소인수가 2와 5만 존재해야 합니다.
두 정수 a와 b가 매개변수로 주어질 때, a/b가 유한소수이면 1을, 무한소수라면 2를 return하도록 solution 함수를 완성해주세요.
질문하기에 있던 반례들을 다 적용해보았으나
여전히 6, 11, 25, 45번에서 실패했다...
function solution(a, b) {
// 분모가 1이면 무조건 정숭이기 때문에
if (b === 1) return 1;
// 기약분수로 만들기
[2, 3, 5, Math.min(a, b)].forEach(ele => {
if (a !== 1) {
while((a % ele === 0) && (b % ele === 0)) {
a /= ele;
b /= ele;
}
}
})
// 분모가 2와 5로만 이뤄져 있는지 확인하기
while((b % 2 === 0) || (b % 5 === 0)) {
if (b % 2 === 0) b /= 2;
if (b % 5 === 0) b /= 5;
}
return b === 1 ? 1 : 2;
}
해당 문제에 대한 해결방법을 구글링한 결과
한 줄 짜리 풀이도 있었다.
function solution(a, b) {
return Number((a/b).toFixed(10)) === a/b ? 1: 2;
}
toFixed(10)으로 하는 이유는
소수점 아래 자리가 10이 넘어갈 경우 무한소수 확률이 높기 때문에 통과가 가능하다는 설명이였따.
추가로, toFixed()는 문자열로 반환하기 때문에 숫자로 변환해줘야 한다.
[참고풀이1, 참고풀이2]
function solution(a, b) {
let num = 1;
// 최대공약수 구하기(최대공약수는 a의 약수이면서 b의 약수인 수 중 가장 큰 수)
for(let i = 1; i <= Math.min(a,b); i++) {
if ((a % i === 0) && (b % i === 0)) {
num = i;
}
}
// 분모를 최대공약수로 나눠서 기약분수의 분모로 만듬
b /= num;
// 분모가 2와 5로만 이뤄졌는지 확인하기
while(b % 2 === 0) b/= 2;
while(b % 5 === 0) b/= 5;
return b === 1 ? 1 : 2;
}