Этот вопрос вращается больше вокруг математики и алгоритмов, чем питонизмов.Решение, которое я предлагаю ниже, имеет сложность в O(n**2)
.
Идея состоит в том, чтобы обратить функцию (x, y) => x * x + y * y, где пространство поиска является перекрестным произведениемОригинальный список с собой.Затем, используя операторы множеств Python, вычислите пересечение между изображением приложения и допустимыми квадратами.В конце концов, используйте обратное приложение для восстановления триплетов.
from collections import defaultdict
original_list = [8, 5, 73, 3, 34, 4, 23, 73]
uniq = sorted(set(original_list))
antecedents = defaultdict(lambda: []) # Reverse mapping
for i, left in enumerate(uniq):
for right in uniq[i+1:]:
key = left * left + right * right
antecedents[key].append((left, right))
# The keys of antecedents are sum of squares
uniq_squares = set([ x * x for x in uniq ])
common_keys = uniq_squares & antecedents.keys()
for key in common_keys:
sqrt = int(0.5 + key**0.5)
key_antecedents = antecedents[key]
for (left, right) in key_antecedents:
print("Found triplet:", (left, right, sqrt))