In C, how do I get an array of n numbers (each 0x00-0xFF in my case), of which the sum is within a given range 0..k?
The almost duplicate C++ multiple random numbers adding up to equal a certain number targets a specific sum, but in my case the sum can be anything between 0..k.
You need to specify what is the desired distribution of the random numbers.
If there are no further requirements, I would suggest one of the following:
(1)
If you have upper limit m on the range of the random number, use min(k-a[1]-... m) as upper bound of the interval.
Disadvantages: you will get a lot of small numbers and just a few big ones.
(2)
Disadvantages: It is unlikely to get large numbers this way. If integers are required, there will likely be a gap between the sum of numbers and k due to rounding error.
I think you get "nicer" numbers with option (2) but as stated above, it depends on the requirements.
Assuming k is less than 255 * n one solution is to assign k / n to every element of the array, then randomly subtract a value to the array elements.
// for (int i = 0; i < n; i++) array[i] = k / n;
// for (int i = 0; i < n; i++) array[i] -= randbetween(0, array[i]);
for (int i = 0; i < n; i++) array[i] = randbetween(0, k / n);
This has an expected sum of k / 2. By tweaking the randbetween() function you can change the probability of the resulting array sum.
It is easy to create one number within range [0, 255].
It is easy to identify if k > 255*n or k < 0 there is no solution.
If 0 <= k <= 255*n, the solution exists. Here we only talk about n > 1 condition.
You have created n-1 random numbers, and sum of the n-1 numbers is s1, suppose the nth number is x. So s1 + x = k, and x should be [0, 255]. If the n-1 numbers are all within range [0, a], then (n-1)*a + 255 >= k, we get a >= (k-255)/(n-1).
If k > 255, just let a = (k-255)/(n-1). It means s1 is [0, k-255]. Then the nth number x can be any random number within [0, 255].
So the solution is arbitrary select n-1 numbers each within [0, (k-255)/(n-1)] (you know (k-255)/(n-1) <= 255, thus it satisfied your condition), and select one random number within [0, 255].
If k <= 255, arbitrary select n numbers each within [0, k/n] (you know k/n is within [0, 255]).