Euler 0024
The Problem:
A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. A number is called deficient if the sum of its proper divisors is less than and it is called abundant if this sum exceeds.
As 12What is the smallestmillionth abundantlexicographic number,permutation of the smallestdigits number0, that1, can2, be3, written4, as5, the6, sum7, of8 twoand 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.9?
Considerations and Approach:
BasedWell, offthis ofis theanother question we knowproblem that wePython onlyhas havea tosimple gobuilt upin toway...
Generating all of the numbers that are sumspermutations of twothe abundantnumbers numbers.0-9 Thenis not computationally an issue for itertools, we subtractcan thatthen fromsort 28123those permutations and voila.grab out the millionth permutation and that's our answer.
The Code:
import mathitertools
def#Sorry generate_primes(upper):that prime_thresholdthe =next upperfew number_listlines =don't look pythonic, I adjusted them for comment clarity sake
#The line should actually just read sorted(itertools.permutations(list(range(10))))[999999]
#We sort
sorted(
#all the permutations
itertools.permutations(
#of the numbers 0-9
list(range(2, prime_threshold+1)10))
prime_list = []
current = 0
total_iteration = 0
while current < len(number_list):
if number_list[current] != -1:
prime = number_list[current]
prime_list += [prime]
increment = current + prime
while increment < len(number_list):
number_list[increment] = -1
increment += prime
total_iteration += 1
#print(number_list)
#print(prime_list)
current += 1
return prime_list
def divisor_finder(number, primes):
upper_limit = number
#upper_limit = 20023110541 #, good to use to double check. Is [2,2,3,167]
current_upper_limit = upper_limit
sqrt_limit = math.sqrt(upper_limit)
prime_factors = []
#we are going to hardcode 2 and 3 for looping sake
i = 0
while primes[i] < sqrt_limit and i < len(primes):
while current_upper_limit % primes[i] == 0:
current_upper_limit = current_upper_limit/primes[i]
prime_factors += [primes[i]]
i += 1
if current_upper_limit != 1:
prime_factors += [current_upper_limit]
#print(prime_factors)
prime_counts = [[prime_factors[0], prime_factors.count(prime_factors[0])]]
#print(prime_counts,prime_counts[-1][0],prime_factors[1])
for#and ithen inwe range(1,len(prime_factors)grab out the millionth permutation
):
#print(prime_counts[-1][0],prime_factors[i])
if prime_counts[-1][0] != prime_factors[i]:
prime_counts += [[prime_factors[i], prime_factors.count(prime_factors[i])]]
#print(prime_counts)
divisors = [1]
counters = [x[1] for x in prime_counts]
#print(counters)
while sum(counters) > 0:
new_divisor = 1
for i in range(len(counters)):
#print(prime_counts[i][0],counters[i], new_divisor)
new_divisor *= prime_counts[i][0]**counters[i]
divisors += [new_divisor]
counters[0] -= 1
for i in range(len(counters)):
if counters[i] == -1:
counters[i] = prime_counts[i][1]
if i != len(counters) - 1:
counters[i+1] -= 1
else:
break
divisors.sort()
return divisors[:-1]
upper_limit = 28124
prime_list = generate_primes(upper_limit)
abundant_nums = []
for i in range(12, upper_limit-12):
divisors = divisor_finder(i, prime_list)
if sum(divisors) > i:
#print(i,sum(divisors), divisors)
abundant_nums += [i]
print(abundant_nums)
abundant_sum_nums = []
for num1 in abundant_nums:
for num2 in abundant_nums:
number = num1 + num2
if number < upper_limit:
abundant_sum_nums += [number]
else:
break
print(len(abundant_nums))
remove = set(abundant_sum_nums)
keep = [x for x in range(1,upper_limit)]
for number in remove:
keep.remove(number)
print(len(keep))
999999]