오일러 프로젝트 45

오일러 프로젝트 45 번은 삼각수이면서, 오각수이고 동시에 육각수인 수를 찾는 문제이다.

삼각수, 오각수, 육각수는 아래 식으로 구할 수 있습니다.

 

삼각수 Tn = n (n + 1) / 2 1, 3, 6, 10, 15, …

오각수 Pn = n (3n − 1) / 2 1, 5, 12, 22, 35, …

육각수 Hn = n (2n − 1) 1, 6, 15, 28, 45, …

 

여기서 T285 = P165 = H143 = 40755 가 됩니다. 오각수와 육각수도 되는, 그 다음으로 큰 삼각수를 구하세요.

http://euler.synap.co.kr/prob_detail.php?id=45

접근

이 문제는 그리 어렵지 않아 보인다. 왜냐하면 각 수의 일반항은 모두 간단한 2차식으로 표현되며,  체크만 잘하면 될 것 같기 때문이다. 하지만 실제로 너무 나이브하게 접근했다가는, 경악스러운 수준의 실행 시간을 맛볼 수 있다.

이렇게 접근해보자. 홀수 번째 삼각수 T_{2k-1}는 다음과 같이 정리된다.

T_{2k - 1} = \frac{(2k - 1)(2k - 1 + 1) }{2} = \frac{k(2k - 1)}{2}

그리고 그 모양은 육각수의 일반항 식으로 귀결된다.  즉 모든 홀수 번째 삼각수는 항상 육각수이므로, 반대로 모든 육각수는 삼각수이다. 따라서 이 조건에 의해서 오각수가 육각수인지만 판별해나가면 된다. 육각수 판별식은 육각수 일반항 식을 역으로 풀어서 n이 자연수인지 판단한다.

파이썬 풀이

def is_hexagonal(k):
    n = (((8*k+1) ** 0.5) + 1 ) /4
    return int(n) == n

def pn(n):
    return n * ( 3 * n - 1) // 2

def e45():
    k = 166
    while True:
        pk = pn(k)
        if is_hexagonal(pk):
            print(pk)
            break
        k += 1

%time e45()
# Wall time: 98 ms