$\begingroup$

Your question mention an inefficient algorithm generating four independent and uniformly distributed numbers among the integers from 0 to 100 and repeating until their sum is 100. I'll assume you are satisfied with the distribution generated by that algorithm, but you are not satisfied with the performance.

Before looking into how to produce the distribution more efficiently, one first has to understand what the distribution looks like.

By construction it is easy to see that each of $a$, $b$, $c$, and $d$ are identically distributed. It is also easy to see that they are not independent due to their sum being constant. What we already know about their distribution is that it has minimum value 0, maximum value 100, and average value 25. The average follows from the fact that their sum has to be 100 on average.

This rules out a uniform distribution of the individual numbers (and in fact it rules out every symmetrical distribution). This means your more efficient algorithm, which generates $a$ uniformly will produce a different distribution.

Towards an efficient algorithm

If we define $X = a+b$ and ask what the distribution of $X$ looks like, we will find something interesting. The distribution clearly doesn't depend on which pair of the four numbers we summed. So all six possible pairs are identically distributed, but not independent. This distribution has minimum 0, maximum 100, and average 50. And the distribution has to be symmetrical because $X$ and $100-X$ are identically distributed.

It is not immediately obvious if the distribution of $X$ is uniform across the integers form 0 to 100. However if the distribution of $X$ can be generated efficiently, then the distribution of all four numbers can be generated efficiently as follows:

Generate $X$

Choose $a$ uniformly random in the range $0$ to $X$

Let $b := X-a$

Choose $c$ uniformly random in the range $0$ to $100-X$

Let $d := 100-X-b$

The distribution of X

The original algorithm would produce $X$ as the sum of two uniformly random numbers in the range $0$ to $100$, but discard any results where the overall sum was different form $100$.

A different algorithm could generate $X$ and $Y$ according to this distribution and discard the result if $X+Y

eq 100$. This is useful because the generation of $X$ and $Y$ can be simplified.

If $X$ is larger than 100 it can be discarded immediately. We easily analyze what the new distribution before we verify the sum of $X$ and $Y$ will be. The initial probability of an outcome $x \in [0;100]$ would be $\frac{1+x}{10000}$, but when we discard values larger than 100, the probability will be $\frac{1+x}{5050}$.

The probability of immediately generating $X=x$ and $Y=100-x$ can then be computed as $\frac{1+x}{5050} \cdot \frac{1+(100-x)}{5050} = \frac{(1+x)(101-x)}{5050^2}$ The probability of $P(X=x \wedge Y=100-x)$ can then be computed by simply scaling the denominator such that the sum will be $1$

At this point it is clear that $X$ isn't uniformly distributed. But it also gives us a way to construct $X$ directly.

In order to generate the distribution of $X$ directly, we need a formula for $P(X \leq x)$. This formula will be:

$$P(X \leq x) = \frac{\Sigma_{i=0}^x (1+x)(101-x)}k = \frac{-2x^3 + 297x^2 + 905x + 606}{6k}$$

Because we know that $P(X \leq 100) = 1$, we can deduce that $k=176851$.

With this the algorithm becomes: