Find the smallest number with 2 500500 2^{500500} 2 5 0 0 5 0 0 divisors. Give your answer modulo 500500507 500500507 5 0 0 5 0 0 5 0 7 .

Here's code I wrote to generate Highly Composite Numbers that have divisors that have a power of two. Not the most elegant code, but gets the job done

github

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 # https://projecteuler.net/problem=500 # Find the smallest number with 2^500500 divisors. # Give your answer modulo 500500507. import primes # Function I made to iterate through primes import heapq as heap import sys h = [] divisors = [ 2 , 3 ] limit = 500500 - 1 divs = 2 def addDivisor ( divisor ): global divs if divs > limit : # print divisors print reduce ( lambda x , y : x * y % 500500507 , divisors ) % 500500507 sys . exit ( 0 ) divisors . append ( divisor ) divs = divs + 1 def main (): # heap[0] = Actual number # heap[1] = Base number # heap[2] = Exponent heap . heappush ( h , ( 4 , 2 , 2 )) heap . heappush ( h , ( 9 , 3 , 2 )) for prime in primes . primeGen (): # Select candidate from bottom of heap div = h [ 0 ] while div [ 0 ] < prime : div = heap . heappop ( h ) addDivisor ( div [ 0 ]) newExponent = div [ 2 ] * 2 heap . heappush ( h , ( div [ 1 ] ** ( newExponent ), div [ 1 ], newExponent )) div = h [ 0 ] addDivisor ( prime ) heap . heappush ( h , ( prime ** 2 , prime , 2 )) if __name__ == "__main__" : main ()

Explanation

Highly composite numbers are numbers that have more divisors than the numbers below them. With some bit of number theory, it is particularly easy to construct HCNs with divisors of powers of two. This is because

A number n = p a q b r c . . . n = p^{a}q^{b}r^{c} ... n=paqbrc... has ( a + 1 ) ( b + 1 ) ( c + 1 ) . . . (a+1)(b+1)(c+1)... (a+1)(b+1)(c+1)... divisors

500 = 5 3 2 2 500 = 5^{3}2^{2} 500=5322, therefore it must have ( 3 + 1 ) ( 2 + 1 ) (3+1)(2+1) (3+1)(2+1) = 12 divisors 1, 2, 4, 5, 10, 20, 25, 50, 100, 125, 250, 500 (12 divisors)

Sample run

1 2 3 4 5 6 7 8 9 10 11 [2, 3, 4] = 24 has 2^3 divisors [2, 3, 4, 5] = 120 has 2^4 divisors [2, 3, 4, 5, 7] = 840 has 2^5 divisors [2, 3, 4, 5, 7, 9] = 7560 has 2^6 divisors [2, 3, 4, 5, 7, 9, 11] = 83160 has 2^7 divisors [2, 3, 4, 5, 7, 9, 11, 13] = 1081080 has 2^8 divisors [2, 3, 4, 5, 7, 9, 11, 13, 16] = 17297280 has 2^9 divisors [2, 3, 4, 5, 7, 9, 11, 13, 16, 17] = 294053760 has 2^10 divisors [2, 3, 4, 5, 7, 9, 11, 13, 16, 17, 19] = 5587021440 has 2^11 divisors [2, 3, 4, 5, 7, 9, 11, 13, 16, 17, 19, 23] = 128501493120 has 2^12 divisors [2, 3, 4, 5, 7, 9, 11, 13, 16, 17, 19, 23, 25] = 3212537328000 has 2^13 divisors

I will now go through how my program "thinks"

It starts with 2 2 2 primes: 2 2 2 and 3 3 3 It selects the next candidate, which is the next prime. In this step, 5 5 5 It checks if 2 2 2^{2} 22 and 3 2 3^{2} 32 are less than the candidate. We can see that 4 4 4 is less than 5 5 5, so we put it in the list of divisors We add 2 4 2^{4} 24 to the heap (to be clear, the heap is a different thing from the divisor list). What this will achieve, if you add this number to the heap, is that the number of divisors will remain a power of two. I construct this by making the exponent of two in our list is one less a power of two. 1 + 2 + 4 = 2 3 − 1 1 + 2 + 4 = 2^{3} - 1 1+2+4=23−1 We can see that our candidate prime, 5 5 5, is larger than everything in the heap, so we put it in the divisor list We put 5 2 5^{2} 52 to the heap Our next candidate is 7 7 7 It checks if there's a number less than 7 7 7 in our heap. There isn't, so we add 7 2 7^{2} 72 to the heap and checks the next prime candidate, 11. So on.

my question