유한 소수의 결정

문제 설명
소수점 뒤에 계속되지 않고 유한한 십진수를 유한 십진수라고 합니다. 분수를 소수로 변환할 때 분수를 유한 소수로 나타낼 수 있는지 확인하려고 합니다. 분수가 유한 소수가 되기 위한 조건은 다음과 같습니다.

  • 기약분수로 나타낼 때 분모의 소인수는 2와 5만 있으면 됩니다.

매개변수로 두 개의 정수 a와 b가 주어지면 a/b가 유한 소수이면 1을 반환하고 무한 소수이면 2를 반환하도록 solve 함수를 완성합니다.


제한

  • ㅏ, b는 정수
  • 0 ≤ 1,000
  • 0 b ≤ 1,000

I/O 예시

결과
7 20 하나
11 22 하나
12 21 2

I/O 예시 설명

I/O 예제 #1

  • 분수 7/20은 기약 분수입니다. 분모에서 20의 소인수는 2와 5이므로 유한합니다. 그래서 1을 반환합니다.

I/O 예제 #2

  • 분수 11/22는 환산 분수로 표현하면 1/2입니다. 분모 2는 소인수가 2개뿐이므로 유한합니다. 그래서 1을 반환합니다.

I/O 예제 #3

  • 분수 12/21은 환산 분수로 4/7입니다. 7의 분모는 소인수가 7이므로 무한소수입니다. 따라서 2를 반환합니다.

알아채다

  • 기약 분수를 만들기 위해 분자와 분모의 최대 공약수로 줄입니다.
  • 정수도 유한 소수로 분류됩니다.

문제를 해결하다

from math import gcd
def solution(a, b):
    b //= gcd(a,b)
    while b % 2 == 0:
        b //= 2
    while b % 5 == 0:
        b //= 5
    return 1 if b == 1 else 2

문제를 풀면서 먼저 소수점에 접근하는 방법을 계산해보았는데, 소수점의 개수가 고정되어 있으면 유한소수, 무한대로 가면 하나의 무한소수이다.

나는 다른 사람들의 솔루션을 참조하여 해결했습니다.

이것을 기약분수로 표현하기 위해 gcd라는 함수를 사용하여 a와 b의 최대공약수를 먼저 구하고 이를 b로 나누는 형태로 다시 b에 대입하였다.

그런 다음 골절이 회복 불가능한지 여부를 확인할 수 있었습니다.

그리고 분모의 소인수는 2와 5라는 조건을 고려하여 분모 b를 2로 나누었을 때 나머지가 0인 경우를 while문을 이용하여 계속해서 b를 2로 나눈 다음, 5. while문을 이용하여 5로 나눌 때 나머지가 0인 경우를 찾아 b를 다시 5로 나누고 마지막에 b가 1이면 분수가 되고 그렇지 않으면 유한소수점이 된다. 무한 소수점이므로 1을 반환하고 2로 나누어 정답을 확인합니다.

추가 설명

※ 참고 – 2022년 11월 10일 테스트 케이스가 추가되었습니다. 이전에 제출한 코드가 실패할 수 있습니다.

문제 끝에 새로운 힌트를 추가했고 제가 처음 시도한 방식으로 소수점 이하 자릿수를 알아내는 조건이 있었다면 처음 시도했던 방식으로 풀 수 있었을 것 같습니다.

제가 먼저 시도한 방법과 유사한 솔루션에서,

def solution(a, b):
    return 1 if a/b * 1000 % 1 == 0 else 2

있었지만 그 현재 실패한 코드그리고 이전에 소수점 이하 자릿수가 제한되었을 때 풀 수 있는 코드였습니다.