크래프톤 정글 TIL : 1014

lazyArtisan·2024년 10월 14일
0

정글 TIL

목록 보기
106/147

⚔️ 백준


📌 Fraction to Recurring Decimal

# 나눠지는 수가 나누려는 수보다 작다면 크거나 같아질때까지 10을 곱한다
# 나눈 몫은 나눠지는 수에 10을 곱했던 만큼 10을 나눠준 뒤 합에 기록한다.
# 나머지로 또다시 나누려는 수보다 크거나 같아질때까지 10을 곱한다
# 나눌 때마다 반복되는 패턴이 있는지 확인한다. 반복되면 종료하고 출력한다.
# 나머지가 0이 되면 종료하고 출력한다

def find_rep(num):
    rep = ''
    i=1
    while num[len(num)-i]!='.': # 소수점까지 찾을건데요
        temp=num[len(num)-i:len(num)] # 맨 끝에서 하나씩 늘린건데요
        if 0<=len(num)-i-1-len(temp): # 비교할 자리가 있는지 확인할건데요
            pre=num[len(num)-i-len(temp):len(num)-i] # 비교할건데요
            if pre==temp:
                rep=temp
                break
        i+=1
    return rep

n,d=map(int,input().split())
debt=1
num = str(n/d)
if n%d==0: # 정수인데요
    print(int(n/d))
else: # 정수가 아닌데요
    num = 0
    while 1:
        while n < d:
            n = n * 10
            debt *= 10
        num += int(n // d) / debt
        n = n % d

        if n == 0:
            print(num)
            break

        rep = find_rep(str(num))
        if rep: # 도돌이표 찾았는데요
            idx = str(num).find(rep)
            for i in range(len(str(num))):
                if i == idx:
                    print('('+rep+')')
                    break
                print(str(num)[i],end='')
            break

어찌저찌 거의 다 풀었는데

분명 // 연산을 했으니 정수 몫으로 들어가야 할 친구가 갑자기 무한 소수점을 내뿜어버림.

num += int(n // d) * (1 / debt)

소수점 둘째 자리 이상으로 가면 애가 이상해지는 것 같아서
0.001을 곱하는 식으로 바꿨더니 문제는 해결.
근데 제출했더니 시간 초과 뜸.

str(num)을 일일이 연산하는게 아니라 변수에 담아서 한 번만 하게 바꿨는데
그게 문제가 아니라 1을 17로 나누는 테케에서 무한 반복이 일어났던 거.

아 또 이 오류네 진짜 미치겠네 ㅋㅋㅋㅋ

from decimal import Decimal, getcontext

getcontext().prec = 20
num += int(n // d) * Decimal(1) / Decimal(debt)

찾아보니까 부동소수점 관련 오류라고 함.
gpt한테 물어봤더니 getcontext.prec로 일정 자리수까지의 연산을 정확히 하게 하고
소수들에는 decimal 먹이면 된다고 해서 그대로 했더니

이렇게 돼버림. 이건 내 로직의 잘못..
같은 숫자가 하나라도 반복되면 그대로 이어지는 줄 알았음.

아니 그럼 반복된다는 걸 어떻게 앎?

단순히 일정 길이 이상일 때 끊고 도돌이표를 확인하는 건 불가능.
정확히 도돌이표가 끝나는 곳에서 끊긴다는 보장이 없기 때문.
최대 10배의 차이가 나니까 2번만 확인하면 진짜 도돌이표인지 아닌지 확인가능할듯.
도돌이표로 확인됐으면 카운트 하나 올리고 카운트 두 번 돼야 진짜 도돌이표로 인정?
이러면 도돌이표 길이가 2개인 걸 확인을 못함.

도저히 내 기존 로직으로는 안될 것 같아서
힌트 봤더니 뭔가 잡힐 것 같기도. 내가 했던 식으로
문자열을 일일이 되돌아가면서 확인하는게 아니라
나눈 나머지를 확인하면 될듯.

일단 여기까지. 내일 다시 시도해보기.

0개의 댓글