Question: I'm trying to distribute Values over a specific number of Value Holders based on a Start and End value.

If the number of Value Holders is equal to the difference of the Start and End Values, it will just be a simple iteration:

```
Start Value  : 1
End Value    : 10
Value Holders: 10
|
Expected Result: 1 2 3 4 5 6 7 8 9 10

```

If the number of Value Holders is less than the difference of the Start and End Values, we need to skip some numbers. The goal is to try to distribute the values as evenly as possible.

NOTE: Leaning on either right/left is not important :)

```
Start Value  : 1
End Value    : 10
Value Holders: 5
|
Expected Result: 1 3 5 8 10
                 or
                 1 3 6 8 10

Start Value  : 1
End Value    : 10
Value Holders: 3
|
Expected Result: 1 5 10
                 or
                 1 6 10

```

If the number of Value Holders is more than the difference of the Start and End Values, we will be repeating some numbers.

```
Start Value  : 1
End Value    : 10
Value Holders: 15
|
Expected Result: 1 2 3 4 4 5 5 6 6 7 7 8 8 9 10
                 (or something similar)

```

How can I implement this in C#?

Answer: 
It is just another formulation of [arithmetic progression](https://en.wikipedia.org/wiki/Arithmetic_progression) with declared `a1` (start value), `N` (number of value holders) and `aN` (end value). 

From the formula of arithmetic progression:  

[![enter image description here](https://i.stack.imgur.com/ZpDw0.png)](https://i.stack.imgur.com/ZpDw0.png)

we can extract `d` since we know all other values. 

```
d = (aN - a1) / (N - 1)

```

When you know all values, you can simply generate the whole arithmetic progression sequence:

```
public int[] GetValues(int a, int b, int count)
{
    double d = (b - a) / (double)(count - 1);

    return Enumerable.Range(0, count)
       .Select(i => (int)Math.Round(a + d * i))
       .ToArray();
}

// Usage:
int[] r1 = GetValues(1, 10, 10); // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
int[] r2 = GetValues(1, 10, 5); // 1, 3, 6, 8, 10
int[] r3 = GetValues(1, 10, 15); // 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10

```

You can remove `(int)Math.Round()` to see intermediate results as double.
Treat the start and end points as "anchors" - these will always make up the first and last elements in the distributed sequence. Then take the range between them (`end-start`) and divide it into the number of "spaces" between the numbers (`holders - 1`). The resulting `step` value is the amount to add between successive elements in the distributed sequence.

```
static List<int> Distribute(int start, int end, int holders)
{
    List<int> result = new List<int>();

    // First value will always be the start
    result.Add(start);

    // Calculate the step size for the middle values
    double range = end - start;
    double step = range / (holders - 1);

    // Generate the middle values using the step spacing
    for (int i = 1; i < holders - 1; i++)
    {
        double target = step * i + start;
        result.Add((int)Math.Round(target));
    }

    // Last value is the end
    result.Add(end);
    return result;
}

```

The method of rounding controls how the sequence "leans." Using `Math.Round` will make the sequence symmetrical around the center of the range. `Math.Ceiling` will cause the sequence to lean right, and `Math.Floor` will cause the sequence to lean left.