歐拉計劃 37

3797這個數很有趣。它本身是質數,而且如果我們從左邊不斷地裁去數字,得到的仍然都是質數:3797,797,97,7。
而且我們還可以從右向左裁剪:3797,379,37,3,得到的仍然都是質數。

找出全部11個這樣從左向右和從右向左都可以裁剪的質數。

注意:2,3,5和7不被認爲是可裁剪的質數。

import math
import itertools


def is_prime(x):
    """ x是否質數 """
    if x == 1:
        return False
    if x == 2:
        return True
    assert math.floor(x) == x and x > 0
    x_sqrt = int(math.sqrt(x))
    l = [2]
    l.extend(range(3, x_sqrt + 1, 2))
    for i in l:
        if x % i == 0:
            return False
    return True


def is_prime_all(l):
    """
    左邊不斷地裁去數字\從右向左裁剪都爲質數
    """
    l_len = len(l)
    for i_l in range(l_len):
        l_ = l[i_l: ]
        if not is_prime(sum([v * 10 ** (len(l_) - 1 - i) for i, v in enumerate(l_)])):
            return False
        l_ = l[: i_l + 1]
        if not is_prime(sum([v * 10 ** (len(l_) - 1 - i) for i, v in enumerate(l_)])):
            return False
    return True


n_max = 11
n = 0
digit = 2
while n < n_max:
    # 首尾只能是質數
    for i_digit in [2, 3, 5, 7]:
        for i_1 in [3, 7]:
            for i_mid in itertools.product([1, 3, 7, 9], repeat=digit-2):
                if digit > 2:
                    n_list = [i_digit]
                    n_list.extend(list(i_mid))
                    n_list.append(i_1)
                else:
                    n_list = [i_digit, i_1]
                if is_prime_all(n_list):
                    n += 1
                    print(sum([n_list[i] * 10 ** (digit - 1 - i) for i in range(digit)]))
    digit += 1
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章