Highly Divisible Triangular Number
The n -th triangular number is T_n = (n(n+1))/(2). Find the smallest T_n with tau(T_n) > 500, where tau(m) denotes the number of positive divisors of m.
Problem Statement
This archive keeps the full statement, math, and original media on the page.
The sequence of triangle numbers is generated by adding the natural numbers. So the $7^{th}$ 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, \dots$$ Let us list the factors of the first seven triangle numbers: \begin{align*} \mathbf 1 &\colon 1\\ \mathbf 3 &\colon 1,3\\ \mathbf 6 &\colon 1,2,3,6\\ \mathbf{10} &\colon 1,2,5,10\\ \mathbf{15} &\colon 1,3,5,15\\ \mathbf{21} &\colon 1,3,7,21\\ \mathbf{28} &\colon 1,2,4,7,14,28 \end{align*} We can see that $28$ is the first triangle number to have over five divisors.
What is the value of the first triangle number to have over five hundred divisors?
Problem 12: Highly Divisible Triangular Number
Mathematical Development
Definitions and Notation
Definition 1. For with prime factorization , the divisor function is .
Definition 2. The -th triangular number is .
Theorems
Theorem 1 (Divisor count formula). If , then .
Proof. A positive divisor of has the form where . Each exponent admits independent choices, yielding divisors in total.
Theorem 2 (Multiplicativity of ). The function is multiplicative: if , then .
Proof. Write and . Since , the sets and are disjoint. Hence is in canonical form, and
Lemma 1 (Coprimality of consecutive integers). For all , .
Proof. If and , then , so .
Theorem 3 (Coprime factorization of ). For all :
Proof. We have . Exactly one of is even. Write the factorization as where the factor of is absorbed into the even term:
- If : set , .
- If : set , .
We must verify in each case. Consider the case . Every prime dividing also divides . By Lemma 1, , so . Hence . The odd case is symmetric. Applying Theorem 2 yields the result.
Remark. This decomposition is the key algorithmic insight: instead of factoring (which can be as large as ), we factor two numbers of size and separately, reducing the trial division cost.
Editorial
We test triangle numbers in increasing order and compute their divisor counts from prime factorizations. For each index , we use together with the coprimality of and to evaluate as or , where the helper factors its input by trial division. The first triangle number whose divisor count exceeds the target is therefore the desired answer.
Pseudocode
Algorithm: First Triangle Number with More Than M Divisors
Require: A divisor threshold M.
Ensure: The least triangle number T_n with tau(T_n) > M.
1: Initialize n ← 1.
2: Repeat:
3: Factor the coprime pair n and n + 1, divide one factor by 2, and combine the resulting exponents to obtain tau(T_n).
4: If tau(T_n) > M, return T_n ← n(n + 1) / 2; otherwise set n ← n + 1.
Complexity Analysis
Proposition. The algorithm terminates in time and auxiliary space, where is the index satisfying .
Proof. For each from to , we compute of two numbers, each at most . Trial division of an integer requires divisions. Hence the cost per iteration is , and the total cost is
No auxiliary data structure is needed beyond variables.
Verification. At : , giving .
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <bits/stdc++.h>
using namespace std;
int countDivisors(long long n) {
int count = 1;
for (long long d = 2; d * d <= n; d++) {
int e = 0;
while (n % d == 0) { n /= d; e++; }
count *= (e + 1);
}
if (n > 1) count *= 2;
return count;
}
int main() {
for (long long n = 1; ; n++) {
long long a = (n % 2 == 0) ? n / 2 : n;
long long b = (n % 2 == 0) ? n + 1 : (n + 1) / 2;
if (countDivisors(a) * countDivisors(b) > 500) {
cout << a * b << endl;
return 0;
}
}
}
"""Project Euler Problem 12: Highly Divisible Triangular Number"""
def count_divisors(n):
if n == 0:
return 0
count = 1
d = 2
while d * d <= n:
e = 0
while n % d == 0:
n //= d
e += 1
count *= e + 1
d += 1
if n > 1:
count *= 2
return count
n = 1
while True:
if n % 2 == 0:
d = count_divisors(n // 2) * count_divisors(n + 1)
else:
d = count_divisors(n) * count_divisors((n + 1) // 2)
if d > 500:
print(n * (n + 1) // 2)
break
n += 1