from collections import namedtuple Point = namedtuple("P", ["x", "y"]) Vector = namedtuple("V", ["x", "y"]) def generate_triangles(n): all_points = [Point(x, y) for x in range(0, n + 1) for y in range(0, n + 1) ] all_points = all_points[1:] # remove (0, 0) all_pairs = [] for i in range(len(all_points)): for j in range(i + 1, len(all_points)): p = (all_points[i], all_points[j]) yield p def vector(p1, p2): return Vector(p2.x - p1.x, p2.y - p1.y) def dot_product(v1, v2): return v1.x * v2.x + v1.y * v2.y def has_right_angle(p, q): o = Point(0, 0) oq = vector(o, q) op = vector(o, p) qp = vector(q, p) if dot_product(oq, op) == 0: return True elif dot_product(oq, qp) == 0: return True elif dot_product(op, qp) == 0: return True return False def euler_091(): count = 0 ts = generate_triangles(50) for t in ts: if has_right_angle(*t): count += 1 return count if __name__ == "__main__": solution = euler_091() print("e091.py: " + str(solution)) assert(solution == 14234)