here is an example algorithm for generating numbers whose sum is a specific integer. asking for the summands of an integer is a question with multiple solutions, and in this case a random number generator is used to find one possible solution. the relative distribution of summands is information that is lost in a sum.
to create a function that splits an integer n into count integers equal to or greater than min whose sum is n,
with the following signature:
integer_summands :: integer:n integer:count integer:min -> (integer ...)
and the following domain:
n = integer count >= 0 n >= (count * min)
count * min from n to get the remaining totalcount - 1 random numbers in the range 0 to the remaining totalmin to each to ensure the minimum value constraintn may be less likely to occur the higher count is. in tests with uniform distribution and n = 50, count = 4, min = 2, the maximum possible value 44 occurred only in about 1:30000 applications.integer_summands = (n, count, min) -> t = n - count * min return [] if t < 0 s = [0, t].concat((Math.floor(Math.random() * (t + 1)) for _ in [1...count])) s.sort (a, b) -> a - b s[i + 1] - s[i] + min for i in [0...count]
example usage
integer_summands 50, 4, 2
example results (results will vary because of the use of random)
[12, 2, 28, 8] [20, 5, 12, 13] [14, 16, 16, 4] [11, 21, 7, 11] [2, 13, 23, 12]
integer_summands_unique = (n, count, min) -> s = count * min + (count * (count - 1)) / 2 return [] if n < s t = n - s a = (Math.floor(x * t) for x in ([Math.random() for _ in [1...count-1]].sort())) a = (a[i] - (a[i-1] || 0) for i in [0...a.length]).concat [t - (a[a.length-1] || 0)] a = a.sort () -> Math.random() - 0.5 (min + i + a[i] for i in [0...count]).sort (a, b) -> a - b