Search code examples
c#algorithmroulette-wheel-selection

Flat Roulette with random number: get interval where random belongs to


For example i have and array with such elements:

0 21 29 0 0 50

let's "flat" this numbers:

enter image description here

let's say my random number is 54, so my number belongs to the last element in my array with index 6 (it's 50)

i can't understand, how to algorytmize that... with c#

i try:

  Random random = new Random();
            int randomNumber = random.Next(1, 100);
            int temp, temp_ind;
            float a_, b_;
            for (j = 0; j < n-1; j++)
            {
                if (roulette[j] != 0)
                {
                    temp_ind = j+1;
                    a_ = roulette[j];
                    while ((roulette[temp_ind] == 0.0) && (temp_ind < n-1))
                    {
                        temp_ind++;
                    }
                    b_ = roulette[temp_ind];
                    if ((a_ <= randomNumber) && (b_ >= randomNumber))
                    {
                        start = j;
                        break;
                    }
                }
            }

but this doesn't work, maybe something could help me?


Solution

  • Here's a solution which converts the array to a cumulative array (using an extension method from this answer by Eric Lippert), then finds the index of the first match in that array which is higher than the random number.

    class Program
    {
        static void Main(string[] args)
        {
            var random = new Random();
            int[] roulette = { 0, 21, 29, 0, 50 };
    
            var cumulated = roulette.CumulativeSum().Select((i, index) => new { i, index });
            var randomNumber = random.Next(0, 100);
            var matchIndex = cumulated.First(j => j.i > randomNumber).index;
    
            Console.WriteLine(roulette[matchIndex]);
        }
    }
    
    public static class SumExtensions
    {
        public static IEnumerable<int> CumulativeSum(this IEnumerable<int> sequence)
        {
            int sum = 0;
            foreach (var item in sequence)
            {
                sum += item;
                yield return sum;
            }
        }
    }