Question
Triangle, pentagonal, and hexagonal numbers are generated by the following formulae:
\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.
Haskell
import qualified Data.Set as Set
triangles :: [Int]
= [(n*(n + 1)) `quot` 2 | n <- [1..]]
triangles
pentagonals :: [Int]
= [(n*(3*n - 1)) `quot` 2 | n <- [1..100000]]
pentagonals
hexagonals :: [Int]
= [n*(2*n - 1) | n <- [1..100000]]
hexagonals
candidates :: [Int]
= dropWhile (<= 40755) [t | t <- triangles, isPentagonal t, isHexagonal t]
candidates where isPentagonal = (`Set.member` Set.fromList pentagonals)
= (`Set.member` Set.fromList hexagonals)
isHexagonal
main :: IO ()
= print $ head candidates main
$ ghc -O2 -o tri-pen-hex tri-pen-hex.hs
$ time ./tri-pen-hex
real 0m0.036s
user 0m0.036s
sys 0m0.000s
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():
= set(pentagonal(n) for n in range(100000))
p = set(hexagonal(n) for n in range(100000))
h for n in range(100000):
= triangle(n)
t 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.123s
user 0m0.123s
sys 0m0.000s
Ruby
#!/usr/bin/env ruby
require 'set'
p = (1..100000).map { |n| n*(3*n-1)/2 }.to_set
= (1..100000).map { |n| n*(2*n-1) }.to_set
h 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.110s
user 0m0.102s
sys 0m0.008s