Symbol(clack:cancel)
This commit is contained in:
70
solutions/0000_0029/0023/euler_23.py
Normal file
70
solutions/0000_0029/0023/euler_23.py
Normal file
@@ -0,0 +1,70 @@
|
||||
"""
|
||||
A perfect number is a number for which the sum of its proper divisors is exactly equal to the number.
|
||||
For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28,
|
||||
which means that 28 is a perfect number.
|
||||
|
||||
A number n is called deficient if the sum of its proper divisors is less than n and
|
||||
it is called abundant if this sum exceeds n .
|
||||
|
||||
As 12 is the smallest abundant number, 1+2+3+4+6 = 16,
|
||||
the smallest number that can be written as the sum of two abundant numbers is 24.
|
||||
By mathematical analysis, it can be shown that all integers greater than 28123 can be written
|
||||
as the sum of two abundant numbers.
|
||||
However, this upper limit cannot be reduced any further by analysis even though
|
||||
it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than
|
||||
this limit.
|
||||
|
||||
Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.
|
||||
"""
|
||||
|
||||
import time
|
||||
|
||||
|
||||
def timer(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
start_time = time.time()
|
||||
result = func(*args, **kwargs)
|
||||
end_time = time.time()
|
||||
print(f"Execution time: {end_time - start_time} seconds")
|
||||
return result
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def is_abundant(n: int) -> bool:
|
||||
if n % 12 == 0:
|
||||
return True
|
||||
sum_divisors = [1]
|
||||
for i in range(2, n):
|
||||
if n % i == 0:
|
||||
if i not in sum_divisors:
|
||||
sum_divisors.append(i)
|
||||
if n // i not in sum_divisors:
|
||||
sum_divisors.append(n // i)
|
||||
if sum(sum_divisors) > n:
|
||||
return True
|
||||
return sum(sum_divisors) > n
|
||||
|
||||
|
||||
def is_sum_of_two_abundants(n: int) -> bool:
|
||||
if n < 24:
|
||||
return False
|
||||
if n == 24:
|
||||
return True
|
||||
for i in range(12, n // 2 + 1):
|
||||
if is_abundant(i) and is_abundant(n - i):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
@timer
|
||||
def main():
|
||||
limit = 28123
|
||||
non_abundant_sums = [
|
||||
i for i in range(1, limit + 1) if not is_sum_of_two_abundants(i)
|
||||
]
|
||||
print(sum(non_abundant_sums))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
45
solutions/0000_0029/0023/euler_23_s2.py
Normal file
45
solutions/0000_0029/0023/euler_23_s2.py
Normal file
@@ -0,0 +1,45 @@
|
||||
import time
|
||||
|
||||
from sympy import divisors
|
||||
|
||||
|
||||
def timer(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
start_time = time.time()
|
||||
result = func(*args, **kwargs)
|
||||
end_time = time.time()
|
||||
print(f"Execution time: {end_time - start_time:.6f} seconds")
|
||||
return result
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def is_abundant(n: int) -> bool:
|
||||
return sum(divisors(n)) > 2 * n
|
||||
|
||||
|
||||
def is_sum_of_two_abundants(n: int) -> bool:
|
||||
if n < 24:
|
||||
return False
|
||||
for i in range(12, n // 2 + 1):
|
||||
if is_abundant(i) and is_abundant(n - i):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
@timer
|
||||
def main():
|
||||
limit = 28123
|
||||
abundant_numbers = [n for n in range(1, limit + 1) if is_abundant(n)]
|
||||
non_abundant_sums = set(range(1, limit + 1))
|
||||
for i in range(len(abundant_numbers)):
|
||||
for j in range(i, len(abundant_numbers)):
|
||||
if abundant_numbers[i] + abundant_numbers[j] > limit:
|
||||
break
|
||||
non_abundant_sums.discard(abundant_numbers[i] + abundant_numbers[j])
|
||||
print(sum(non_abundant_sums))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
67
solutions/0000_0029/0023/euler_23_s3.py
Normal file
67
solutions/0000_0029/0023/euler_23_s3.py
Normal file
@@ -0,0 +1,67 @@
|
||||
import time
|
||||
|
||||
|
||||
def timer(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
start_time = time.time()
|
||||
result = func(*args, **kwargs)
|
||||
end_time = time.time()
|
||||
print(f"{func.__name__} took {end_time - start_time:.6f} seconds")
|
||||
return result
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def sum_of_non_abundant_numbers(limit=28123):
|
||||
"""
|
||||
计算所有不能表示为两个盈数之和的正整数之和
|
||||
|
||||
参数:
|
||||
limit: 上限值,默认为28123(欧拉计划官方推荐值)
|
||||
根据数学证明,所有大于28123的数都可以表示为两个盈数之和
|
||||
|
||||
返回:
|
||||
total: 所有满足条件的正整数之和
|
||||
"""
|
||||
|
||||
# 1. 使用筛法预处理所有数的真因数之和(高效O(n log n))
|
||||
divisor_sum = [0] * (limit + 1)
|
||||
for i in range(1, limit + 1):
|
||||
for j in range(i * 2, limit + 1, i):
|
||||
divisor_sum[j] += i
|
||||
|
||||
# 2. 找出所有盈数
|
||||
abundant_numbers = [i for i in range(12, limit + 1) if divisor_sum[i] > i]
|
||||
|
||||
# 3. 标记可以表示为两个盈数之和的数
|
||||
can_be_expressed = [False] * (limit + 1)
|
||||
abundant_set = list(set(abundant_numbers)) # 用于快速查找
|
||||
|
||||
# 遍历盈数对
|
||||
n_abundant = len(abundant_set)
|
||||
for i in range(n_abundant):
|
||||
a = abundant_set[i]
|
||||
if a > limit:
|
||||
break
|
||||
# 从i开始,允许两个相同的盈数相加(如12+12=24)
|
||||
for j in range(i, n_abundant):
|
||||
s = a + abundant_set[j]
|
||||
if s > limit:
|
||||
break
|
||||
can_be_expressed[s] = True
|
||||
|
||||
# 4. 计算所有不能表示为两个盈数之和的数的和
|
||||
total = sum(i for i in range(1, limit + 1) if not can_be_expressed[i])
|
||||
|
||||
return total
|
||||
|
||||
|
||||
@timer
|
||||
def main():
|
||||
# 执行计算
|
||||
result = sum_of_non_abundant_numbers()
|
||||
print(f"所有不能表示为两个盈数之和的正整数之和是:{result}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
10
solutions/0000_0029/0023/readme.md
Normal file
10
solutions/0000_0029/0023/readme.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# 盈数
|
||||
|
||||
[数列信息 OEIS](https://oeis.org/A005101)
|
||||
|
||||
-----
|
||||
|
||||
盈数(Abundant Number,又称过剩数)是指一个正整数,其所有真因数(proper divisors,即不包括自身的所有正因数)之和大于该数本身。
|
||||
所以质数不是盈数。这一点困惑了我一下,因为对真因数理解出误而致。这里特别记录以下这个问题。
|
||||
|
||||
另,自然解法三最好,不使用其他package的解法,速度也最快。
|
||||
Reference in New Issue
Block a user