Tim Varley Logo
Tim Varley Principal AI Engineer and Tech Leader
Problem #91 medium

Right triangles with integer coordinates

The points P(x1,y1)P(x_1, y_1) and Q(x2,y2)Q(x_2, y_2) are plotted at integer co-ordinates and are joined to the origin, O(0,0)O(0,0), to form OPQ\triangle OPQ.

Right triangle coordinate example 1

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

Right triangle coordinate example 2

Given that 0x1,y1,x2,y2500 \le x_1, y_1, x_2, y_2 \le 50, how many right triangles can be formed?

View on Project Euler

Implementations

cpp
#include <iostream>
unsigned int gcd(unsigned int a, unsigned int b) {
while (a != 0) {
unsigned int c = a;
a = b % a;
b = c;
}
return b;
}
long long right_triangles() {
const unsigned int size = 50;
long long result = 3LL * size * size; // origin + x-axis + y-axis
// right angle at interior point P(px, py); uses GCD to step through valid Q points where PO·PQ = 0
// only iterates bottom triangle (py <= px) and doubles count for symmetry (except diagonal)
for (unsigned int px = 1; px <= size; ++px) {
for (unsigned int py = 1; py <= px; ++py) {
unsigned int factor = gcd(px, py);
unsigned int dx = px / factor;
unsigned int dy = py / factor;
unsigned int found = 0;
// Q below P
int qx = static_cast<int>(px) - dy;
int qy = static_cast<int>(py) + dx;
while (qx >= 0 && qy <= static_cast<int>(size)) {
++found;
qx -= dy;
qy += dx;
}
// Q above P
qx = static_cast<int>(px) + dy;
qy = static_cast<int>(py) - dx;
while (qy >= 0 && qx <= static_cast<int>(size)) {
++found;
qx += dy;
qy -= dx;
}
if (px != py) found *= 2;
result += found;
}
}
return result;
}

Solution Notes

Mathematical Background

This problem counts the number of right-angled triangles formed by points with integer coordinates on a grid from (0,0) to (50,50), where one vertex is at the origin and the right angle can be at any of the three vertices.

Algorithm Analysis

The solution iterates over possible positions for the right angle at point P, using GCD to find perpendicular directions. It counts valid Q positions in both directions from P, accounting for symmetry when P is not on the diagonal.

Performance

All implementations run in under 100ms, with the algorithm being O(N²) where N=50, making it highly efficient for this scale.

Key Insights

  • Cases where the right angle is at the origin or on the axes are counted separately.
  • GCD is used to reduce vectors to their simplest form for stepping along lattice lines.
  • Symmetry reduces computation by considering only px >= py and doubling counts.

Educational Value

Illustrates the application of number theory (GCD) in geometric problems on integer lattices, demonstrating how combinatorial methods can efficiently solve counting problems.

Problem #91 is taken from Project Euler and licensed under CC BY-NC-SA 4.0.