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]
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.036s
user 0m0.036s
sys 0m0.000sPython
#!/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.123s
user 0m0.123s
sys 0m0.000sRuby
#!/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.110s
user 0m0.102s
sys 0m0.008s