# Simulating a scale, balancing weight from lists

I have simulated balancing a scale by having each side total the same weight.

The scale has two weights (left and right side) and some spare weights:

weights = [3, 4]
spare_weights = [1, 2, 7, 7]


A maximum of two weights can be used from the spare weights to balance the scale. The spare(s) may be on a single side or split between both.

The output should be the minimum number of weight needed to balance the scale.

import itertools

weights = [3, 4]
spare_weights = [1, 2, 7, 7]
c = enumerate([subset for l in range(0, 3) for subset in itertools.combinations(spare_weights, l)])

cc = cc = list(itertools.combinations(c, 2))

left, right = weights
qualifying_combos = []
for c in cc:
l, r = c
if sum(l[1]) + left == sum(r[1]) + right:
qualifying_combos.append(list(l[1]) + list(r[1]))
elif sum(l[1]) + right == sum(r[1]) + left:
qualifying_combos.append(list(l[1]) + list(r[1]))
print(min(qualifying_combos, key=len))


output:

[1]


Is there a more elegant way to code this?

• @close-voter&down-voter what code is missing from the question? The code runs as stated. This seems like a pretty ridiculous judgment, did you, the close voter, even try to run the code? – Peilonrayz Dec 16 '19 at 13:10
• A made a few edits since they downvoted. – Dave Dec 16 '19 at 13:13
• As the 3rd viewer, I'm guessing I saw the original. That didn't deserve a CV. Thank you for the edit, no-one should have any qualms with whether it's LCC now. – Peilonrayz Dec 16 '19 at 13:17
• @Peilonrayz I don't know, but it may have something to do with the old first sentence which could, if you squint your eyes just right, may be misconstrued as a request for alternative implementations instead of reviews. – Mast Dec 16 '19 at 13:58
• Can both spares be put on one side? – JollyJoker Dec 16 '19 at 14:18

1. Write functions. Make this a balance_scale function, that returns the minimum.
2. Your variable names are pretty poor, single letter variable names leave people guessing at what they mean.
3. You should change cc = cc = ... to just one assignment.

Since you can use a maximum of two spare weights the solution can be a lot simpler than you've produced.

1. $$\W_1\$$ is the smaller weight in weights and $$\W_2\$$ is the larger.
2. If $$\W_1 = W_2\$$ then you return an empty list.
3. We can determine what weight is needed when only one weight can be used.

$$\S = W_2 - W_1\$$

Therefore if $$\S\$$ is in spare_weights then we can return $$\S\$$.

4. For each $$\S_1\$$ in spare_weights we can determine the weight needed, $$\S_2\$$.

$$\S_2 = |W_2 - W_1 - S_1|\$$

We take the absolute as this weight can be on either side of the scale. If the non-absolute value of $$\S_2\$$ is positive then we add it to $$\W_1 + S_1\$$ if it's negative then we add it to $$\W_2\$$.

If we add $$\0\$$ twice to spare_weights, then we can see that (4), (3) and (2) are all roughly the same equation.

We don't need to check if $$\S_1\$$ and $$\S_2\$$ both exist in spare_weights, as the only time they are the same is if $$\W_1 = W_2\$$, and so they would both be 0. We however have to assign $$\S_1\$$ to 0 first.

def balance_scale(scale, spares):
w1, w2 = sorted(scale)
spare_set = set(spares) | {0}
for s1 in [0] + spares:
s2 = abs(w2 - w1 - s1)
if s2 in spare_set:
return [i for i in [s1, s2] if i]
return None

print(balance_scale([4, 3], [1, 2, 7, 7]))

[1]