I need every combination of three positive integers with the sum of 1000.
This was my attempt but I'm unsure if this is correct since I have no way to validate it.
def getSum():
l = []
for x in range(1, 999):
total = 1000-x
for y in range(1, 999):
total = total-y
if total>0:
l.append([x, y, total])
return l
print len(getSum())
I get 28776 different combinations. Is that correct?
Since 1+998+1
and 1+1+998
are not the same thing, there are some incredible amount of combinations:
This line can generate them all:
[(i, 1000-i-k, k) for i in range(1,999) for k in range(1,1000-i)]
Results:
[...
(1, 4, 995),
(1, 3, 996),
(1, 2, 997),
(1, 1, 998),
(2, 997, 1),
(2, 996, 2),
...]
The length of this list is:
498501
No, that number is not correct. The problem with your code is this line:
total = total-y
Here, you decrease total
further and further with each value of y
that you try, never resetting it to the value after just subtracting x
. To fix it, create a new variable, eg total2
, and use that in the inner loop.
total2 = total-y
This way, you get 498501
combinations. Also, you can break
from the inner loop as soon as total2 < 0
.
If you need just the number of combinations: Note that there are N-1
combinations to sum two numbers to N
, eg for N==4
: 1+3
, 2+2
, 3+1
(assuming you consider 1+3
and 3+1
different). You can extend this to the case of three numbers as partitioning the number in two parts two times. This way, you only need a single loop. And this can be simplified further to an O(1) formula.
Example, with naive approach using product
as reference:
>>> N = 100 # to make reference faster
>>> sum(1 for t in product(range(1, N+1), repeat=3) if sum(t)==N)
4851
>>> sum(N-1-i for i in range(1, N-1))
4851
>>> ((N-2)*(N-1))//2
4851
Of course, also works for N = 1000
(or much, much larger):
>>> N = 1000
>>> sum(N-1-i for i in range(1, N-1))
498501
>>> ((N-2)*(N-1))//2
498501
If you treated [1,1,998] and [1,998,1] the same (no unique integers):
def getSum():
l = []
for x in range(1, 999):
total = 1000-x
for y in range(1, 999):
total = total-y
if total>0:
z = [x, y, total]
z.sort()
if z not in l:
l.append(z)
return l
a = getSum()
print(len(a))
If you want 3 unique integers:
def getSum():
l = []
for x in range(1, 999):
total = 1000-x
for y in range(1, 999):
total = total-y
if total>0:
z = [x, y, total]
z.sort()
if (z not in l) and (not((len(set(z)) < len(z)))):
l.append(z)
return l
a = getSum()
print(len(a))
Otherwise your code is (in my sense) ok. I haven't check your answer yet...
EDIT : I have checked it using brutal force. The correct answer is actually 498501 if you treated (1,1,998) and (998,1,1) differently. Currently I don't know why...
Try this:
def getSum():
l = []
for x in range(1, 6):
for y in range(1, 6):
total = 6-(y+x)
if total>0:
s = set([x, y, total])
if s not in l:
l.append(s)
print(x, y, total)
return l
print (len(getSum()))
This is my algorithm, Although there is better ways. In this case I wrote code for number 6 and printed all combinations to show how it works. You can set 1000 or any number instead of 6 in this code(in 3 position) and ignore print() line.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.