[프로그래머스] LEVEL0 유한소수 판별 파이썬

그린·2023년 2월 15일
0

프로그래머스

목록 보기
5/28
post-thumbnail

[프로그래머스] LEVEL0 유한소수 판별


✔️문제

✅문제 설명

소수점 아래 숫자가 계속되지 않고 유한개인 소수를 유한소수라고 합니다. 분수를 소수로 고칠 때 유한소수로 나타낼 수 있는 분수인지 판별하려고 합니다. 유한소수가 되기 위한 분수의 조건은 다음과 같습니다.

기약분수로 나타내었을 때, 분모의 소인수가 2와 5만 존재해야 합니다.
두 정수 a와 b가 매개변수로 주어질 때, a/b가 유한소수이면 1을, 무한소수라면 2를 return하도록 solution 함수를 완성해주세요.

✅제한사항

  • a, b는 정수
  • 0 < a ≤ 1,000
  • 0 < b ≤ 1,000

입출력 예

abresult
7201
11221
12212

✔️풀이

🙋‍♀️내 풀이

테스트 케이스 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. yaksu() 함수는 n의 약수를 배열로 리턴해주는 함수이다.
    n이 i로 나누어 떨어지면 배열에 추가하고 n을 i로 나눠주고 i는 다시 1로 만들어준다. i를 다시 1로 만들어줌으로써 중복된 인수를 모두 찾을 수 있다.
  2. yaksu() 함수를 통해 찾은 분자와 분모의 약수들을 찾는다.
    2-1. 분모의 약수들에서 분자와 공통된 약수를 제외시켜 약분을 해준다.
  3. 분모의 남아 있는 약수들 중 [2,5]가 아닌 약수가 있으면 2를 없으면 1을 리턴해준다.

테스트 케이스 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을 리턴해준다.


👍오늘 배운 것

💡gcd(), lcm() 함수

from math import gcd 또는 import math
gcd, lcm 함수는 math 라이브러리에 속해있기 때문에 math 라이브러리를 import 해야한다.

  1. gcd() 최대 공약수 함수
    gcd의 인자로 숫자들을 입력하면, 인자로 들어온 숫자들의 최대 공약수를 반환한다.
    gcd는 인자가 없는 경우, 0을 반환한다.

  2. lcm() 최소 공배수 함수
    lcm의 인자로 숫자들을 입력하면, 인자로 들어온 숫자들의 최대 공배수를 반환한다.
    lcm은 인자가 없는 경우, 1을 반환한다.

0개의 댓글