feat: 添加欧拉计划第49题“素数排列”的Python解法
This commit is contained in:
85
solutions/0049.PrimePermutations/euler_49.py
Normal file
85
solutions/0049.PrimePermutations/euler_49.py
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
"""
|
||||||
|
The arithmetic sequence, 1487,4817,8147, in which each of the terms increases by 3330,
|
||||||
|
is unusual in two ways: (i) each of the three terms are prime, and, (ii) each of the
|
||||||
|
4-digit numbers are permutations of one another.
|
||||||
|
|
||||||
|
There are no arithmetic sequences made up of three 1-, 2-, or 3-digit primes, exhibiting this property,
|
||||||
|
but there is one other 4-digit increasing sequence.
|
||||||
|
|
||||||
|
What 12-digit number do you form by concatenating the three terms in this sequence?
|
||||||
|
"""
|
||||||
|
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
def timer(func):
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
start_time = time.time()
|
||||||
|
result = func(*args, **kwargs)
|
||||||
|
end_time = time.time()
|
||||||
|
elapsed_time = end_time - start_time
|
||||||
|
print(f"{func.__name__} time: {elapsed_time:.6f} seconds")
|
||||||
|
return result
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
def list_primes(start: int, end: int) -> list[int]:
|
||||||
|
# 只需要筛到 sqrt(9999) ≈ 100 即可标记合数
|
||||||
|
limit = int(end**0.5) + 1
|
||||||
|
base_primes = [True] * limit
|
||||||
|
base_primes[0] = base_primes[1] = False
|
||||||
|
|
||||||
|
# 生成基础质数(2到100)
|
||||||
|
for i in range(2, int(limit**0.5) + 1):
|
||||||
|
if base_primes[i]:
|
||||||
|
for j in range(i * i, limit, i):
|
||||||
|
base_primes[j] = False
|
||||||
|
|
||||||
|
# 分段筛:只标记1000-9999范围
|
||||||
|
size = end - start + 1
|
||||||
|
is_prime = [True] * size
|
||||||
|
|
||||||
|
for p in range(2, limit):
|
||||||
|
if base_primes[p]:
|
||||||
|
# 找到第一个大于等于start的p的倍数
|
||||||
|
first = max(p * p, ((start + p - 1) // p) * p)
|
||||||
|
for j in range(first, end + 1, p):
|
||||||
|
is_prime[j - start] = False
|
||||||
|
|
||||||
|
return [i + start for i, val in enumerate(is_prime) if val]
|
||||||
|
|
||||||
|
|
||||||
|
def list_com(a: list, b: list) -> bool:
|
||||||
|
if len(set(a)) != len(set(b)):
|
||||||
|
return False
|
||||||
|
xb = b.copy()
|
||||||
|
for x in a:
|
||||||
|
if x not in xb:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
xb.remove(x)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@timer
|
||||||
|
def main():
|
||||||
|
primes = list_primes(1000, 9999)
|
||||||
|
max_sp = max(primes)
|
||||||
|
res = []
|
||||||
|
for i, v in enumerate(primes):
|
||||||
|
if v == max_sp:
|
||||||
|
break
|
||||||
|
gap = int((max_sp - v) / 3)
|
||||||
|
for g in range(gap, (primes[i + 1] - v - 1), -1):
|
||||||
|
if v + g in primes and v + 2 * g in primes:
|
||||||
|
if list_com(list(str(v)), list(str(v + g))):
|
||||||
|
if list_com(list(str(v)), list(str(v + 2 * g))):
|
||||||
|
res.append(str(v) + str(v + g) + str(v + 2 * g))
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
print(res)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user