The sequence of triangle numbers is generated by adding the natural numbers. So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. The first ten terms would be:
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
Let us list the factors of the first seven triangle numbers:
1: 1
3: 1,3
6: 1,2,3,6
10: 1,2,5,10
15: 1,3,5,15
21: 1,3,7,21
28: 1,2,4,7,14,28
We can see that 28 is the first triangle number to have over five divisors.
What is the value of the first triangle number to have over five hundred divisors?
In [1]:
from __future__ import print_function
from euler import gen_triangular
from euler import gen_lt
from euler import get_factors
from euler import product
from euler import gen_n
from collections import defaultdict
from collections import Counter
from itertools import count
In [2]:
# modest hardware for 2015
!lscpu
In [3]:
list(gen_lt(gen_triangular(), 100))
Out[3]:
In [4]:
list(get_factors(1)), list(get_factors(72))
Out[4]:
In [5]:
def tabulate(x):
'''Returns dictionary for given collection x where
keys are for collection elements
values are count of how many times
the key occurs in the given collection.'''
f = {}
for i in x:
if i not in f:
f[i] = 0
f[i] += 1
return f
In [6]:
tabulate(get_factors(24)), len(tabulate(get_factors(24)))
Out[6]:
In [7]:
def foo(n):
for t in gen_triangular():
if product(map((lambda x: x+1), tabulate(get_factors(t)).values())) > n:
return t
In [8]:
n = 500
%timeit foo(n)
foo(n)
Out[8]:
In [9]:
def tabulate(x):
'''Returns dictionary for given collection x where
keys are for collection elements
values are count of how many times
the key occurs in the given collection.'''
counts = defaultdict(int)
for i in x:
counts[i] += 1
return counts
In [10]:
n = 500
%timeit foo(n)
foo(n)
Out[10]:
In [11]:
def foo(n):
for t in gen_triangular():
if product(map((lambda x: x+1), Counter(get_factors(t)).values())) > n:
return t
In [12]:
n = 500
%timeit foo(n)
foo(n)
Out[12]:
In [13]:
def gen_triangular_main_factors():
for i in count(1, 2):
yield i, (i+1) / 2
yield (i+1) / 2, i+2
In [14]:
for i in gen_n(gen_triangular_main_factors(), 10):
print(i, product(i))
In [15]:
def tabulate(x):
'''Returns dictionary for given collection of collection x where
keys are for collection elements
values are count of how many times
the key occurs in the given collection.'''
f = {}
for y in x:
for i in y:
if i not in f:
f[i] = 0
f[i] += 1
return f
In [16]:
def foo(n):
for t in gen_triangular_main_factors():
factors = tabulate(map(get_factors, t))
if product(map((lambda x: x+1), factors.values())) > n:
return product(t)
In [17]:
n = 500
%timeit foo(n)
foo(n)
Out[17]: