## Question

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

\displaystyle \begin{aligned} \text{Triangle} & T_n=\frac{n(n+1)}{2} & 1, 3, 6, 10, 15, ... \\ \text{Pentagonal} & P_n=\frac{n(3n-1)}{2} & 1, 5, 12, 22, 35, ... \\ \text{Hexagonal} & H_n=n(2n-1) & 1, 6, 15, 28, 45, ... \end{aligned}

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

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

import qualified Data.Set as Set

triangles :: [Int]
triangles = [(n*(n + 1)) quot 2 | n <- [1..]]

pentagonals :: [Int]
pentagonals = [(n*(3*n - 1)) quot 2 | n <- [1..100000]]

hexagonals :: [Int]
hexagonals = [n*(2*n - 1) | n <- [1..100000]]

candidates :: [Int]
candidates = dropWhile (<= 40755) [t | t <- triangles, isPentagonal t, isHexagonal t]
where isPentagonal = (Set.member Set.fromList pentagonals)
isHexagonal = (Set.member Set.fromList hexagonals)

main :: IO ()
main = print $head candidates $ ghc -O2 -o tri-pen-hex tri-pen-hex.hs
$time ./tri-pen-hex real 0m0.053s user 0m0.040s sys 0m0.012s ## Python #!/usr/bin/env python def triangle(n): return n*(n+1)//2 def pentagonal(n): return n*(3*n-1)//2 def hexagonal(n): return n*(2*n-1) def main(): p = set(pentagonal(n) for n in range(100000)) h = set(hexagonal(n) for n in range(100000)) for n in range(100000): t = triangle(n) if t in p and t in h and t > 40755: print(t) if __name__ == "__main__": main() $ time python3 tri-pen-hex.py
real   0m0.117s
user   0m0.116s
sys    0m0.000s

## Ruby

#!/usr/bin/env ruby
require 'set'
p = (1..100000).map { |n| n*(3*n-1)/2 }.to_set
h = (1..100000).map { |n| n*(2*n-1) }.to_set
puts (286..100000).map { |n| n*(n+1)/2 }.detect { |t|
p.include?(t) and h.include?(t)
}
\$ time ruby tri-pen-hex.rb
real   0m0.136s
user   0m0.108s
sys    0m0.008s