Richard Knop
Richard Knop

Reputation: 83677

How to get 4 unique random numbers in range <0;9>?

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

Answers (5)

MaYaN
MaYaN

Reputation: 6986

Why not do:

    Enumerable.Range(0, 9)
              .OrderBy(x => Guid.NewGuid().GetHashCode())
              .Take(4)
              .ToArray();

Upvotes: 0

marcob
marcob

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

pm100
pm100

Reputation: 50110

I am sorry but I could not resist

http://xkcd.com/221/

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

Jason Kresowaty
Jason Kresowaty

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

LukeH
LukeH

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

Related Questions