""" If p is the perimeter of a right angle triangle with integral length sides, {a, b, c} , there are exactly three solutions for p = 120. {20,48,52},{24,45,51},{30,40,50} For which value of p<=1000, is the number of solutions maximised? """ import time import math def timer(func): def wrapper(*args, **kwargs): start_time = time.time() result = func(*args, **kwargs) end_time = time.time() print(f"{func.__name__} took time: {end_time - start_time:.6f} seconds") return result return wrapper def generate_pythagorean_triples(max_perimeter: int = 1000) : """ 使用yield生成勾股三元组的m和n参数 参数: max_perimeter: 三角形周长的最大值 生成: (m, n) 元组,满足: - m > n > 0 - m和n互质 (gcd(m, n) == 1) - m和n一奇一偶 - 三角形周长 2*m*(m+n) < max_perimeter """ # 从m=2开始(因为m>n≥1) m = 2 while True: # 对于每个m,n从1到m-1 for n in range(1, m): # 检查是否满足互质条件 if math.gcd(m, n) != 1: continue # 检查是否一奇一偶 if (m % 2) == (n % 2): continue # 计算对应三角形的周长 perimeter = 2 * m * (m + n) # 如果周长超过限制,则停止生成 if perimeter >= max_perimeter: # 对于当前m,如果最小周长(当n=1时)已经超过限制, # 那么后续更大的m也会超过,所以完全停止 if n == 1: return # 如果周长在限制内,则yield当前(m, n) if perimeter < max_perimeter: yield (m, n) m += 1 def triangle_length(m:int, n:int) -> int: return 2 * m * (m + n) def get_abc(m:int, n:int) -> tuple[int, int, int]: a = m**2 - n**2 b = 2 * m * n c = m**2 + n**2 return a, b, c def primitive_triangles(limit: int = 1000) -> dict[int, list] : triangle_lengths = {} for m, n in generate_pythagorean_triples(limit): length = triangle_length(m, n) if length not in triangle_lengths: triangle_lengths[length] = set() a,b,c = get_abc(m, n) triangle_lengths[length].add((a, b, c)) for k in range(2, limit // length + 1) : lenp = k * (a + b + c) if lenp not in triangle_lengths: triangle_lengths[lenp] = set() triangle_lengths[lenp].add((a*k, b*k, c*k)) return triangle_lengths @timer def main(): max_perimeter = 1000 triangle_lengths = primitive_triangles(max_perimeter) print(triangle_lengths) max_length = max(triangle_lengths, key=lambda x: len(triangle_lengths[x])) print(f"Max length: {max_length}, Count: {len(triangle_lengths[max_length])}") if __name__ == "__main__": main()