소스 코드

# 1,2,4로 만드는 숫자의 자리수와 시작 자연수
# otf_lst[1] == 3 == 1자리 자연수는 3까지
# otf_lst[2] == 12 == 2자리 자연수는 3부터 12까지
otf_lst = [0 for _ in range(19)]
for q in range(1,19):
    otf_lst[q] = otf_lst[q-1] + 3**q

    if otf_lst[q] > 500000000:
        break
otf = ['1','2','4']

def solution(n):

    # n의 자리수 찾기
    digit = 0
    for w in range(1,19):
        if otf_lst[w] >= n:
            digit = w
            break

    temp = ''
    
    # 시작위치
    s = otf_lst[digit-1]
    
    # 도착위치
    g = n
    for e in range(digit):

        if g != s:
            ee = (g-s) / (3**(digit-e-1))
            if ee <= 1:
                temp += otf[0]

            elif ee <= 2:
                temp += otf[1]

            else:
                temp += otf[2]

            s += (3**(digit-e-1)) * int(ee)

        else:
            temp += otf[(g-s)%3-1]

    answer = temp
    return answer

print(solution(30))

 


해결 방법

1. 1,2,4로 숫자를 만드는 것이기 때문에 숫자의 자리수는 3의 제곱단위로 변한다

ex) 1자리 수는 1,2,4 == 자연수 3까지는 1자리 수, 2자리 수는 11 ~ 44 == 자연수 4~12까지는 2자리 수

 

2. 자연수 n이 몇 자리 수(x)인지 구하고

 

3. (도착 지점(n) - 시작 지점) / (3**(x-1))를 통해 (3**(x-1))이 몇번 반복되는지 확인 후 temp에 값 추가

 

4. 시작 지점을 바꾸면서 반복

 

ex) 자연수 5의 경우

도착 지점은 5, 초기 시작 지점은 3(자연수 3 == '4', 1자리가 끝나는 지점임), x는 2

(5-3) / (3**(2-1)) == 0.xxx == '1'로 시작하는 값들을 0.xx만큼 지나왔다는 의미

== 현재 값은 '1'로 시작한다

(7의 경우에는 4 / 3 == 1.xxx == '1'로 시작하는 값들을 1만큼 지나왔고, '2'로 시작하는 값들을 0.xx만큼 지나왔다는 의미 == 현재 값은 '2'로 시작한다)

 


느낀 점

내가 생각한 방식을 코드로 풀어내는 것이 쉽지 않다보니 코드 자체가 좀 보기 싫게 만들어짐... ㅠㅠ

 

ps. 개인적인 코드와 코드를 작성의 이유를 적은 것입니다.

 

오류적절치 않은 문법이 존재할 수 있으며, 다른 분들께는 굉장히 비효율적인 방법으로 여겨질 수 있습니다.

 

혹시 개선 사항, 오류 및 문제에 대한 수정 사항 등을 댓글로 남겨주신다면 감사한 마음으로 배우고 수정하겠습니다.