Filling an array with numbers limited to a sum of one number

I wish to create an array that is filled with numbers that all add up to one number. So in this code I have written, I am trying to limit the number that the array can add up to to 35 or 105.

var all_stats : int[];
var max_stat_number : int = 34;
var max_stat_number_special : int = 104;
var picked_stat_number : int;
var normal_check : int;
var stats_normal : boolean;

function Start () {

all_stats = new int[7];

}

function Update () {



}

function OnGUI () {

	if(GUI.Button(new Rect((Screen.width / 2) - 50, (Screen.height / 2) - 50, 100, 100), "Calculate Normal Stats"))
	{
	CalcNormal();
	}

}

function CalcNormal () {

	for(var stat : int; stat < all_stats.length; stat++)
	{
		if(max_stat_number > 1)
		{
		picked_stat_number = Random.Range(1,max_stat_number);
		max_stat_number -= picked_stat_number;
		all_stats[stat] = picked_stat_number;
		}
		else
		{
		all_stats[stat] = 1;
		}
	}
	max_stat_number = 34;
	EnsureAllUsed();


}

function EnsureAllUsed () {
	normal_check = 0;
	for(var stat_check : int; stat_check < all_stats.length; stat_check++)
	{
		normal_check += all_stats[stat_check];
	}
	if(normal_check < 35)
	{
	max_stat_number = 35 - normal_check;
	normal_check = 0;
	CalcNormal();
	}
	else
	{
	stats_normal = true;
	}

}

The problem is that it always goes over or under, and it will eventually produce this error if clicked on more than a few times:

StackOverflowException
UnityEngine.Random.Range (Int32 min, Int32 max) (at C:/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineRandom.gen.cs:30)

I know there’s something I’m missing here, I just can’t comprehend what it is.

The Stack overflow happens when your initial numbers are small and even filled array is not adding up to required value, than it enters into kind of recursive loop between CalcNormal and EnsureAllUsed;

I am sure that you can find an algorithm for your problem on google, thus I am not gonna write a full code, One thing you missed there is to make sure, that next element will not add to the result sum directly when its not being written into final cell of the array (i.e. your array look like (30,4,1,x,x,x,x) so after three elements sum is meet: You either reserve at least 1 for each remaining free cell ( something like picked_stat_number = Random.Range(1,max_stat_number-all_stats.length-stat (check here by 1 error)), or apply some sort of distribution for the max random for next element so you not gonna have too big numbers at the start.

Another thing you need to make sure is to fill the last cell with the requested value minus current sum, so the results works; Unless you want your program to try looping until will generate all values randomly *which in your case produces stack overflow.

Try with smaller array i.e. 2 or 3 and try to comprehend and take care of all of the possible cases: than scale it to 7 or whatever size you need;

This is a classic problem in college combinatorics. Like, in the book. Suppose you want 6 numbers that sum to 30. To solve, imagine you have 5 identical backs balls used as dividers, and 30 identical white balls that stand for the numbers. Arrange them all in a line, any way. The 5 black balls divide the 30 white balls into 6 groups.

So the solution is to pick one of (SUM choose (GROUPS-1)). In other words, pick 5 different random numbers out of 35. Sort them. Those are the black divider balls. Count each group of white balls that makes. Suppose you picked 4,5,15,18 and 33. Count the “white balls” in each division: 3, 0 (0 balls between slot 4 and 5) 2, 19 and 2 (white balls in slot 34 and 35.)

If there’s a minimum, subtract it from the sum for each group, then add back at the end (if each # must be 2 or more, subtract 12 from the sum.) If there’s a maximum … hmmm … not sure. That trick may not work.

It does work (I use this method,) and is short and fast. But it’s pretty much if you know what (12 choose 5) means, it’s totally obvious how to use this trick. If not … it may be too much like magic to be worth trying.

Oh, also nothing to do with Unity. Just saying.