I'm trying to make a program that calculates quadruplets (a^3 b^3=c^3 d^3). With my current code i get 8 answers within the domain of [1, 15], but as you'll see by the output, the answers are all the same but the order is switched around. My question is: how can i filter out the duplicates and just get one answer? (Sorry if i caused you a heart attack with my messy code)
Code:
interval = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
solutions = []
for a in interval:
for b in interval:
for c in interval:
for d in interval:
if a != c and b !=d:
if a != d and b != c:
if a**3 b**3 == c**3 d**3:
temp = [a, b, c, d]
solutions.append(temp)
print(solutions)
Output:
[[1, 12, 9, 10], [1, 12, 10, 9], [9, 10, 1, 12], [9, 10, 12, 1], [10, 9, 1, 12], [10, 9, 12, 1], [12, 1, 9, 10], [12, 1, 10, 9]]
Thanks in advance!
CodePudding user response:
As ShadowRanger mentioned in the comments, itertools.combinations
is the tool to use:
from itertools import combinations
solutions = []
for (a,b),(c,d) in combinations(combinations(range(1,16),2),2):
if a**3 b**3 == c**3 d**3:
solutions.append((a,b,c,d))
print(solutions)
prints [(1, 12, 9, 10)]
CodePudding user response:
You can use itertools.combinations
to produce ordered 4-tuples from your list with much less duplication. But it does present a new problem, that you don't actually want ordered values, since your equation can't possibly be satisfied with a < b < c < d
, since you'd be adding up the cubes of the two smallest values which will always be smaller than the cubes of the two largest values.
That does lead us to a key insight. We never want to pair up the two largest and two smallest values from our four-tuple. Further, we don't even want to pair up the smaller of the first two values with the smaller of the second two values, because again, they cubes will always wind up smaller than the other pair. So we can just always pair up the largest value with the smallest value and pair up the two middle values. So if they're ordered (a < b < c < d
), you want a**3 d**3
and b**3 c**3
. Here's how I'd do that in code:
import itertools as it
interval = range(1, 16)
results = [[a, d, b, c] for a, b, c, d in it.combinations(interval, 4)
if a**3 d**3 == b**3 c**3]
CodePudding user response:
You can also add an order to your solutions. For example, according to your function, you can add this line to your conditions:
if a < b and c < d and a < c:
Then you only have:
Output : [[1, 12, 9, 10]]
CodePudding user response:
Here is a solution that involves itertools.product
and sets of sets of sets:
from itertools import product
interval = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
solutions = set()
for a, b, c, d in product(interval, repeat=4):
if a != c and b != d and a != d and b != c:
if a ** 3 b ** 3 == c ** 3 d ** 3:
left_side = frozenset({a, b})
right_side = frozenset({c, d})
equality = frozenset({left_side, right_side})
solutions.add(equality)
print(solutions)
This makes use of the fact that a
and b
can be swapped without affecting the equality, and the same goes for c
and d
, and (a, b)
can be swapped with (c, d)
.