问题是,例如,我需要生成总共N个数字才能获得总和0。如果N = 4,则应生成[1、0,-3、2]或[-2、1,-4、5]。
到目前为止,这是我的代码,它生成一个随机的int,其总和为N的值,并且它是列表中值的随机总数。
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))
答案 0 :(得分:2)
您可以使用5
,然后简单地将最后一个值设为前三个值之和的负值:
random.sample
例如,它将输出:
import random
N=4
l = random.sample(range(-10, 10), k=3)
print(l + [-sum(l)])
哪个:
[-5, 1, -8, 12]
礼物:
print(sum([-5, 1, -8, 12]))
答案 1 :(得分:1)
这不能完全确保最终数字是唯一的,但是它不太可能已经存在于列表中。
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
以上解决方案不能确保唯一性的事实困扰着我。这是应确保唯一性的增强版本:
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
答案 2 :(得分:1)
解决此问题的一种选择是递归。我们可以从低到高的范围生成列表的第一个值,将其添加到列表中,然后通过函数进行返回,但是现在只有有限的选项(由于唯一性),直到我们到达一个点为止剩下。到那时,我们要么成功找到列表,要么失败了,以前的递归级别将在可能起作用的较早索引处搜索其他值。另一种可能性是没有可能的列表(例如,从低到高均为正,选项在最后一个点之前用完),在这种情况下,我们的函数将返回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)
答案 3 :(得分:1)
最简单的解决方案是将 1, 2, 3 ... N-1 包含在数组中,数组的最后一个元素是前面元素的总和乘以 -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));
它们不是随机的,但至少是唯一的 ;) 并且解决方案很快。
答案 4 :(得分:0)
def solution(N):
l = random.sample(range(-10, 10), k=(N-1))
return (l + [-sum(l)])
试试这个。