Tharres
Tharres

Reputation: 113

Generating random number between two numbers and ignoring numbers from the set

I am looking to generate a random number between two 2 digit numbers and if the random number is one of the numbers from the set, then ignore this number and re-randomize it. I am facing issue with the looping part. That is, if the number from the list is found twice, it would not loop again. How do I achieve this?

public float[] nums_to_ignore = new float[] {64.0f, 80.0f, 90.0f, 92.0f, 85.0f, 73.0f, 86.0f};
public float random_num;

void Start()
{
  random_num = Random.Range(60.0f, 95.0f);
  for(int i = 0; i<nums_to_ignore.Length;i++)
  {
    if(random_num == nums_to_ignore[i])
    {
      random_num = Random.Range(60.0f, 95.0f); //Keep looping till you get a number not from the list
    }
  }
}

Upvotes: 1

Views: 81

Answers (2)

Johnathan Barclay
Johnathan Barclay

Reputation: 20363

It would be more efficient to use a HashSet<float> for your numbers to ignore, as HashSet<T>.Contains has O(1) complexity.

You can continue to repeat your random generation using a do..while loop:

public HashSet<float> nums_to_ignore
   = new HashSet<float> { 64.0f, 80.0f, 90.0f, 92.0f, 85.0f, 73.0f, 86.0f };
public float random_num;

void Start()
{
    do random_num = Random.Range(60.0f, 95.0f);
    while (nums_to_ignore.Contains(random_num));
}

The above would still work if you keep nums_to_ignore as a float[], but Enumerable.Contains has O(n) complexity.


Update

As pointed out by @derHugo, float values are approximations, and equality comparisons may yield incorrect results.

Fortunately, Unity has a method that is designed for comparing floats in this way: Mathf.Approximately:

void Start()
{
    do random_num = Random.Range(60.0f, 95.0f);
    while (nums_to_ignore.Any(n => Mathf.Approximately(n, random_num)));
}

Unfortunately, this means that GetHashCode cannot be used reliably with float, and the benefits of hashing cannot be achieved.

Upvotes: 4

Max Arnold
Max Arnold

Reputation: 1

id go about it like this

Random random = new Random();
List<int> numbers = new List<int>();
int min = 60, max = 95;

for (int i = 0; i <= 100; i++) 
{
   int num;
   do
     num = random.Next(min,max);
   while (numbers.Contains(num));
   numbers.Add(num);
}

you can replace random.next by unitys Random.Range, i was sleeping on you using unity. the for i 0 to 100 loop was just there as an example how to fill the list you can easily replace it with a methode instead

Upvotes: -1

Related Questions