Problem 45: Triangular, pentagonal, and hexagonal

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

TriangleTn=n(n+1)/21, 3, 6, 10, 15, …
PentagonalPn=n(3n−1)/21, 5, 12, 22, 35, …
HexagonalHn=n(2n−1)1, 6, 15, 28, 45, …

It can be verified that T285 = P165 = H143 = 40755.

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

Here is my solution in Golang!

package main 

import (
	"fmt"
	"sync"
)

func main() {
	var triList, pentList, hexList []uint64
	nMax := 5000
	nSeed := nMax
	// Start at n = 285, since that is the lower bounds for the question
	nStart := 286
	listGen(nMax, 0, &triList, &pentList, &hexList)
	for !triCheck(nStart, nMax, triList, pentList, hexList) {
		// Start at what was previously the max
		nStart = nMax
		// Increase the max value to calculate for n
		nMax += 1000
		listGen(nMax, nSeed, &triList, &pentList, &hexList)
		// Preserve nMax for next loop to know where to start calculating to append to lists
		nSeed = nMax
	}
}

func triGen(nMax int, nSeed int, triList *[]uint64) {
	triCalc := func(i uint64) uint64 {
		return ((i * (i + 1)) / 2)
	}	

	for i := uint64(nSeed); i < uint64(nMax); i++ {
		*triList = append(*triList, triCalc(i) )
	}

	return
}

func pentGen(nMax int, nSeed int, pentList *[]uint64) {
	pentCalc := func(i uint64) uint64 {
		return ((i * ((3 * i) - 1)) / 2)
	}

	for i := uint64(nSeed); i < uint64(nMax); i++ {
		*pentList = append(*pentList, pentCalc(i))
	}

	return
}

func hexGen(nMax int, nSeed int, hexList *[]uint64) {
	hexCalc := func(i uint64) uint64 {
		return (i * ((2 * i) - 1))
	}
	
	for i := uint64(nSeed); i < uint64(nMax); i++ {
		*hexList = append(*hexList, hexCalc(i))
	}
	
return
}

func listGen(nMax int, nSeed int, triList *[]uint64, pentList *[]uint64, hexList *[]uint64) {
	var wg sync.WaitGroup
	wg.Add(3)

	// Spawn routines to calculate next sets of numbers
	go func(){
		defer wg.Done()
		triGen(nMax, nSeed, triList)
	}()

	go func(){
		defer wg.Done()
		pentGen(nMax, nSeed, pentList)
	}()	

	go func(){
		defer wg.Done()
		hexGen(nMax, nSeed, hexList)
	}()

	wg.Wait()
}	

func triCheck(nStart int, nMax int, triList []uint64, pentList []uint64, hexList []uint64) bool {
	for i := nStart; i < nMax; i++ {
		for j := 0; j < nMax; j++ {
			// If the pentagonal number is greater than the triangle, I know to increment the triangle!
			if pentList[j] > triList[i] {
				break
			}
			// Else if they are equal, I know to start checking for a hexList match
			if pentList[j] == triList[i] {
				for k := 0; k < nMax; k++ {
					// If the hexList value is now greater than the pentList value, I know to increment pentList, which will in turn increment triList
					if hexList[k] > pentList[j] {
						break
					} else {
						if hexList[k] == pentList[j] && pentList[j] == triList[i] {
							fmt.Printf("The next triangle number that is also pentagonal and hexagonal is %v\n ", triList[i])
							fmt.Printf("T%v = %v, P%v = %v, H%v = %v", i, triList[i], j, pentList[j], k, hexList[k])
							return true
						}
					}
				}
			}
		}
	}
	return false
}

Leave a Reply

Your email address will not be published. Required fields are marked *