[코딩 테스트 연습 입문] 유한소수 판별하기
문제
소수점 아래 숫자가 계속되지 않고 유한개인 소수를 유한소수라고 합니다. 분수를 소수로 고칠 때 유한소수로 나타낼 수 있는 분수인지 판별하려고 합니다. 유한소수가 되기 위한 분수의 조건은 다음과 같습니다.
- 기약분수로 나타내었을 때, 분모의 소인수가 2와 5만 존재해야 합니다.
두 정수 a와 b가 매개변수로 주어질 때, a/b가 유한소수이면 1을, 무한소수라면 2를 return하도록 solution 함수를 완성해주세요.
❗제한사항❗
- a, b는 정수
- 0 < a ≤ 1,000
- 0 < b ≤ 1,000
입출력 예
입출력 예 설명
입출력 예 #1
- 분수 7/20은 기약분수 입니다. 분모 20의 소인수가 2, 5 이기 때문에 유한소수입니다. 따라서 1을 return합니다.
입출력 예 #2
- 분수 11/22는 기약분수로 나타내면 1/2 입니다. 분모 2는 소인수가 2 뿐이기 때문에 유한소수 입니다. 따라서 1을 return합니다.
입출력 예 #3
- 분수 12/21는 기약분수로 나타내면 4/7 입니다. 분모 7은 소인수가 7 이므로 무한소수입니다. 따라서 2를 return합니다.
Hint
- 분자와 분모의 최대공약수로 약분하면 기약분수를 만들 수 있습니다.
- 정수도 유한소수로 분류합니다.
✔풀이
def solution(a, b):
for num in range(a,1,-1):
if (a%num==0) and (b%num==0):
a=a/num
b=b/num
while b!=1:
if b%2==0:
b=b//2
elif b%5 == 0:
b= b//5
else:
return 2
return 1
📝설명
문제에서는 a를 분자로 하고 b를 분모로 하는 분수를 만들고, 기약분수를 만든 후, 유한소수인지를 판단하여 결과를 return 하도록 지시했다.
기약분수를 만든 후, 분모를 2와 5로 계속 나누어 결론적으로 1이 나온다면 2로 return, 분모가 1이 되지 않는다면 1로 return 해야겠다고 생각했다.
for문은 기약분수를 만드는 과정이고, while문은 유한소수 여부를 판단하는 코드이다.
for문에서는 a부터 2까지 계속해서 내려서 숫자 num을 꺼내고, num이 a와 b에 모두 나누어진다면 나눈 몫을 a와 b에 재할당하도록 했다.
for문을 통해 기약분수화 된 a와 b는 이제 분모인 b만 가지고 while문에서 유한소수인지를 판단하는 데에 쓰인다.
분모 b에 2나 5를 나누어 나머지가 0인 경우에는, b에 몫을 할당한다.
만약 b가 1이 아닌데, 2나 5로 나누어지지 않는다면 2를 return 하도록 한다.
b가 1이 아니라면 이라고 while문의 조건을 건 이유는, b가 만약에 유한소수라서 2와 5로 나누어진다면 결국 마지막에는 1이 될 것 이기 때문이다.
while문에서 유한소수가 아닌 경우를 return 했기 때문에! while문이 끝나고 난 다음에는 1를 return 하도록 한다.
👑모범 답안
🔎 math의 gcd는 최대 공약수를 구할 수 있다.
여기에서는 b를 a와 b의 최대 공약수로 나누어 재정의 하였다.
이렇게 나온 b를 while문에서 2로 나누어 나머지가 0인 동안에 계속해서 2로 나눈 값을 다시 b에 저장하는 걸 반복한다.
해당 while문이 끝나고 나면 또다른 while문으로 5로 나누어지면 b를 5로 나눈 값을 b에 다시 저장하는 걸 반복한다.
5로 나눴을 때 나머지가 생긴다면, 해당 나머지가 1인 경우에는 1로, 아닌 경우에는 2로 return 한다.
👀느낀 점
: gcd를 저번에 혼자서 공부했는데, 또 까먹은 채로 문제를 해결했다.
복습이 중요하다. 복습.. 복습..
💻 문제 출처