✅문제 설명
소수점 아래 숫자가 계속되지 않고 유한개인 소수를 유한소수라고 합니다. 분수를 소수로 고칠 때 유한소수로 나타낼 수 있는 분수인지 판별하려고 합니다. 유한소수가 되기 위한 분수의 조건은 다음과 같습니다.
기약분수로 나타내었을 때, 분모의 소인수가 2와 5만 존재해야 합니다.
두 정수 a와 b가 매개변수로 주어질 때, a/b가 유한소수이면 1을, 무한소수라면 2를 return하도록 solution 함수를 완성해주세요.✅제한사항
- a, b는 정수
- 0 < a ≤ 1,000
- 0 < b ≤ 1,000
입출력 예
a b result 7 20 1 11 22 1 12 21 2
테스트 케이스 1번과 10번에서 실패가 나온 코드
def yaksu(n) :
answer = []
i=1
while i<=n :
if n%i == 0:
answer.append(i)
n = n//i
i=1
i = i+1
return answer
def solution(a, b):
answer = 1
yak_a = yaksu(a)
yak_b = yaksu(b)
yak_b = [i for i in yak_b if i not in yak_a]
for e in yak_b:
if e not in [2,5]:
answer = 2
return answer
테스트 케이스 1,10번이 실패라고 떠서 어떤 예외가 있을까 생각해봤다.
yak_a = [1,2,3]
yak_b = [1,2,3,3,5]
위와 같을 때, yak_b = [i for i in yak_b if i not in yak_a]
를 이용하면 [5]만 남게 된다. 즉, 공통된 인수는 횟수 상관없이 걸러지기 때문에 약분되고도 남아있는 3을 발견하지 못한다. 따라서 다음과 같이 코드를 수정하였다.
## 수정한 코드
def yaksu(n) :
answer = []
i=1
while i<=n :
if n%i == 0:
answer.append(i)
n = n//i
i=1
i = i+1
return answer
def solution(a, b):
answer = 1
yak_a = yaksu(a)
yak_b = yaksu(b)
dic = {}
for e in yak_b:
if e not in dic:
dic[e] = 1
else:
dic[e] += 1
for e in yak_a:
if e in dic:
dic[e] -= 1
for k,v in dic.items() :
if k not in [2,5] and v > 0:
return 2
return answer
딕셔너리를 사용하여 분자와 분모의 인수 개수를 세서 약분 후 남아있는 인수를 인수:인수의 개수로 나타내었다. 그 후 2나 5가 아닌 인수(key)의 개수(value)가 0보다 크면 2를 리턴시켜 해결하였다.
from math import gcd
def solution(a, b):
b = b / gcd(a, b)
for i in [2, 5]:
while not b % i:
b //= i
return 1 if b == 1 else 2
math 라이브러리에 있는 gcd(), lcm() 함수를 사용하여 풀이했다.
1. 분모를 최대 공약수로 나눠준다. 즉, 기약분수로 만들어줬을 때의 분모값으로 만든다.
2. 2나 5로 나눠질 때까지 나눈다.
2-1. 나머지가 0이 아닐 때. 즉, 더 이상 나눠지지 않을 때의 몫이 1이라면 1을 리턴, 아니라면 2을 리턴해준다.
from math import gcd
또는 import math
gcd, lcm 함수는 math 라이브러리에 속해있기 때문에 math 라이브러리를 import 해야한다.
gcd() 최대 공약수 함수
gcd의 인자로 숫자들을 입력하면, 인자로 들어온 숫자들의 최대 공약수를 반환한다.
gcd는 인자가 없는 경우, 0을 반환한다.
lcm() 최소 공배수 함수
lcm의 인자로 숫자들을 입력하면, 인자로 들어온 숫자들의 최대 공배수를 반환한다.
lcm은 인자가 없는 경우, 1을 반환한다.