# Random class • ### Question

• Can someone please help me with code for a random class that must select a number between 1 and 600 and the number should never be repeated.

Thank you.

Thursday, May 9, 2013 2:24 PM

• This is working for me

int num = myrandom.Next(1, 60);
while (count != 0)
{
if (!mylist.Contains(num))
{
count--;
getnumbers();
}
else
{
getnumbers();
}
}

• Marked as answer by Friday, May 10, 2013 8:30 AM
Friday, May 10, 2013 8:30 AM

### All replies

• It's very easy:

``` Random r = new Random();
r.Next(1, 600);```

Regards,
Bubu
http://zsvipullo.blogspot.it

Please mark my answer if it helped you, I would greatly appreciate it.

Thursday, May 9, 2013 2:29 PM
• Random m = new Random(600);

List<int> ls = new List<int>();

// example

int d = m.Next();

if ( ls.Contains(d) )  { d = m.Next(); ls.Add(d); } ; else { ls.Add(d); }

or

int d = ls.Contains(m.Next()) ? m.Next() : m;

• Edited by Thursday, May 9, 2013 2:37 PM
Thursday, May 9, 2013 2:30 PM
• Try this:

```class MyRandom
{
private List<int> numbers = new List<int>();
private Random random;
public void Initialize(int min, int max)
{	numbers.Clear();
random = new Random();
for (var i = min; i <= max; i++)
{
}
}

public int GetNext()
{
var index = random.Next(0, numbers.Count);
var result = numbers[index];
numbers.RemoveAt(index);
return result;
}
}

//USAGE
MyRandom rand = new MyRandom();
rand.Initialize(1,600);
Console.WriteLine(rand.GetNext());```

• Edited by Thursday, May 9, 2013 2:37 PM Added numbers.Clear() so class is reusable without a relaunch of application
• Proposed as answer by Thursday, May 9, 2013 2:39 PM
Thursday, May 9, 2013 2:34 PM
• Here you go:

```    class RandomNumber
{
List<int> usedNumbers = new List<int>();
Random rnd = new Random();

public int Next()
{
bool _usedNumber = false;
int newNumber;
do
{
newNumber = rnd.Next(1, 601);
if(usedNumbers.Contains(newNumber))		{			_usedNumber = true;			usedNumbers.Add(_usedNumber);		}

else
_usedNumber = false;
} while (_usedNumber);

return newNumber;
}
}```

To use the class:

```RandomNumber rn = new RandomNumber();
int newNumber = rn.Next();```

Noam B.

• Edited by Thursday, May 9, 2013 2:39 PM
Thursday, May 9, 2013 2:36 PM
• use Random Class

```Random random = new Random();
return random.Next(1, 1000); ```

Regards

Mohit

Thursday, May 9, 2013 2:38 PM
• You can do it like:

```        Random r;
public Form1()  //constructor of class
{
r = new Random();
int num1 = r.Next(1, 601); //1st option
int num2 = GetRandomNumber(); //2nd option
}

private int GetRandomNumber()
{
return r.Next(1, 601);
}```

Mitja

Thursday, May 9, 2013 2:38 PM
• Sergio - that would work, except it would have the chance of repeating numbers, which is what he was trying to avoid.
Thursday, May 9, 2013 2:41 PM
• I wouldn't use a used numbers list - the more numbers you use, the longer the method will take to return, growing exponentially.
Thursday, May 9, 2013 2:43 PM
• Almost but quite. Suppose the list contains 10 and 22 and Next returns 10. The if will be true so it does Next again. If that returns 22 it adds it again. Need something like:

int d = m.Next();
while ( ls.Contains(d) )  { d = m.Next(); }

Regards David R
---------------------------------------------------------------
The great thing about Object Oriented code is that it can make small, simple problems look like large, complex ones.
Object-oriented programming offers a sustainable way to write spaghetti code. - Paul Graham.
Every program eventually becomes rococo, and then rubble. - Alan Perlis
The only valid measurement of code quality: WTFs/minute.

Thursday, May 9, 2013 2:56 PM
• Contains is o(n) so won't grow exponentially. At least according to help. :)

Regards David R
---------------------------------------------------------------
The great thing about Object Oriented code is that it can make small, simple problems look like large, complex ones.
Object-oriented programming offers a sustainable way to write spaghetti code. - Paul Graham.
Every program eventually becomes rococo, and then rubble. - Alan Perlis
The only valid measurement of code quality: WTFs/minute.

Thursday, May 9, 2013 3:01 PM
• Contains is o(n) so won't grow exponentially. At least according to help.

But you're not calling "Contains" just once.  In fact, since it's possible to keep generating numbers that have already been generated every single time, this approach is O(infinity).  It's possible to literally *never* have it complete.  (Technically this isn't true since "Random" isn't actually random, it does repeat, it just takes a LONG time to do so, so it's not technically O(infinity) unless you get a better random number generator.)

The approach of keeping track of the numbers you have already generated and then generating a new one if you've already given out that one is appropriate with the total number of random numbers that you need is much less than the range of numbers you're generating between.  It's a *terrible* algorithm to use in the event that you'll eventually want every single value in the range.

Consider the example that you want non-repeating random numbers in the range of 1 to 1,000,000, and you keep asking for more until you've gotten all one million of them.  Consider what it will take to get the very last number alone.  You have a 1 in 1 million chance of choosing the right one.  If you don't, you'll try again, and again, and again, until you generate the one remaining "valid" value.  On top of that, the "contains" check in your list is O(n), as it's doing a linear search, so you're doing a linear search of a list with 999,999 items every time you guess wrong.  It will take you, on average, one million runs to get that last value, so it will end up costing O(1,000,000n) just for that last value.  Then on top of that you need to get the other 999,999 values that proceeded it.  Very, very expensive.

If you want to be getting a very large percentage of all of the items in the range, and especially if you want all of the items in the range, it's important to use shuffling instead.  The idea is you take a collection that contains every single value in the range and shuffle them into a random order.  There are quite a few effective algorithms for doing this quickly and easily.  It can be done in O(n) time.  See the wikipedia article on the subject to see this algorithm.

Thursday, May 9, 2013 3:30 PM
• The approach of keeping track of the numbers you have already generated and then generating a new one if you've already given out that one is appropriate with the total number of random numbers that you need is much less than the range of numbers you're generating between.

As it is in this case - unless the MS PRNG is so poor that the period is so small that 600 is a relatively large compared to the range.

I suspect that in the OP's case the performance is of o(n) but that would require either some maths or simulation to confirm. :) It would also depend on how many of the 600 is needed. If it is e.g. only 5 out of 600 with no repeats, then that would be different to getting 550 out of 600 with no repeats.

Regards David R
---------------------------------------------------------------
The great thing about Object Oriented code is that it can make small, simple problems look like large, complex ones.
Object-oriented programming offers a sustainable way to write spaghetti code. - Paul Graham.
Every program eventually becomes rococo, and then rubble. - Alan Perlis
The only valid measurement of code quality: WTFs/minute.

Thursday, May 9, 2013 4:51 PM
• Can someone please help me with code for a random class that must select a number between 1 and 600 and the number should never be repeated.

Thank you.

Such an operation is not actually random. A truly random process has an equal probability for any value being produced. By definition once you generate 238 (say) it has a zero probability thereafter.

Also as you "pick" values from the set its size will effectively reduce and so each number you pick "next" will have a greater probability of being picked.

Imagine you'd picked 599 values except 238 then the probability of 238 being picked next is 1 - that's not random.

Of course you may not care - but I just wanted to stress that such a technique isn't really random in the true sense and relying upon it might cause unexpected effects.

Cap'n

Thursday, May 9, 2013 9:17 PM
• It sounds like what you want to do is shuffle the numbers from 1 to 600.  The basic idea is to have a setup stage when you do the shuffling and then a selection stage where you return each of the numbers.

In the setup stage you would put the numbers from 1 to 600 in an array (or list or whatever works best for you) in numeric order, a simple loop.  Then for each element of the array, swap it with a randomly selected element.  Your array has now been shuffled.  Set the currentElement index to zero.

Selection stage.  When a request is made for the next number you return the array element at currentElement and increment.  You will need to make a decision about what to do if currentElement is pointing beyond the end of the array, eg what do you want to happen if the caller asks for more than 600 numbers?  You could throw an exception, return an error code, start again from the beginning of the same shuffled array or create a completely new shuffled array and start returning the elements from it.

Start writing code based on the above outline and let us know if you have any specific problems.

Paul Linton

Friday, May 10, 2013 12:56 AM
• This is working for me

int num = myrandom.Next(1, 60);
while (count != 0)
{
if (!mylist.Contains(num))
{
count--;
getnumbers();
}
else
{
getnumbers();
}
}

• Marked as answer by Friday, May 10, 2013 8:30 AM
Friday, May 10, 2013 8:30 AM
• In the setup stage you would put the numbers from 1 to 600 in an array (or list or whatever works best for you) in numeric order, a simple loop.  Then for each element of the array, swap it with a randomly selected element.  Your array has now been shuffled.  Set the currentElement index to zero.

That's not a valid algorithm for shuffling an array.  See this article for several valid algorithms.
Friday, May 10, 2013 3:09 PM
• Sounds suspiciously like Knuth's Algorithm P from the article. I.e:

To shuffle an array a of n elements (indices 0..n-1):
for i from n − 1 downto 1 do
j ← random integer with 0 ≤ j ≤ i
exchange a[j] and a[i]

Regards David R
---------------------------------------------------------------
The great thing about Object Oriented code is that it can make small, simple problems look like large, complex ones.
Object-oriented programming offers a sustainable way to write spaghetti code. - Paul Graham.
Every program eventually becomes rococo, and then rubble. - Alan Perlis
The only valid measurement of code quality: WTFs/minute.

Friday, May 10, 2013 3:28 PM
• @Riced, yes, it is similar, but there's a very key difference.  Paul suggested swapping each item with any random index.  That algorithm separates the array into a "shuffled" and "unshuffled" section and take a "random" item from the unshuffled section and moves it (through swapping) to the shuffled section.  Essentially the key difference is the "for" starting from the top and going down, and then selecting an index from below the "current index".  Those differences are small in code, but they have a *huge* impact on the validity of the results.
Friday, May 10, 2013 3:53 PM
• What is specifically wrong with my method?

Will it take longer to compile because ive never really focused on performance in code.

This was my source for my code:

http://www.functionx.com/csharp1/topics/randomnumbers.htm

• Edited by Monday, May 13, 2013 6:57 AM
Monday, May 13, 2013 6:55 AM
• What is specifically wrong with my method?

As you have written the code it seems to generate a single number between 1 and 59 and then adds that number to a List.  Then it enters an infinite loop as the value of num never changes.

If you fix that problem by using some global variables then you still have the problem that if count is > 600 you have an infinite loop.  (Also ignoring the case where count is initialized to a negative value)

If you fix that problem by not setting count to a number which is too big then you have the problem that each time around the loop will take longer and longer as more and more numbers are generated which are already present in the list.

If you solve the first two problems and the inefficiency is OK for you (and it probably is, given the size of numbers you are talking about) then your code will solve your problem.

(Note that if you want to generate a different size list of numbers in the future - say 1 - 10000 then you need to be very careful to change all the parts of the code that are effected by that requirement.  For example, I note that you first random number is 1 <= x < 60 but your initial post said that you required 1 <= x < 601, a simple typo but one that code like this is prone to)

Paul Linton

Monday, May 13, 2013 7:11 AM