fork download
  1. import math
  2.  
  3. def count_parallelograms():
  4. count = 0
  5. n = 500
  6. # iterate through all distinct side lengths a, b
  7. # use the constraint: a + b < n
  8. for a in range(2, n):
  9. for b in range(1, a): # b < a ensures distinctness
  10. if a + b >= n:
  11. break
  12.  
  13. # Condition: a and b must be relatively prime
  14. if math.gcd(a, b) != 1:
  15. continue
  16.  
  17. # Parallelogram Law: d1^2 + d2^2 = 2(a^2 + b^2)
  18. S = 2 * (a * a + b * b)
  19.  
  20. # iterate through possible integer values for diagonal d1
  21. # constraints on d1:
  22. # 1) triangle Inequality: |a - b| < d1 < a + b
  23. # 2) to avoid double counting and ensure d2 exists: d1 <= sqrt(S/2)
  24. lower_bound = a - b + 1
  25. upper_bound = int(math.isqrt(S // 2))
  26.  
  27. for d1 in range(lower_bound, upper_bound + 1):
  28. # check if d2 is an integer
  29. d2_sq = S - d1 * d1
  30. d2 = math.isqrt(d2_sq)
  31.  
  32. if d2 * d2 != d2_sq:
  33. continue
  34.  
  35. # we have integer diagonals d1, d2.
  36. # now check for Integer Area using Heron's Formula on triangle (a, b, d1)
  37. # semiperimeter s must be integer for area to be integer => Perimeter even
  38. if (a + b + d1) % 2 != 0:
  39. continue
  40.  
  41. s = (a + b + d1) // 2
  42. # area squared = s(s-a)(s-b)(s-d1)
  43. area_sq = s * (s - a) * (s - b) * (s - d1)
  44.  
  45. if area_sq > 0:
  46. root_area = math.isqrt(area_sq)
  47. if root_area * root_area == area_sq:
  48. # All conditions met: integer sides, diagonals, and area
  49. count += 1
  50. # optional: Print found parallelograms
  51. # print(f"Sides: ({a}, {b}), Diagonals: ({d1}, {d2}), Area: {root_area * 2}")
  52.  
  53. return count
  54.  
  55. print(count_parallelograms())
Success #stdin #stdout 1.39s 14036KB
stdin
Standard input is empty
stdout
95