Problem is that I need to generate a total of N numbers to be able to get the sum of 0. for example. if N=4 it should generate [1, 0, −3, 2] or [−2, 1, −4, 5].
Here's my code so far, it generates random int that sums to the value of N though, and it's random total number of values in the list.
from random import randint
def solution(N):
values = []
while 1 <= N <= 100:
value = randint(1, N)
values.append(value)
N = N - value
return values
print(solution(3))
You can use random.sample
, then simply get the last value to be the negative value of the sum of the first three values:
import random
N=4
l = random.sample(range(-10, 10), k=3)
print(l + [-sum(l)])
For example it will output:
[-5, 1, -8, 12]
Which:
print(sum([-5, 1, -8, 12]))
Gives:
0
This doesn't completely ensure the final number is unique, but it is rather unlikely that it will already exist in the list.
def gen_unique_zero_sum_list(num_members):
ret = []
for i in range(int(num_members) - 1):
candidate = random.randint(-100, 100)
while candidate in ret:
candidate = random.randint(-100, 100)
ret.append(candidate)
ret.append(-sum(ret))
return ret
The fact that the above solution did not ensure uniqueness bugged me. Here's an enhanced version that should ensure uniqueness:
def gen_unique_zero_sum_list(num_members, min=-100, max=100):
if int(num_members) < 1:
raise ValueError
ret = []
# populate as many as we can randomly
for i in range(0, int(num_members) - 2, 1):
candidate = random.randint(min, max)
while candidate in ret:
candidate = random.randint(min, max)
ret.append(candidate)
if int(num_members) > 1:
while len(ret) < int(num_members):
# at this point we could get a forced duplicate
candidate = random.randint(min, max)
while candidate in ret:
candidate = random.randint(min, max)
final = -(sum(ret) + candidate)
if final in ret or final == candidate:
# we would have a duplicate, force two new numbers
continue
ret.append(candidate)
ret.append(final)
else:
# this will always be zero, by definition
ret.append(-sum(ret))
return ret
An option in solving this problem is recursion. We can generate our first value of our list from the range from low to high, add it to the list, go back through the function but now with limited options (due to uniqueness) until we get to the point where there is only one spot left. At that point either we have succeeded in finding a list or we have failed and the previous levels of recursion will search for other values at earlier indices that may work. Another possibility is that there are no possible lists (eg low to high are both positive, options run out before last spot) in which case our function will return None.
import random
def foo(n, low, high):
"""Helper function for recursive function"""
def rbar(arr):
"""Recursive function to create a 'random' list of n integers
between low and high (exclusive) such that the sum of the list is 0
and the entries of the list are unique."""
# if one spot left check if -sum(arr) in arr
if len(arr) == n-1:
if -sum(arr) not in arr and -sum(arr) in range(low, high):
return arr + [-sum(arr)]
# if more than one spot then generate the next possible values
# and try to get to a full list of size n with those
else:
# loop through shuffled options (randomness here)
options = [x for x in range(low, high) if x not in arr]
for opt in random.sample(options, len(options)):
# if recursively going through function produces a list then return it
if rbar(arr + [opt]) is not None:
return rbar(arr + [opt])
# if nothing worked then return None
return
if n==0:
return []
elif n==1 and 0 in range(low, high):
return [0]
elif n==1 and 0 not in range(low, high):
return None
else:
return rbar([])
k = foo(4, -10, 10)
if k is not None:
print("List: {}, Sum:{}".format(k, sum(k)))
else:
print(None)
The simplest solution to this would be to include in the array 1, 2, 3 ... N-1 and the final element of the array is the sum of the previous elements multiplied by -1:
function findSet(N) { var sum = 0; var r = []; if (N === 1) { r[0] = 0; } else { for (var i = 1; i < N; i++) { r[i - 1] = i; sum += i; } r[N - 1] = -sum; } return r; } function printArray(a) { console.log('[' + a.join(',') + ']'); } printArray(findSet(1)); printArray(findSet(2)); printArray(findSet(3)); printArray(findSet(4)); printArray(findSet(5));
They are not random, but at least unique ;) and the solution is fast.
def solution(N):
l = random.sample(range(-10, 10), k=(N-1))
return (l + [-sum(l)])
Try this.
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.