Primitive Triangles
Consider the triangles with integer sides a, b and c with a <= b <= c. An integer sided triangle (a, b, c) is called primitive if gcd(a, b, c) = 1. How many primitive triangles exist with a perimet...
Problem Statement
This archive keeps the full statement, math, and original media on the page.
Consider the triangles with integer sides \(a\), \(b\) and \(c\) with \(a \le b \le c\).
An integer sided triangle \((a,b,c)\) is called primitive if \(\underline {\gcd (a, b, c)} = 1\)
How many primitive integer sided triangles exist with a perimeter not exceeding \(10\,000\,000\)?
Problem 276: Primitive Triangles
Mathematical Analysis
Counting Triangles with Exact Perimeter
The number of triangles with , , and is given by the Alcuin sequence (OEIS A005044).
The generating function is:
This yields the linear recurrence for :
with initial values: .
Deriving the Recurrence
The denominator of the GF factors as:
Since , we get:
Asymptotic Behavior
From the partial fraction decomposition, the dominant term at (a third-order pole) gives:
Therefore .
Mobius Sieve for Primitive Triangles
Every triangle with and perimeter corresponds to a primitive triangle with perimeter . Thus:
By Mobius inversion:
This is implemented as a sieve: initialize , then for each from to , subtract from for
Final Answer
Editorial
We compute for all from 3 to using the linear recurrence: . We then apply the Mobius sieve: (harmonic series). Finally, sum the primitive counts: .
Pseudocode
Compute $t(s)$ for all $s$ from 3 to $N$ using the linear recurrence: $O(N)$
Apply the Mobius sieve: $O(N \log N)$ (harmonic series)
Sum the primitive counts: $O(N)$
Correctness
Theorem. The method described above computes exactly the quantity requested in the problem statement.
Proof. The preceding analysis identifies the admissible objects and derives the formula, recurrence, or exhaustive search carried out by the algorithm. The computation evaluates exactly that specification, so every valid contribution is included once and no invalid contribution is counted. Therefore the returned value is the required answer.
Complexity
Time: where .
Space: for the array.
Verification
- (verified by brute force)
- (verified by brute force)
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <bits/stdc++.h>
using namespace std;
/*
* Problem 276: Primitive Triangles
*
* Count primitive triangles (gcd(a,b,c)=1) with a<=b<=c and perimeter <= N=10^7.
*
* Method:
* 1. Compute t(s) for all s using the recurrence from the generating function
* G(x) = x^3 / ((1-x^2)(1-x^3)(1-x^4)), which gives:
* t(n) = t(n-2)+t(n-3)+t(n-4)-t(n-5)-t(n-6)-t(n-7)+t(n-9) for n >= 12
*
* 2. Apply Mobius sieve: for n from 1 to N/2, subtract t[n] from t[kn] for k>=2.
* After sieving, t[n] = number of PRIMITIVE triangles with perimeter exactly n.
*
* 3. Sum all t[n] for n = 3..N.
*/
int main(){
const int N = 10000000;
// Step 1: Compute triangle counts using recurrence
vector<long long> t(N + 1, 0);
// Initial values (OEIS A005044):
t[3] = 1; t[5] = 1; t[6] = 1; t[7] = 2; t[8] = 1; t[9] = 3; t[10] = 2; t[11] = 4;
for (int n = 12; n <= N; n++) {
t[n] = t[n-2] + t[n-3] + t[n-4] - t[n-5] - t[n-6] - t[n-7] + t[n-9];
}
// Step 2: Mobius sieve to extract primitive counts
for (long long n = 1; n <= N / 2; n++) {
if (t[n] == 0) continue;
for (long long k = 2 * n; k <= N; k += n) {
t[k] -= t[n];
}
}
// Step 3: Sum primitive counts
long long answer = 0;
for (int n = 3; n <= N; n++) {
answer += t[n];
}
cout << answer << endl;
return 0;
}
#!/usr/bin/env python3
"""
Problem 276: Primitive Triangles
Count primitive triangles (gcd(a,b,c)=1) with a<=b<=c and perimeter <= 10^7.
Method:
1. Compute t(s) for all s using the linear recurrence from the GF
G(x) = x^3 / ((1-x^2)(1-x^3)(1-x^4)):
t(n) = t(n-2)+t(n-3)+t(n-4)-t(n-5)-t(n-6)-t(n-7)+t(n-9) for n >= 12
2. Apply Mobius sieve: for n from 1 to N/2, subtract t[n] from t[kn] for k>=2.
3. Sum primitive counts.
"""
def solve(N=10**7):
# Step 1: Compute triangle counts using recurrence
t = [0] * (N + 1)
# Initial values (OEIS A005044)
if N >= 3: t[3] = 1
if N >= 5: t[5] = 1
if N >= 6: t[6] = 1
if N >= 7: t[7] = 2
if N >= 8: t[8] = 1
if N >= 9: t[9] = 3
if N >= 10: t[10] = 2
if N >= 11: t[11] = 4
for n in range(12, N + 1):
t[n] = t[n-2] + t[n-3] + t[n-4] - t[n-5] - t[n-6] - t[n-7] + t[n-9]
# Step 2: Mobius sieve
for n in range(1, N // 2 + 1):
if t[n] == 0:
continue
for k in range(2 * n, N + 1, n):
t[k] -= t[n]
# Step 3: Sum
answer = sum(t[n] for n in range(3, N + 1))
return answer
if __name__ == "__main__":
N = 10**7
answer = solve(N)
print(answer)