# Project Euler Problem 45: Triangular, pentagonal, and hexagonal

Triangle, pentagonal, and hexagonal numbers are generated by the following formulae:

Triangle

$$T_n = \frac{n(n+1)}{2} \\ 1, 3, 6, 10, 15, \dotsc$$

Pentagonal

$$P_n = \frac{n(3n−1)}{2} \\ 1, 5, 12, 22, 35, \dotsc$$

Hexagonal

$$H_n = n(2n−1) \\ 1, 6, 15, 28, 45, \dotsc$$

It can be verified that $T_{285} = P_{165} = H_{143} = 40755$.

Find the next triangle number that is also pentagonal and hexagonal.

#### Version 1: Brute force¶

In :
from six.moves import map, range
from itertools import islice

In :
def argmin(iterable):
argmin_ = 0
for i, n in enumerate(iterable):
if n < iterable[argmin_]:
argmin_ = i
return argmin_

In :
from random import randint

In :
a = [randint(1, 100) for _ in range(15)]; a

Out:
[78, 25, 88, 84, 50, 62, 83, 30, 80, 90, 38, 52, 26, 43, 82]
In :
argmin(a)

Out:
1
In :
def polygonal(s):
c = s - 2
a = b = 1
while True:
yield a
b += c
a += b

In :
list(islice(polygonal(2), 10))

Out:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
In :
list(islice(polygonal(3), 10))

Out:
[1, 3, 6, 10, 15, 21, 28, 36, 45, 55]
In :
list(islice(polygonal(4), 10))

Out:
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
In :
s = [3, 5, 6]

In :
polygonal_iters = list(map(polygonal, s))

In :
list(islice(polygonal(7), 10))

Out:
[1, 7, 18, 34, 55, 81, 112, 148, 189, 235]
In :
polygonal_iters = list(map(polygonal, s))

In :
values = list(map(next, polygonal_iters))

In :
next(polygonal_iters[argmin(values)])

Out:
3
In :
all_equals = lambda lst: lst[1:] == lst[:-1]

In :
def polygonal_combinations(s_lst):
iters = list(map(polygonal, s_lst))
values = list(map(next, iters))
while True:
if all_equals(values):
yield values
amin = argmin(values)
values[amin] = next(iters[amin])

In :
list(islice(polygonal_combinations([3, 5, 6]), 4))

Out:
[1, 40755, 1533776805, 57722156241751]
In :
it = polygonal_combinations([3, 4, 6, 29, 60, 124])

In :
next(it)

Out:
1
In :
next(it)

Out:
1225

The number 1225 is hecticositetragonal ($s=124$), hexacontagonal ($s=60$), icosienneagonal ($s=29$), hexagonal, square, and triangular.

In :
from operator import itemgetter

In :
def polygonal_combinations(s_lst):
values = [1 for _ in s_lst]
increm = [1 for _ in s_lst]
while True:
if all_equals(values):
yield values
amin = argmin(values)
increm[amin] += s_lst[amin] - 2
values[amin] += increm[amin]

In :
it = polygonal_combinations([3, 5, 6])

In :
next(it)

Out:
1
In :
next(it)

Out:
40755
In :
next(it)

Out:
1533776805