Reputation: 47
I am new to programming in general and am trying to do the "Goldbach Theorie" in Python, that every number between 3 and a given number (in my case 50.)
lijst2 = []
for n in lijst:
j = 2*n+1
lijst2.append(j)
priemgetallen = [2]
counter = 2
x = 2
while len(priemgetallen)<50:
priemgetallendelers = []
for i in range (1,counter+1):
if counter % i == 0:
priemgetallendelers.append(i)
if len(priemgetallendelers) == 2:
priemgetallen.append(counter)
counter += 1
else:
counter +=1
The code above is unimportant for my problem and is only there to make it easier to understand what I am trying to do.
while not len(sommen) == len(lijst2):
for i in lijst2:
for j in priemgetallen:
for r in priemgetallen:
for t in priemgetallen:
if i == j+r+t:
Here I am trying to say that if a number in my original list, is made up out of the sum of three prime numbers, add it to the list.
sommen2 = []
sommen2.append(j)
sommen2.append(r)
sommen2.append(t)
So until here everything seams to work but if I let it print out the output I get several times the same "I" or rather the same sum from the prime numbers.
for q in sommen:
if not sum(sommen2) == sum(q):
sommen.append(sommen2)
Here I am trying to say that for a q in my list "sommen" if a sum of that q already exists, don't add another one. Bu instead my laptop just calculates for a long time.
print (sommen)
Upvotes: 0
Views: 177
Reputation: 14226
The problem is your loop. You are returning the same sums more than once because your loop treats [1, 7, 5]
as being different from [5, 7, 1]
as being different from [7, 5, 1]
and so on.
Clean up the loop to be this.
import itertools
l = [10, 15, 4, 2, 7, 20]
p = [1, 2, 3, 5, 7, 11, 13]
sommen = []
for v in map(lambda x: sum(x), itertools.combinations(p, 3)):
if v in sommen:
pass
elif v in l:
sommen.append(v)
print sommen
>> [10, 15, 20]
As expected
2 + 3 + 5 = 10
3 + 5 + 7 = 15
2 + 7 + 11 = 20
Notice that 1 + 2 + 7 also gives 10 but 10 was not added twice
Notice that 2 + 5 + 13 also gives 20 but 20 was not added twice
Edit: If you want to see the factors that went in how about this:
for combo in itertools.combinations(p, 3):
if sum(combo) in map(lambda x: x[0],sommen):
pass
elif sum(combo) in l:
sommen.append([sum(combo), combo])
print sommen
>> [[10, (1, 2, 7)], [15, (1, 3, 11)], [20, (2, 5, 13)]]
Upvotes: 0
Reputation: 709
The problem is the following code:
for q in sommen:
if not sum(sommen2) == sum(q):
sommen.append(sommen2)
If I understand you correctly you want to add sommen2 to sommen if its sum is not already in sommen. But what you do is, you add it to sommen for every element in sommen which has not the same sum as sommen2. Replace this by the following:
if not any(sum(sommen2) == sum(q) for q in sommen):
sommen.append(sommen2)
Upvotes: 0
Reputation:
To answer your original question first:
The issue lies in the fact that you iterated the entire sommen
when checking for only one item sommen2
. Suppose sommen
contains 9 values including one that is equal to sommen2
's sum, you are still appending sommen2
for 8 times.
I would use a dict to comprehensively rewrite your program, like this:
sum_summands = dict()
# found a candidate i=j+r+t here
sum_summands[i] = (j,r,t) #use tuple not list
# or if you want to always keep the first candidate you've found
if i not in sum_summands: # don't overwrite if sum i already exists
sum_summands[i] = (j,r,t)
There are a ton of other things you can optimize in your algorithm. Let me point out the most obvious one. Instead of doing this -
for i in lijst2:
for j in priemgetallen:
for r in priemgetallen:
for t in priemgetallen:
if i == j+r+t:
why don't you get rid of the inner-most loop -
for i in lijst2:
for j in priemgetallen:
for r in priemgetallen:
if i-j-r in priemgetallen:
It's pointless to iterate over a huge list of numbers just to check if they add up to a certain sum - you should do some minimum level of math to simplify things.
Upvotes: 0