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