Right Triangles with Integer Coordinates
Let O=(0,0), P=(x_1,y_1), Q=(x_2,y_2), with all coordinates integers in [0,50]. We ask for the number of right triangles OPQ.
Problem Statement
This archive keeps the full statement, math, and original media on the page.
The points \(P(x_1, y_1)\) and \(Q(x_2, y_2)\) are plotted at integer co-ordinates and are joined to the origin, \(O(0,0)\), to form \(\triangle OPQ\).

There are exactly fourteen triangles containing a right angle that can be formed when each co-ordinate lies between \(0\) and \(2\) inclusive; that is, \(0 \le x_1, y_1, x_2, y_2 \le 2\).

Given that \(0 \le x_1, y_1, x_2, y_2 \le 50\), how many right triangles can be formed?
Problem 91: Right Triangles with Integer Coordinates
Counting Strategy
We count triangles by the location of the right angle.
1. Right angle at the origin
If the right angle is at , then
Because all coordinates are nonnegative, this happens if and only if one point lies on the positive -axis and the other lies on the positive -axis. Hence this case contributes
2. Right angle on one of the axes, but not at the origin
Suppose the right angle is at with . Since is horizontal, orthogonality forces to be vertical, so with . Therefore this contributes another
By symmetry, the same number of triangles have the right angle at a point on the -axis. Thus all axis cases together contribute
3. Right angle at an interior lattice point
Now let the right angle be at an interior point
Write
so that .
We want all lattice points such that . This is equivalent to
that is,
or
Substituting and , we get
Since , divisibility implies that there exists such that
Therefore every lattice point giving a right angle at is of the form
So the primitive step along the line through perpendicular to is
Positive direction
If , then
To stay inside the square , we need
Hence
So the number of valid positive steps is
Negative direction
If , write with . Then
The bounds become
so
Thus the number of valid negative steps is
For a fixed interior point , the number of triangles with right angle at is therefore
Summing over all interior lattice points gives the exact formula
Editorial
The clean way to avoid overcounting is to classify triangles by the position of the right angle. The cases at the origin and on the axes are simple and contribute closed forms immediately, so the only real work is when the right angle sits at an interior lattice point .
For such a point, the segment must lie on the line through perpendicular to . Writing gives the primitive lattice step on that perpendicular line, namely up to sign. Every valid choice of is obtained by moving along this primitive direction until the square boundary is hit. So the search space is constrained to just two one-dimensional walks from each interior point, and the number of admissible steps in each direction is exactly what the formula counts.
Pseudocode
Initialize the total with the three axis-based contributions $3N^2$.
For each interior lattice point $(x,y)$ with $1 \le x,y \le N$:
Compute $g=\gcd(x,y)$
Compute the primitive perpendicular step $(y/g,\;x/g)$
Count how many forward steps keep the point inside the square
Count how many backward steps keep the point inside the square
Add both counts to the running total
Return the running total.
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 Analysis
There are interior lattice points. Each point requires one gcd computation and arithmetic. Therefore:
- Time:
- Space:
For , this is trivial to evaluate.
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <algorithm>
#include <cassert>
#include <iostream>
#include <numeric>
long long count_right_triangles(int n) {
long long total = 3LL * n * n;
for (int x = 1; x <= n; ++x) {
for (int y = 1; y <= n; ++y) {
const int g = std::gcd(x, y);
const int step_x = y / g;
const int step_y = x / g;
total += std::min((n - x) / step_x, y / step_y);
total += std::min(x / step_x, (n - y) / step_y);
}
}
return total;
}
int main() {
const long long answer = count_right_triangles(50);
assert(answer == 14234);
std::cout << answer << '\n';
return 0;
}
"""
Problem 91: Right Triangles with Integer Coordinates
Count right triangles with vertices O=(0,0), P, Q on the integer grid
[0,N] x [0,N] by counting how many lattice points lie on the line through
each possible right-angle vertex and perpendicular to OP.
"""
from math import gcd
def count_right_triangles(n):
total = 3 * n * n
for x in range(1, n + 1):
for y in range(1, n + 1):
g = gcd(x, y)
step_x = y // g
step_y = x // g
total += min((n - x) // step_x, y // step_y)
total += min(x // step_x, (n - y) // step_y)
return total
def solve():
return count_right_triangles(50)
if __name__ == "__main__":
answer = solve()
assert answer == 14234
print(answer)