Highly Divisible Triangular Number
The sequence of triangle numbers is generated by adding the natural numbers. So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. The first ten terms would be:
What is the value of the first triangle number to have over five hundred divisors?
I broke this problem down into mini-problems. All of which were related to one primary concern: A triangular number with 500 factors is probably really really big. Those mini-problems are as follows:The sequence of triangle numbers is generated by adding the natural numbers. So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. The first ten terms would be:
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
Let us list the factors of the first seven triangle numbers:1: 1We can see that 28 is the first triangle number to have over five divisors.
3: 1,3
6: 1,2,3,6
10: 1,2,5,10
15: 1,3,5,15
21: 1,3,7,21
28: 1,2,4,7,14,28
What is the value of the first triangle number to have over five hundred divisors?
- How do I convert $n$ to its corresponding triangular number without having to sum up all the preceding numbers in the series?
- How do I calculate the number of factors of $n$ without actually having to figure out what each of those factors are?
- Is there any way to run my functions on $n$ instead of its corresponding triangular number?
1. Converting $n$ to it's corresponding triangular number.
function tri(num) {
return (num * (num + 1)) / 2;
}
2. Counting the factors of $n$.
function factorCount(num) {
let count = 1;
for (let prime of primes) { // See note A.
if ((prime * prime) > num) { // See note B.
count *= 2; // See note C.
break;
}
let exponent = 0; // See note D.
while (num % prime == 0) { // See note E.
exponent++;
num /= prime;
}
if (exponent > 0) { // See note F.
count *= exponent + 1; // See note G.
}
if (num == 1) { // See note H.
break;
}
}
return count; // See note I.
}
Notes on the above algorithm.
- I needed a list of prime numbers to implement this algorithm. In this example, the global constant
primesrepresents an array of prime numbers in ascending order, starting at 2, and ending at 104743. - First, we need to establish an exit condition so that we won't need to iterate over the entire list of primes. Since we only need to search from $1 \longrightarrow \sqrt{n}$ to find factors of $n$, the very first prime whose square is greater than $n$ tells us that we no longer need to evaluate any primes at that point or beyond.
- We double the count since every factor of $n$ has a co-factor after $\sqrt{n}$.
- We must now determine the exponent of the prime we are evaluating. We start our exponent counter at 0.
- So long as $n$ is divisible by our prime, we can increment our counter while dividing out the prime. To help visualize this: Imagine that $n=8$ and we are evaluating the prime $p=2$. To get our exponent, we progressively divide $n/p$ while also increasing our exponent counter by 1 each time the division occurs. At the end of this process, our exponent counter will equal 3. This makes sense because $8 = 2\times 2\times 2 = 2^3$
- Before we proceed, we need to check if the counter moved at all. This tells us whether $n$ was divisible by the prime. If it wasn't divisible, we cannot apply the method.
- Now that we have determined the exponent. We can finally apply the method!
- Lastly, we need to break out of the loop if $n=1$. Think back to the $n=8$, $p=2$ example (from note E). When all of the $p$'s are divided out of $n$, $n=1$. At that point, there is no sense trying to evaluate the next prime.
- Since the variable
countnow equals the number of factors of $n$, we can return it.
3. Working with $n$ instead of $T(n)$.
Since $T(n)$ is many, many times larger than $n$, we can speed up our calculation dramatically if we could just work with $n$. The strategy is to use $T(n) = \dfrac {n\times (n+1)}{2}$ to find $D(T(n))$ in terms of $n$. If we do the math, then: $$D(T(n)) = D\left (\dfrac {n\times (n+1)}{2}\right )=$$$$D\left (\dfrac {n}{2}\right )\times D(n+1)\implies \text{if }n\text{ is even}$$$$D(n)\times D\left (\dfrac {n+1}{2}\right )\implies \text{if }n\text{ is odd}$$If we use our
factorCount function above to represent the $D(n)$ the resulting code can take any integer and spit out the number of factors of it's corresponding triangular number. The code is as follows:function triFactorCount(num) {
let term1, term2;
if (num % 2 == 0) {
term1 = factorCount(num / 2);
term2 = factorCount(num + 1);
} else {
term1 = factorCount(num);
term2 = factorCount((num + 1) / 2);
}
return term1 * term2;
}
Putting it all together!
tri and triFactorCount functions as they've been defined above.let num = 1;
while (triFactorCount(num) < 500) {
num++;
}
console.log(tri(num));