Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Distribute Values Based on a Start and End Value and Number of Value Holders

Tags:

c#

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#?

like image 996
Floating Sunfish Avatar asked Apr 06 '17 03:04

Floating Sunfish


1 Answers

It is just another formulation of 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

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.

like image 57
Yeldar Kurmangaliyev Avatar answered Sep 18 '22 23:09

Yeldar Kurmangaliyev