def all_triples(p, factors_hash=None): if factors_hash is None: factors_hash = {} if p % 2 == 1 or p < 2 or not isinstance(p, int): return [] if p / 2 in factors_hash: choices_k = factors_hash[p / 2] else: choices_k = all_factors(p / 2, factors_hash)[p / 2] result = [] for k in choices_k: if p / (2 * k) in factors_hash: choices_m = factors_hash[p / (2 * k)] else: choices_m = all_factors(p / (2 * k), factors_hash)[p / (2 * k)] # 2*k*m*(m + n) = p for m in choices_m: n = p / (2 * k * m) - m if n > 0 and m > n: result.append((k, m, n)) return result
def main(verbose=False): n = 10000 factors = all_factors(n - 1) # sum of proper divisors first_pass = [sum(factors[i]) - i for i in range(1, n)] max_out = max(first_pass) factors = all_factors(max_out, factors) # applying sum of divisors twice to i we have # s_1 = func(i), s_2 = func(s_1) # s_1 = sum(factors[i]) - i, s_2 = sum(factors[s_1]) - s_1 # i == s_2 <==> # i == sum(factors[sum(factors[i]) - i]) - (sum(factors[i]) - i) <==> # sum(factors[sum(factors[i]) - i]) == sum(factors[i]) # Similarly s_1 != i <==> sum(factors[i]) != 2*i result = [i for i in range(2, n) if sum(factors[sum(factors[i]) - i]) == sum(factors[i]) and sum(factors[i]) != 2 * i] if verbose: return '%s.\nThe full list of such amicable numbers is %s.' % ( sum(result), ', '.join(str(elt) for elt in result)) else: return sum(result)
def nontrivial_factorizations(n): factor_hash = {1: [1]} factor_hash = all_factors(n, factor_hash) result = {1: [[]], 2: [[2]]} value_hash = {} for i in range(3, n + 1): to_add = [[i]] for factor in factor_hash[i]: if factor > 1 and factor**2 <= i: for subset1 in result[factor]: for subset2 in result[i/factor]: cand = sorted(subset1 + subset2) if cand not in to_add: to_add.append(cand) for match in to_add: new_k = i + len(match) - sum(match) if new_k > 1 and new_k not in value_hash: value_hash[new_k] = i result[i] = to_add return result, value_hash
def all_triangles_up_to_n(n): factors_hash = all_factors(n) result = {} for p in range(2, n + 1, 2): result[p] = all_triangles(p, factors_hash) return result
def abundant_numbers(n): factor_hash = all_factors(n) # sum of proper divisors return [i for i in range(2, n + 1) if i < sum(factor_hash[i]) - i]