d(n)定义为n 的所有真因子(小于 n 且能整除 n 的整数)之和。
如果 d(a) = b 并且 d(b) = a, 且 a ≠ b, 那么 a 和 b 就是一对相亲数(amicable pair),
并且 a 和 b 都叫做亲和数(amicable number)。
例如220的真因子是 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 和 110;
因此 d(220) = 284. 284的真因子是1, 2, 4, 71 和142; 所以d(284) = 220.
计算10000以下所有亲和数之和。
def get_divisors(x):
"""
求x所有真因子
若x = x1 * x2,则x所有真因子 = (x1所有真因子 + x1) 和 (x2所有真因子 + x2) 交叉乘积集合
"""
x_s = {1}
x_sqrt = int(pow(x, 0.5))
for x1 in range(2, x_sqrt + 1):
if x % x1 == 0:
x1_s = divisors_dict[x1].copy()
x1_s.add(x1)
x2 = x // x1
x2_s = divisors_dict[x2].copy()
x2_s.add(x2)
for i1 in x1_s:
for i2 in x2_s:
x_s.add(i1 * i2)
x_s.remove(x)
break
return x_s
n = 10000
divisors_dict = dict()
for i in range(2, n):
if i not in divisors_dict:
divisors_dict[i] = get_divisors(i)
amicable_set = set()
for (k, v) in divisors_dict.items():
if k in amicable_set:
continue
v_sum = sum(v)
if v_sum == 1 or k == v_sum or v_sum >= n:
continue
if sum(divisors_dict[v_sum]) == k:
# 真因子,一对写入
amicable_set.add(k)
amicable_set.add(v_sum)
print(sum(amicable_set))