|
| 1 | +""" |
| 2 | +Project Euler Problem 91: https://projecteuler.net/problem=91 |
| 3 | +
|
| 4 | +The points P (x1, y1) and Q (x2, y2) are plotted at integer coordinates and |
| 5 | +are joined to the origin, O(0,0), to form ΔOPQ. |
| 6 | + |
| 7 | +There are exactly fourteen triangles containing a right angle that can be formed |
| 8 | +when each coordinate lies between 0 and 2 inclusive; that is, |
| 9 | +0 ≤ x1, y1, x2, y2 ≤ 2. |
| 10 | + |
| 11 | +Given that 0 ≤ x1, y1, x2, y2 ≤ 50, how many right triangles can be formed? |
| 12 | +""" |
| 13 | + |
| 14 | + |
| 15 | +from itertools import combinations, product |
| 16 | + |
| 17 | + |
| 18 | +def is_right(x1: int, y1: int, x2: int, y2: int) -> bool: |
| 19 | + """ |
| 20 | + Check if the triangle described by P(x1,y1), Q(x2,y2) and O(0,0) is right-angled. |
| 21 | + Note: this doesn't check if P and Q are equal, but that's handled by the use of |
| 22 | + itertools.combinations in the solution function. |
| 23 | +
|
| 24 | + >>> is_right(0, 1, 2, 0) |
| 25 | + True |
| 26 | + >>> is_right(1, 0, 2, 2) |
| 27 | + False |
| 28 | + """ |
| 29 | + if x1 == y1 == 0 or x2 == y2 == 0: |
| 30 | + return False |
| 31 | + a_square = x1 * x1 + y1 * y1 |
| 32 | + b_square = x2 * x2 + y2 * y2 |
| 33 | + c_square = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) |
| 34 | + return ( |
| 35 | + a_square + b_square == c_square |
| 36 | + or a_square + c_square == b_square |
| 37 | + or b_square + c_square == a_square |
| 38 | + ) |
| 39 | + |
| 40 | + |
| 41 | +def solution(limit: int = 50) -> int: |
| 42 | + """ |
| 43 | + Return the number of right triangles OPQ that can be formed by two points P, Q |
| 44 | + which have both x- and y- coordinates between 0 and limit inclusive. |
| 45 | +
|
| 46 | + >>> solution(2) |
| 47 | + 14 |
| 48 | + >>> solution(10) |
| 49 | + 448 |
| 50 | + """ |
| 51 | + return sum( |
| 52 | + 1 |
| 53 | + for pt1, pt2 in combinations(product(range(limit + 1), repeat=2), 2) |
| 54 | + if is_right(*pt1, *pt2) |
| 55 | + ) |
| 56 | + |
| 57 | + |
| 58 | +if __name__ == "__main__": |
| 59 | + print(f"{solution() = }") |
0 commit comments