質數3, 7, 109, 和 673是值得注意的。將其中任意兩個質數以任何順序相連線產生的結果都是質數。
例如,取7和109,連線而成的7109和1097都是質數。這四個質數的和是792,這也是滿足這個性質的四個質數集合的最小總和。
找出滿足這個性質的五個質數的集合中,集合數之和最小的。算出這個最小的和。
import time
defget_primes
(n):
""" n以下質數 """
n_set = set(range(3, n, 2))
for i in range(3, n, 2):
if i in n_set:
i_set = set(range(i * 2, n, i))
n_set -= i_set
return n_set
defis_prime
(x):
""" x是否質數 """
if x < n_max:
if x in primes_set:
return
true
else:
return
false
x_sqrt = int(pow(x, 0.5))
l = [2]
l.extend(range(3, x_sqrt + 1, 2))
for i in l:
if x % i == 0:
return
false
return
true
defcheck_prime_pair
(p1, p2):
""" 將其中任意兩個質數以任何順序相連線產生的結果都是質數 """
p1_p2 = int('%d%d' % (p1, p2))
if p1_p2 not
in primes_set:
ifnot is_prime(p1_p2):
return
false
p2_p1 = int('%d%d' % (p2, p1))
if p2_p1 not
in primes_set:
ifnot is_prime(p2_p1):
return
false
return
true
defprime_pair
(p):
""" 能與p組合以任何順序相連線產生的結果都是質數的質數集 """
if p in primes_dict:
return primes_dict[p]
primes = set()
for j in range(primes_list.index(p) + 1, len(primes_list)):
p_ = primes_list[j]
if check_prime_pair(p, p_):
primes.add(p_)
primes_dict[p] = primes
return primes
defget_prime_set
(p, pairs, sum_max):
""" 遞迴,五個質數的集合 """
if sum(p) + (5 - len(p)) * max(p) >= sum_max:
return sum_max
if len(p) == 4:
p.add(min(pairs))
print(p)
return sum(p)
for pp in pairs:
pairs_ = pairs & prime_pair(pp)
if len(pairs_) == 0:
continue
p_ = p.copy()
p_.add(pp)
sum_max_ = get_prime_set(p_, pairs_, sum_max)
if sum_max_ < sum_max:
sum_max = sum_max_
return sum_max
t1 = time.time()
n_max = 10000
primes_set = get_primes(n_max) -
sum_max = float('inf')
primes_dict = {}
# 按與3的餘數劃分質數集
# 餘數為1的數只能與餘數為1的數和3組合
# 餘數為2的數只能與餘數為2的數和3組合
for mod_3 in [2, 1]:
primes_list = [p for p in primes_set if p % 3 != mod_3]
primes_list.sort()
for i1 in range(len(primes_list)):
v1 = primes_list[i1]
if v1 * 5 >= sum_max:
break
v1_prime_pair = prime_pair(v1)
for i2 in range(i1 + 1, len(primes_list)):
v2 = primes_list[i2]
if v1 + v2 * 4 >= sum_max:
break
if v2 not
in v1_prime_pair:
continue
v2_prime_pair = prime_pair(v2)
for i3 in range(i2 + 1, len(primes_list)):
v3 = primes_list[i3]
if v1 + v2 + v3 * 3 >= sum_max:
break
if v3 not
in v1_prime_pair or v3 not
in v2_prime_pair:
continue
v3_prime_pair = prime_pair(v3)
for i4 in range(i3 + 1, len(primes_list)):
v4 = primes_list[i4]
if v1 + v2 + v3 + v4 * 2 >= sum_max:
break
if v4 not
in v1_prime_pair or v4 not
in v2_prime_pair or v4 not
in v3_prime_pair:
continue
v4_prime_pair = prime_pair(v4)
for i5 in range(i4 + 1, len(primes_list)):
v5 = primes_list[i5]
if v1 + v2 + v3 + v4 + v5 >= sum_max:
break
if v5 not
in v1_prime_pair or v5 not
in v2_prime_pair or v5 not
in v3_prime_pair or v5 not
in v4_prime_pair:
continue
sum_max = v1 + v2 + v3 + v4 + v5
print(v1, v2, v3, v4, v5)
print(sum_max)
t2 = time.time()
print(t2 - t1)
t1 = time.time()
n_max = 10000
primes_set = get_primes(n_max) -
primes_dict = {}
sum_max = float('inf')
# 按與3的餘數劃分質數集
# 餘數為1的數只能與餘數為1的數和3組合
# 餘數為2的數只能與餘數為2的數和3組合
for mod_3 in [2, 1]:
primes_list = [p for p in primes_set if p % 3 != mod_3]
primes_list.sort()
for i in primes_list:
sum_max = get_prime_set(, prime_pair(i), sum_max)
print(sum_max)
t2 = time.time()
print(t2 - t1)
尤拉計畫 6
前十個自然數的平方和是 1 2 2 2 10 2 385 前十個自然數的和的平方是 1 2 10 2 552 3025 所以平方和與和的平方的差是3025 385 2640.找出前一百個自然數的平方和與和平方的差。def get square sub x 遞迴,展開行列式 if x 1 return...
尤拉計畫 14
以下迭代序列定義在整數集合上 n n 2 當n是偶數時 n 3n 1 當n是奇數時 應用以上規則,並且以數字13開始,我們得到以下序列 13 40 20 10 5 16 8 4 2 1 可以看出這個以13開始以1結束的序列包含10個項。雖然還沒有被證明 collatz問題 但是人們認為在這個規則下,...
尤拉計畫 15
從乙個2 2網格的左上角開始,有6條 不允許往回走 通往右下角的路。對於20 20的網格,這樣的路有多少條?def get load num x,y x,y 網格的路數等於 x 1,y x,y 1 if x 0 or y 0 return 1return get xy load x 1,y get ...