Question

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?

Was it helpful?

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;
        }
    }
}

OTHER TIPS

You have hopelessly too many variables, overcomplicating the problem. Beyond the counter and the number, you only need one additional variable to keep track of the closest smaller number.

Below is some code I wrote which has essentially the same idea, it just seems a bit simpler.

int[] roulette = {0, 21, 29, 0, 0, 50};
int closest = -1;
int number = 54;
for (int j = 0; j < roulette.Length; j++)
   // if the values isn't 0 and it's smaller
   // and we haven't found a smaller one yet, or this one's closer
   if (roulette[j] != 0 && roulette[j] < number &&
       (closest == -1 || roulette[j] > roulette[closest]))
   {
      closest = j;
   }

if (closest == -1) // no smaller number found
   Console.WriteLine(0);
else
   Console.WriteLine(roulette[closest]);

Live demo.

For repeated queries, it would be better to sort the numbers, then do a binary search to find the correct position.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top