How to get a random number from a range, excluding some values
you can use a do-while statement to pick another Random if it equals what number you want to exclude. this code is to exclude the number you picked before
int newNumber;
do {
newNumber = Random.Range (0, 100);
} while(number == newNumber);
number = newNumber;
Since no-one has posted any example code:
private int GiveMeANumber()
{
var exclude = new HashSet<int>() { 5, 7, 17, 23 };
var range = Enumerable.Range(1, 100).Where(i => !exclude.Contains(i));
var rand = new System.Random();
int index = rand.Next(0, 100 - exclude.Count);
return range.ElementAt(index);
}
Here's the thinking:
- Build a Hashset of numbers you want to exclude
- Create a collection of all the numbers 0-100 which aren't in your list of numbers to exclude with a bit of LINQ.
- Create a random object.
- Use the Random object to give you a number between 0 and the number of elements in your range of numbers (inclusive).
- Return the number at that index.
This is what I do in this situation, it's not perfect but works well for me. I usually do it only for 1 number but this is how it can be for a group of excluded numbers:
Let's say I want to exclude [5, 7, 17, 23] from a random between 1-100. I always have a substitution for each of the excluded numbers such as [6, 8, 18, 24]. If the random number falls into any of the excluded numbers, I replace it with its substitution.
I came here looking for a better solution but I couldn't find any so I ended up sharing mine.
If you care about Big O, check out this algorithm. It assumes that the excluded values array is sorted in ascending order and contains values within 0
and n-1
range (inclusive).
public static int random_except_list(int n, int[] x)
{
Random r = new Random();
int result = r.Next(n - x.Length);
for (int i = 0; i < x.Length; i++)
{
if (result < x[i])
return result;
result++;
}
return result;
}
If you call it with:
random_except_list(8, new int[]{3,4,6})
it will return one of the following values: 0
, 1
, 2
, 5
, 7
.