Use python to solve a math problem: sum up to a value as close as possible











up vote
1
down vote

favorite












I have a list of numbers. Now if I set a fixed value V, is it possible for python to divide the list into several groups such that each group's sum is not smaller than V (get those groups as many as possible)?



Ex: if the list is [1,2,3,4,5] and the V is 6, then the result should be [[1,5],[2,3,4]]. Dividing the group means you cannot use the same original item more than once.



There's no limitation on how many items each sublist can contain and also the numbers are not in order (can be some random numbers). Could someone help me out? So far my solution is sum up all the combinations and compare the sums. But I'm pretty sure there should be a more effective solution. Thanks!



My solution: I kinda use this first and do the rest job by my mind, so it doesn't worth a further development.



import itertools
import math

stuff = list(range(10))
v = 6

for L in range(0, len(stuff)+1):
for subset in itertools.combinations(stuff, L):
if math.fsum(subset) > v:
print(subset,math.fsum(subset))









share|improve this question
























  • Can you show your solution as code?
    – Austin
    Nov 19 at 17:52










  • @RoryDaulton Yeah I just notice that. I changed my description. Thanks!
    – Louie Lee
    Nov 19 at 17:54










  • But still, according to your description, the 3 should not be seperate
    – user8408080
    Nov 19 at 18:15










  • @user8408080 You're right
    – Louie Lee
    Nov 19 at 18:19















up vote
1
down vote

favorite












I have a list of numbers. Now if I set a fixed value V, is it possible for python to divide the list into several groups such that each group's sum is not smaller than V (get those groups as many as possible)?



Ex: if the list is [1,2,3,4,5] and the V is 6, then the result should be [[1,5],[2,3,4]]. Dividing the group means you cannot use the same original item more than once.



There's no limitation on how many items each sublist can contain and also the numbers are not in order (can be some random numbers). Could someone help me out? So far my solution is sum up all the combinations and compare the sums. But I'm pretty sure there should be a more effective solution. Thanks!



My solution: I kinda use this first and do the rest job by my mind, so it doesn't worth a further development.



import itertools
import math

stuff = list(range(10))
v = 6

for L in range(0, len(stuff)+1):
for subset in itertools.combinations(stuff, L):
if math.fsum(subset) > v:
print(subset,math.fsum(subset))









share|improve this question
























  • Can you show your solution as code?
    – Austin
    Nov 19 at 17:52










  • @RoryDaulton Yeah I just notice that. I changed my description. Thanks!
    – Louie Lee
    Nov 19 at 17:54










  • But still, according to your description, the 3 should not be seperate
    – user8408080
    Nov 19 at 18:15










  • @user8408080 You're right
    – Louie Lee
    Nov 19 at 18:19













up vote
1
down vote

favorite









up vote
1
down vote

favorite











I have a list of numbers. Now if I set a fixed value V, is it possible for python to divide the list into several groups such that each group's sum is not smaller than V (get those groups as many as possible)?



Ex: if the list is [1,2,3,4,5] and the V is 6, then the result should be [[1,5],[2,3,4]]. Dividing the group means you cannot use the same original item more than once.



There's no limitation on how many items each sublist can contain and also the numbers are not in order (can be some random numbers). Could someone help me out? So far my solution is sum up all the combinations and compare the sums. But I'm pretty sure there should be a more effective solution. Thanks!



My solution: I kinda use this first and do the rest job by my mind, so it doesn't worth a further development.



import itertools
import math

stuff = list(range(10))
v = 6

for L in range(0, len(stuff)+1):
for subset in itertools.combinations(stuff, L):
if math.fsum(subset) > v:
print(subset,math.fsum(subset))









share|improve this question















I have a list of numbers. Now if I set a fixed value V, is it possible for python to divide the list into several groups such that each group's sum is not smaller than V (get those groups as many as possible)?



Ex: if the list is [1,2,3,4,5] and the V is 6, then the result should be [[1,5],[2,3,4]]. Dividing the group means you cannot use the same original item more than once.



There's no limitation on how many items each sublist can contain and also the numbers are not in order (can be some random numbers). Could someone help me out? So far my solution is sum up all the combinations and compare the sums. But I'm pretty sure there should be a more effective solution. Thanks!



My solution: I kinda use this first and do the rest job by my mind, so it doesn't worth a further development.



import itertools
import math

stuff = list(range(10))
v = 6

for L in range(0, len(stuff)+1):
for subset in itertools.combinations(stuff, L):
if math.fsum(subset) > v:
print(subset,math.fsum(subset))






python list math sum






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 19 at 18:18

























asked Nov 19 at 17:50









Louie Lee

408




408












  • Can you show your solution as code?
    – Austin
    Nov 19 at 17:52










  • @RoryDaulton Yeah I just notice that. I changed my description. Thanks!
    – Louie Lee
    Nov 19 at 17:54










  • But still, according to your description, the 3 should not be seperate
    – user8408080
    Nov 19 at 18:15










  • @user8408080 You're right
    – Louie Lee
    Nov 19 at 18:19


















  • Can you show your solution as code?
    – Austin
    Nov 19 at 17:52










  • @RoryDaulton Yeah I just notice that. I changed my description. Thanks!
    – Louie Lee
    Nov 19 at 17:54










  • But still, according to your description, the 3 should not be seperate
    – user8408080
    Nov 19 at 18:15










  • @user8408080 You're right
    – Louie Lee
    Nov 19 at 18:19
















Can you show your solution as code?
– Austin
Nov 19 at 17:52




Can you show your solution as code?
– Austin
Nov 19 at 17:52












@RoryDaulton Yeah I just notice that. I changed my description. Thanks!
– Louie Lee
Nov 19 at 17:54




@RoryDaulton Yeah I just notice that. I changed my description. Thanks!
– Louie Lee
Nov 19 at 17:54












But still, according to your description, the 3 should not be seperate
– user8408080
Nov 19 at 18:15




But still, according to your description, the 3 should not be seperate
– user8408080
Nov 19 at 18:15












@user8408080 You're right
– Louie Lee
Nov 19 at 18:19




@user8408080 You're right
– Louie Lee
Nov 19 at 18:19












2 Answers
2






active

oldest

votes

















up vote
1
down vote



accepted










My solution has O(n^2) time complexity. You can sort list in ascending order. Then iterate over list from the end. As You want max number of subsets, then each value greater then V added to array. In other case collect values from right and left corners while achieve sum of subset equals to V:



def get_value_in_dict(d):
return d.get(list(d)[0])

# Implementation for a list of dictionaries like [{'apple':1},{'pear':22},{'hat':23},{'glass':44}]
def sum_up_to_value(stuff, val):
new_stuff =
sorted_stuff = list(sorted(stuff, key=lambda el: get_value_in_dict(el)))
n = len(stuff)
pointer_r = n - 1
pointer_l = 0
queue = list()

while pointer_r >= pointer_l:
if get_value_in_dict(sorted_stuff[pointer_r]) >= val:
new_stuff.append([sorted_stuff[pointer_r]])
else:
subsum = get_value_in_dict(sorted_stuff[pointer_r])
substuff =
while pointer_l < pointer_r and subsum < val:
# get from queue
while len(queue) and subsum < val:
temp = queue.pop(0)
subsum += get_value_in_dict(temp)
substuff.append(temp)
# get from input
else:
if subsum < val:
subsum += get_value_in_dict(sorted_stuff[pointer_l])
substuff.append(sorted_stuff[pointer_l])
pointer_l += 1
substuff.append(sorted_stuff[pointer_r])
# returns back smallest elements
while subsum - get_value_in_dict(substuff[0]) >= val:
temp = substuff.pop(0)
queue.append(temp)
subsum -= get_value_in_dict(substuff[0])

if subsum < val:
# add substuff to last element of new_stuff
temp = new_stuff.pop()
new_stuff.append(temp + substuff)
else:
new_stuff.append(substuff)
pointer_r -= 1
return new_stuff # list(map(lambda el: sorted(el, key=lambda el_d: get_value_in_dict(el_d)), new_stuff)) for sorted by value elements in resulting list





share|improve this answer























  • Actually for [1, 2, 3, 4, 5] and V = 6, I need [[1,5],[2,3,4]] or [[1,3,5],[2,4]] since 3 is smaller than 6 so it cannot be a sublist by itself.
    – Louie Lee
    Nov 20 at 6:07










  • @LouieLee, I added some code for your new requirements
    – Alexey S. Kiselev
    Nov 20 at 6:17










  • Awesome! But is that possible to do the same thing on a list whose items are dict, like [{'apple':1},{'pear':22},{'hat':23},{'glass':44}] to have [[{'apple':1},{'glass':44}],[{'pear':22},{'hat':23}]]? Thanks
    – Louie Lee
    Nov 20 at 7:27










  • @LouieLee, just edited code for a list of dictionaries. Just added one function for getting value in dict. Works in Python 3.6
    – Alexey S. Kiselev
    Nov 20 at 7:48






  • 1




    @LouieLee, if You are ok with this solution, please, mark this answer as useful.
    – Alexey S. Kiselev
    Nov 20 at 8:20


















up vote
0
down vote













If you sort your list, this should get you the desired result, although it's not very beautiful as I have to admit:



stuff = range(10)
l = len(stuff)
v = 6

new_stuff =
i = 0
active = True

while active:
sub_stuff =
subsum = 0
while subsum<v:
if i>(l-1):
active = False
break
el = stuff[i]
sub_stuff.append(el)
subsum += el
i += 1
else:
new_stuff.append(sub_stuff)


It just goes through your list and sums element until their sum is 6 or higher and then appends a list of those elements to new_stuff and goes on to find the next list.



Try a test list like:



import numpy as np
stuff = sorted(np.random.randint(0,10,100))





share|improve this answer























  • You might change while subsum<6 to while subsum<v?
    – Louie Lee
    Nov 19 at 21:53










  • Also, if I have stuff = [44,23,22,1] and v = 45, your code yields [[44, 23]] instead of [[44,1],[23,22]]
    – Louie Lee
    Nov 19 at 22:06












  • If stuff = [1,22,23,44] and v = 45, your code yields [[1, 22, 23]] instead of [[44,1],[23,22]]
    – Louie Lee
    Nov 19 at 22:09










  • Yes, you are right; this algorithm is too simple. Maybe I can come up with something better tomorrow
    – user8408080
    Nov 20 at 0:58











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53380134%2fuse-python-to-solve-a-math-problem-sum-up-to-a-value-as-close-as-possible%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
1
down vote



accepted










My solution has O(n^2) time complexity. You can sort list in ascending order. Then iterate over list from the end. As You want max number of subsets, then each value greater then V added to array. In other case collect values from right and left corners while achieve sum of subset equals to V:



def get_value_in_dict(d):
return d.get(list(d)[0])

# Implementation for a list of dictionaries like [{'apple':1},{'pear':22},{'hat':23},{'glass':44}]
def sum_up_to_value(stuff, val):
new_stuff =
sorted_stuff = list(sorted(stuff, key=lambda el: get_value_in_dict(el)))
n = len(stuff)
pointer_r = n - 1
pointer_l = 0
queue = list()

while pointer_r >= pointer_l:
if get_value_in_dict(sorted_stuff[pointer_r]) >= val:
new_stuff.append([sorted_stuff[pointer_r]])
else:
subsum = get_value_in_dict(sorted_stuff[pointer_r])
substuff =
while pointer_l < pointer_r and subsum < val:
# get from queue
while len(queue) and subsum < val:
temp = queue.pop(0)
subsum += get_value_in_dict(temp)
substuff.append(temp)
# get from input
else:
if subsum < val:
subsum += get_value_in_dict(sorted_stuff[pointer_l])
substuff.append(sorted_stuff[pointer_l])
pointer_l += 1
substuff.append(sorted_stuff[pointer_r])
# returns back smallest elements
while subsum - get_value_in_dict(substuff[0]) >= val:
temp = substuff.pop(0)
queue.append(temp)
subsum -= get_value_in_dict(substuff[0])

if subsum < val:
# add substuff to last element of new_stuff
temp = new_stuff.pop()
new_stuff.append(temp + substuff)
else:
new_stuff.append(substuff)
pointer_r -= 1
return new_stuff # list(map(lambda el: sorted(el, key=lambda el_d: get_value_in_dict(el_d)), new_stuff)) for sorted by value elements in resulting list





share|improve this answer























  • Actually for [1, 2, 3, 4, 5] and V = 6, I need [[1,5],[2,3,4]] or [[1,3,5],[2,4]] since 3 is smaller than 6 so it cannot be a sublist by itself.
    – Louie Lee
    Nov 20 at 6:07










  • @LouieLee, I added some code for your new requirements
    – Alexey S. Kiselev
    Nov 20 at 6:17










  • Awesome! But is that possible to do the same thing on a list whose items are dict, like [{'apple':1},{'pear':22},{'hat':23},{'glass':44}] to have [[{'apple':1},{'glass':44}],[{'pear':22},{'hat':23}]]? Thanks
    – Louie Lee
    Nov 20 at 7:27










  • @LouieLee, just edited code for a list of dictionaries. Just added one function for getting value in dict. Works in Python 3.6
    – Alexey S. Kiselev
    Nov 20 at 7:48






  • 1




    @LouieLee, if You are ok with this solution, please, mark this answer as useful.
    – Alexey S. Kiselev
    Nov 20 at 8:20















up vote
1
down vote



accepted










My solution has O(n^2) time complexity. You can sort list in ascending order. Then iterate over list from the end. As You want max number of subsets, then each value greater then V added to array. In other case collect values from right and left corners while achieve sum of subset equals to V:



def get_value_in_dict(d):
return d.get(list(d)[0])

# Implementation for a list of dictionaries like [{'apple':1},{'pear':22},{'hat':23},{'glass':44}]
def sum_up_to_value(stuff, val):
new_stuff =
sorted_stuff = list(sorted(stuff, key=lambda el: get_value_in_dict(el)))
n = len(stuff)
pointer_r = n - 1
pointer_l = 0
queue = list()

while pointer_r >= pointer_l:
if get_value_in_dict(sorted_stuff[pointer_r]) >= val:
new_stuff.append([sorted_stuff[pointer_r]])
else:
subsum = get_value_in_dict(sorted_stuff[pointer_r])
substuff =
while pointer_l < pointer_r and subsum < val:
# get from queue
while len(queue) and subsum < val:
temp = queue.pop(0)
subsum += get_value_in_dict(temp)
substuff.append(temp)
# get from input
else:
if subsum < val:
subsum += get_value_in_dict(sorted_stuff[pointer_l])
substuff.append(sorted_stuff[pointer_l])
pointer_l += 1
substuff.append(sorted_stuff[pointer_r])
# returns back smallest elements
while subsum - get_value_in_dict(substuff[0]) >= val:
temp = substuff.pop(0)
queue.append(temp)
subsum -= get_value_in_dict(substuff[0])

if subsum < val:
# add substuff to last element of new_stuff
temp = new_stuff.pop()
new_stuff.append(temp + substuff)
else:
new_stuff.append(substuff)
pointer_r -= 1
return new_stuff # list(map(lambda el: sorted(el, key=lambda el_d: get_value_in_dict(el_d)), new_stuff)) for sorted by value elements in resulting list





share|improve this answer























  • Actually for [1, 2, 3, 4, 5] and V = 6, I need [[1,5],[2,3,4]] or [[1,3,5],[2,4]] since 3 is smaller than 6 so it cannot be a sublist by itself.
    – Louie Lee
    Nov 20 at 6:07










  • @LouieLee, I added some code for your new requirements
    – Alexey S. Kiselev
    Nov 20 at 6:17










  • Awesome! But is that possible to do the same thing on a list whose items are dict, like [{'apple':1},{'pear':22},{'hat':23},{'glass':44}] to have [[{'apple':1},{'glass':44}],[{'pear':22},{'hat':23}]]? Thanks
    – Louie Lee
    Nov 20 at 7:27










  • @LouieLee, just edited code for a list of dictionaries. Just added one function for getting value in dict. Works in Python 3.6
    – Alexey S. Kiselev
    Nov 20 at 7:48






  • 1




    @LouieLee, if You are ok with this solution, please, mark this answer as useful.
    – Alexey S. Kiselev
    Nov 20 at 8:20













up vote
1
down vote



accepted







up vote
1
down vote



accepted






My solution has O(n^2) time complexity. You can sort list in ascending order. Then iterate over list from the end. As You want max number of subsets, then each value greater then V added to array. In other case collect values from right and left corners while achieve sum of subset equals to V:



def get_value_in_dict(d):
return d.get(list(d)[0])

# Implementation for a list of dictionaries like [{'apple':1},{'pear':22},{'hat':23},{'glass':44}]
def sum_up_to_value(stuff, val):
new_stuff =
sorted_stuff = list(sorted(stuff, key=lambda el: get_value_in_dict(el)))
n = len(stuff)
pointer_r = n - 1
pointer_l = 0
queue = list()

while pointer_r >= pointer_l:
if get_value_in_dict(sorted_stuff[pointer_r]) >= val:
new_stuff.append([sorted_stuff[pointer_r]])
else:
subsum = get_value_in_dict(sorted_stuff[pointer_r])
substuff =
while pointer_l < pointer_r and subsum < val:
# get from queue
while len(queue) and subsum < val:
temp = queue.pop(0)
subsum += get_value_in_dict(temp)
substuff.append(temp)
# get from input
else:
if subsum < val:
subsum += get_value_in_dict(sorted_stuff[pointer_l])
substuff.append(sorted_stuff[pointer_l])
pointer_l += 1
substuff.append(sorted_stuff[pointer_r])
# returns back smallest elements
while subsum - get_value_in_dict(substuff[0]) >= val:
temp = substuff.pop(0)
queue.append(temp)
subsum -= get_value_in_dict(substuff[0])

if subsum < val:
# add substuff to last element of new_stuff
temp = new_stuff.pop()
new_stuff.append(temp + substuff)
else:
new_stuff.append(substuff)
pointer_r -= 1
return new_stuff # list(map(lambda el: sorted(el, key=lambda el_d: get_value_in_dict(el_d)), new_stuff)) for sorted by value elements in resulting list





share|improve this answer














My solution has O(n^2) time complexity. You can sort list in ascending order. Then iterate over list from the end. As You want max number of subsets, then each value greater then V added to array. In other case collect values from right and left corners while achieve sum of subset equals to V:



def get_value_in_dict(d):
return d.get(list(d)[0])

# Implementation for a list of dictionaries like [{'apple':1},{'pear':22},{'hat':23},{'glass':44}]
def sum_up_to_value(stuff, val):
new_stuff =
sorted_stuff = list(sorted(stuff, key=lambda el: get_value_in_dict(el)))
n = len(stuff)
pointer_r = n - 1
pointer_l = 0
queue = list()

while pointer_r >= pointer_l:
if get_value_in_dict(sorted_stuff[pointer_r]) >= val:
new_stuff.append([sorted_stuff[pointer_r]])
else:
subsum = get_value_in_dict(sorted_stuff[pointer_r])
substuff =
while pointer_l < pointer_r and subsum < val:
# get from queue
while len(queue) and subsum < val:
temp = queue.pop(0)
subsum += get_value_in_dict(temp)
substuff.append(temp)
# get from input
else:
if subsum < val:
subsum += get_value_in_dict(sorted_stuff[pointer_l])
substuff.append(sorted_stuff[pointer_l])
pointer_l += 1
substuff.append(sorted_stuff[pointer_r])
# returns back smallest elements
while subsum - get_value_in_dict(substuff[0]) >= val:
temp = substuff.pop(0)
queue.append(temp)
subsum -= get_value_in_dict(substuff[0])

if subsum < val:
# add substuff to last element of new_stuff
temp = new_stuff.pop()
new_stuff.append(temp + substuff)
else:
new_stuff.append(substuff)
pointer_r -= 1
return new_stuff # list(map(lambda el: sorted(el, key=lambda el_d: get_value_in_dict(el_d)), new_stuff)) for sorted by value elements in resulting list






share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 23 at 16:32

























answered Nov 20 at 5:59









Alexey S. Kiselev

1046




1046












  • Actually for [1, 2, 3, 4, 5] and V = 6, I need [[1,5],[2,3,4]] or [[1,3,5],[2,4]] since 3 is smaller than 6 so it cannot be a sublist by itself.
    – Louie Lee
    Nov 20 at 6:07










  • @LouieLee, I added some code for your new requirements
    – Alexey S. Kiselev
    Nov 20 at 6:17










  • Awesome! But is that possible to do the same thing on a list whose items are dict, like [{'apple':1},{'pear':22},{'hat':23},{'glass':44}] to have [[{'apple':1},{'glass':44}],[{'pear':22},{'hat':23}]]? Thanks
    – Louie Lee
    Nov 20 at 7:27










  • @LouieLee, just edited code for a list of dictionaries. Just added one function for getting value in dict. Works in Python 3.6
    – Alexey S. Kiselev
    Nov 20 at 7:48






  • 1




    @LouieLee, if You are ok with this solution, please, mark this answer as useful.
    – Alexey S. Kiselev
    Nov 20 at 8:20


















  • Actually for [1, 2, 3, 4, 5] and V = 6, I need [[1,5],[2,3,4]] or [[1,3,5],[2,4]] since 3 is smaller than 6 so it cannot be a sublist by itself.
    – Louie Lee
    Nov 20 at 6:07










  • @LouieLee, I added some code for your new requirements
    – Alexey S. Kiselev
    Nov 20 at 6:17










  • Awesome! But is that possible to do the same thing on a list whose items are dict, like [{'apple':1},{'pear':22},{'hat':23},{'glass':44}] to have [[{'apple':1},{'glass':44}],[{'pear':22},{'hat':23}]]? Thanks
    – Louie Lee
    Nov 20 at 7:27










  • @LouieLee, just edited code for a list of dictionaries. Just added one function for getting value in dict. Works in Python 3.6
    – Alexey S. Kiselev
    Nov 20 at 7:48






  • 1




    @LouieLee, if You are ok with this solution, please, mark this answer as useful.
    – Alexey S. Kiselev
    Nov 20 at 8:20
















Actually for [1, 2, 3, 4, 5] and V = 6, I need [[1,5],[2,3,4]] or [[1,3,5],[2,4]] since 3 is smaller than 6 so it cannot be a sublist by itself.
– Louie Lee
Nov 20 at 6:07




Actually for [1, 2, 3, 4, 5] and V = 6, I need [[1,5],[2,3,4]] or [[1,3,5],[2,4]] since 3 is smaller than 6 so it cannot be a sublist by itself.
– Louie Lee
Nov 20 at 6:07












@LouieLee, I added some code for your new requirements
– Alexey S. Kiselev
Nov 20 at 6:17




@LouieLee, I added some code for your new requirements
– Alexey S. Kiselev
Nov 20 at 6:17












Awesome! But is that possible to do the same thing on a list whose items are dict, like [{'apple':1},{'pear':22},{'hat':23},{'glass':44}] to have [[{'apple':1},{'glass':44}],[{'pear':22},{'hat':23}]]? Thanks
– Louie Lee
Nov 20 at 7:27




Awesome! But is that possible to do the same thing on a list whose items are dict, like [{'apple':1},{'pear':22},{'hat':23},{'glass':44}] to have [[{'apple':1},{'glass':44}],[{'pear':22},{'hat':23}]]? Thanks
– Louie Lee
Nov 20 at 7:27












@LouieLee, just edited code for a list of dictionaries. Just added one function for getting value in dict. Works in Python 3.6
– Alexey S. Kiselev
Nov 20 at 7:48




@LouieLee, just edited code for a list of dictionaries. Just added one function for getting value in dict. Works in Python 3.6
– Alexey S. Kiselev
Nov 20 at 7:48




1




1




@LouieLee, if You are ok with this solution, please, mark this answer as useful.
– Alexey S. Kiselev
Nov 20 at 8:20




@LouieLee, if You are ok with this solution, please, mark this answer as useful.
– Alexey S. Kiselev
Nov 20 at 8:20












up vote
0
down vote













If you sort your list, this should get you the desired result, although it's not very beautiful as I have to admit:



stuff = range(10)
l = len(stuff)
v = 6

new_stuff =
i = 0
active = True

while active:
sub_stuff =
subsum = 0
while subsum<v:
if i>(l-1):
active = False
break
el = stuff[i]
sub_stuff.append(el)
subsum += el
i += 1
else:
new_stuff.append(sub_stuff)


It just goes through your list and sums element until their sum is 6 or higher and then appends a list of those elements to new_stuff and goes on to find the next list.



Try a test list like:



import numpy as np
stuff = sorted(np.random.randint(0,10,100))





share|improve this answer























  • You might change while subsum<6 to while subsum<v?
    – Louie Lee
    Nov 19 at 21:53










  • Also, if I have stuff = [44,23,22,1] and v = 45, your code yields [[44, 23]] instead of [[44,1],[23,22]]
    – Louie Lee
    Nov 19 at 22:06












  • If stuff = [1,22,23,44] and v = 45, your code yields [[1, 22, 23]] instead of [[44,1],[23,22]]
    – Louie Lee
    Nov 19 at 22:09










  • Yes, you are right; this algorithm is too simple. Maybe I can come up with something better tomorrow
    – user8408080
    Nov 20 at 0:58















up vote
0
down vote













If you sort your list, this should get you the desired result, although it's not very beautiful as I have to admit:



stuff = range(10)
l = len(stuff)
v = 6

new_stuff =
i = 0
active = True

while active:
sub_stuff =
subsum = 0
while subsum<v:
if i>(l-1):
active = False
break
el = stuff[i]
sub_stuff.append(el)
subsum += el
i += 1
else:
new_stuff.append(sub_stuff)


It just goes through your list and sums element until their sum is 6 or higher and then appends a list of those elements to new_stuff and goes on to find the next list.



Try a test list like:



import numpy as np
stuff = sorted(np.random.randint(0,10,100))





share|improve this answer























  • You might change while subsum<6 to while subsum<v?
    – Louie Lee
    Nov 19 at 21:53










  • Also, if I have stuff = [44,23,22,1] and v = 45, your code yields [[44, 23]] instead of [[44,1],[23,22]]
    – Louie Lee
    Nov 19 at 22:06












  • If stuff = [1,22,23,44] and v = 45, your code yields [[1, 22, 23]] instead of [[44,1],[23,22]]
    – Louie Lee
    Nov 19 at 22:09










  • Yes, you are right; this algorithm is too simple. Maybe I can come up with something better tomorrow
    – user8408080
    Nov 20 at 0:58













up vote
0
down vote










up vote
0
down vote









If you sort your list, this should get you the desired result, although it's not very beautiful as I have to admit:



stuff = range(10)
l = len(stuff)
v = 6

new_stuff =
i = 0
active = True

while active:
sub_stuff =
subsum = 0
while subsum<v:
if i>(l-1):
active = False
break
el = stuff[i]
sub_stuff.append(el)
subsum += el
i += 1
else:
new_stuff.append(sub_stuff)


It just goes through your list and sums element until their sum is 6 or higher and then appends a list of those elements to new_stuff and goes on to find the next list.



Try a test list like:



import numpy as np
stuff = sorted(np.random.randint(0,10,100))





share|improve this answer














If you sort your list, this should get you the desired result, although it's not very beautiful as I have to admit:



stuff = range(10)
l = len(stuff)
v = 6

new_stuff =
i = 0
active = True

while active:
sub_stuff =
subsum = 0
while subsum<v:
if i>(l-1):
active = False
break
el = stuff[i]
sub_stuff.append(el)
subsum += el
i += 1
else:
new_stuff.append(sub_stuff)


It just goes through your list and sums element until their sum is 6 or higher and then appends a list of those elements to new_stuff and goes on to find the next list.



Try a test list like:



import numpy as np
stuff = sorted(np.random.randint(0,10,100))






share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 20 at 0:58

























answered Nov 19 at 18:31









user8408080

1,070139




1,070139












  • You might change while subsum<6 to while subsum<v?
    – Louie Lee
    Nov 19 at 21:53










  • Also, if I have stuff = [44,23,22,1] and v = 45, your code yields [[44, 23]] instead of [[44,1],[23,22]]
    – Louie Lee
    Nov 19 at 22:06












  • If stuff = [1,22,23,44] and v = 45, your code yields [[1, 22, 23]] instead of [[44,1],[23,22]]
    – Louie Lee
    Nov 19 at 22:09










  • Yes, you are right; this algorithm is too simple. Maybe I can come up with something better tomorrow
    – user8408080
    Nov 20 at 0:58


















  • You might change while subsum<6 to while subsum<v?
    – Louie Lee
    Nov 19 at 21:53










  • Also, if I have stuff = [44,23,22,1] and v = 45, your code yields [[44, 23]] instead of [[44,1],[23,22]]
    – Louie Lee
    Nov 19 at 22:06












  • If stuff = [1,22,23,44] and v = 45, your code yields [[1, 22, 23]] instead of [[44,1],[23,22]]
    – Louie Lee
    Nov 19 at 22:09










  • Yes, you are right; this algorithm is too simple. Maybe I can come up with something better tomorrow
    – user8408080
    Nov 20 at 0:58
















You might change while subsum<6 to while subsum<v?
– Louie Lee
Nov 19 at 21:53




You might change while subsum<6 to while subsum<v?
– Louie Lee
Nov 19 at 21:53












Also, if I have stuff = [44,23,22,1] and v = 45, your code yields [[44, 23]] instead of [[44,1],[23,22]]
– Louie Lee
Nov 19 at 22:06






Also, if I have stuff = [44,23,22,1] and v = 45, your code yields [[44, 23]] instead of [[44,1],[23,22]]
– Louie Lee
Nov 19 at 22:06














If stuff = [1,22,23,44] and v = 45, your code yields [[1, 22, 23]] instead of [[44,1],[23,22]]
– Louie Lee
Nov 19 at 22:09




If stuff = [1,22,23,44] and v = 45, your code yields [[1, 22, 23]] instead of [[44,1],[23,22]]
– Louie Lee
Nov 19 at 22:09












Yes, you are right; this algorithm is too simple. Maybe I can come up with something better tomorrow
– user8408080
Nov 20 at 0:58




Yes, you are right; this algorithm is too simple. Maybe I can come up with something better tomorrow
– user8408080
Nov 20 at 0:58


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53380134%2fuse-python-to-solve-a-math-problem-sum-up-to-a-value-as-close-as-possible%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

If I really need a card on my start hand, how many mulligans make sense? [duplicate]

Alcedinidae

Can an atomic nucleus contain both particles and antiparticles? [duplicate]