This questions revolves more around math and algorithms than pythonisms. The solution I propose below has a complexity in O(n**2)
.
The idea is to reverse the function (x, y) => x * x + y * y, where the search space is the cross product of the original list with itself. Then, using Python set operators, compute the intersection between the application image and the acceptable squares. Eventually, use the reversed application to reconstruct the triplets.
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))