Reputation: 83677
I want to get 4 unique random floating point numbers in the range <0;9>. How could I do that. Is it possible to do this with a single function so I don't need to generate random numbers in a loop?
Upvotes: 5
Views: 11385
Reputation: 6986
Why not do:
Enumerable.Range(0, 9)
.OrderBy(x => Guid.NewGuid().GetHashCode())
.Take(4)
.ToArray();
Upvotes: 0
Reputation: 1013
This is what I use to get distinct random numbers in a given range:
var random = new Random();
int take = 4;
int rangeMin = 0;
int rangeMax = 10;
var randomUniqueNumbers = Enumerable.Range(0, int.MaxValue)
.Select(i => random.Next(rangeMin, rangeMax))
.Distinct()
.Take(Math.Min(take, rangeMax - rangeMin));
It would be nicer with an Infinite enumeration insted of Enumerable.Range(0, int.MaxValue), but this does the job.
Upvotes: 2
Reputation: 50110
I am sorry but I could not resist
In that spirit you can do
r1=2.7;
r2=6.9;
r3=4.2;
r4=8.1;
I swear they are random
Upvotes: 6
Reputation: 16500
so I don't need to generate random numbers in a loop?
Since your range is so limited, you can generate a number in [0, 9999] and use decimal digit extraction. This will likely improve performance, but only very slightly. Personally, I would just use a loop.
int fourDigit = m_Random.Next(10000);
int first = fourDigit % 10; fourDigit /= 10;
int second = fourDigit % 10; fourDigit /= 10;
int third = fourDigit % 10; fourDigit /= 10;
int fourth = fourDigit;
The original poster has clarified that the numbers are to be distinct. This practically necessitates a loop at least somewhere in the code. However, I do not think it requires multiple calls to Random
, by adapting the above.
NOTE: I am not sure if this incrementing technique is free of bias, if someone familiar with the mathematics behind random numbers would be so kind to analyze. Thanks.
int fourDigit = m_Random.Next(10000);
int first = fourDigit % 10; fourDigit /= 10;
int second = fourDigit % 10; while (second == first) second = (second + 1) % 10; fourDigit /= 10;
int third = fourDigit % 10; while (third == first || third == second) third = (third + 1) % 10; fourDigit /= 10;
int fourth = fourDigit; while (fourth == first || fourth == second || fourth == third) fourth = (fourth + 1) % 10;
Upvotes: 2
Reputation: 269288
var rng = new Random();
int first = rng.Next(10);
int second = rng.Next(10);
int third = rng.Next(10);
int fourth = rng.Next(10);
If you need four distinct values then you can do something like this...
var rng = new Random();
var values = Enumerable.Range(0, 10).OrderBy(x => rng.Next()).ToArray();
int first = values[0];
int second = values[1];
int third = values[2];
int fourth = values[3];
Note that if you needed to generate many numbers then a proper shuffle implementation will give better performance than OrderBy
: O(n) rather than O(n log n). If you only need a handful of numbers then OrderBy
will be fine.
Upvotes: 16