Share via


simple random number generator function. C#

Question

Friday, May 16, 2008 11:49 AM

Like a function that returns an array of integers with 1000 elements containing the values 1 to 1000 in random order. No number can be repeated or omitted.

No other .Net framework classes should be used / needed outside of the intrinsic data types.

please provide C# code.

Thanks,

All replies (16)

Sunday, May 18, 2008 11:50 PM ✅Answered

 I dont know how to make this any more clear.  1) create an array filled with the numbers 1-1000 IN ORDER.  2) Loop over the array and randomly swap items.  3) print the array.  If you cant achieve numbers one and three, completeing this assignement will be impossible.


Wednesday, May 21, 2008 9:34 AM ✅Answered

Jeffrey,

Please note any requirement can be achieved with various solutions. Look at my code how I made it quite possible.

ofcourse thanks for your quick reply.

 

1    private static void RandomNum()
2            {
3                //Initialize an array
4                int[] randomList = new int[1000];
5                //Initialize an instance of random class
6                Random rnd = new Random();
7                // integer variable
8                int counter = 0;
9    
10               //Error handler
11               try
12               {
13   
14                   while (counter < 1000)
15                   {
16                       //store random num 
17                       int random = rnd.Next(1, 1001);
18   
19                       if (Array.IndexOf(randomList, random) <= 0)
20                       {
21                           //store random number into Array
22                           randomList[counter] = random;
23                           counter++;
24                       }
25   
26   
27                   }
28               }
29               catch (Exception ex)
30               {
31                   Console.WriteLine("Error in generating an Array of Random Numbers", ex);
32               }
33   
34               //output elements in Array
35               for (int i = 0; i < 1000; i++)
36               {
37                   Console.WriteLine(randomList[i]);
38               }
39               //output number of elements in Array
40               Console.WriteLine(counter);
41               Console.Read();
42           }
43   

 


Friday, May 16, 2008 11:53 AM

 This sounds an awful lot like a homework assignment so I'm not going to provide code.  But if you need help developing your algorithm I'm perfectly willing to help you with that.


Friday, May 16, 2008 12:04 PM

static int RandomNumber(int min, int max)

{

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

}

I come across upto this stage. How can i store the values into an Array to reutn the numbers all btw 1 and 1000 randomly?

Thanks,


Friday, May 16, 2008 12:29 PM

Don't think in terms of generating random numbers - that's not your assignment. Your assignment apparently was to generate the nubmers 1 - 1000 in random order. It's not the numbers that are random. It's the order. There are many ways to solve this problem, and it's a classical problem. If you substitute 1000 for 52, you get the 'shuffle a deck of cards' problem.

So, I suggest you start by generating a sequence of very non-random numbers in a very non-random order in an array, and then think of ways of you can 'shuffle' the contents of that array.


Friday, May 16, 2008 1:22 PM

Thanks for not spoon feeding. I do appreciate that.

Managed to make it ...trail and error. Eventually you get there.

 

1     static void Main(string[] args)
2            {
3                int[] randomNum = new int[1000];
4                Random RandomNumber = new Random();
5    
6                for ( int i = 0; i<1000; i++)
7                {
8                    randomNum[i] = RandomNumber.Next(1, 1000);
9                }
10   
11               foreach (int j in randomNum)
12               {
13                   Console.WriteLine("First Number:{0}",  j);
14               }
15               
16               Console.Read();

Friday, May 16, 2008 2:17 PM

 What you've got there will give you 1000 random numbers.  The assignment was to produce the numbers 1 to 1000 in a random order.  I suggest the following algorithm:

Fill an array with the numbers 1 to 1000.
Go through the array randomly swapping numbers.
Print out the array.


Friday, May 16, 2008 4:17 PM

Thanks. Below code generates  random numbers between 1 and 1000 upto 299 Elements ONLY. I like to get all numbers,(1000 Elements in Array) between 1 and 1000.

 Any suggestions would be appreciated.

 

1    public static int[] GenerateRandomNumbers()
2            {
3                //Initialize an integer variable
4                int num = 0;
5                //Initialize an int temp Array 
6                int[] tempArr = new int[1001];
7                //Initialize an int array
8                int[] randomNum = new int[1001];
9                //Initialize random Number variable
10               Random rnd = new Random();
11   
12   
13               //Loop through to store Random Numbers to Array
14               for (int i = 0; i <= 1000; i++)
15               {
16   
17                   num = rnd.Next(1, 1000);
18                   tempArr[i] = num;
19   
20                   //Insert only if the number is not already in the previouly 
21                   //generated vlaue
22                   for (int j = 0; j < i; j++)
23                   {
24                       if (tempArr[j] != num)
25                       {
26                           randomNum[i] = num;
27                       }
28                   }
29                   //output elements in Array
30                   Console.WriteLine(num);
31               }
32   
33               return randomNum;
34           }

 


Wednesday, May 21, 2008 9:42 AM

any requirement can be achieved with various solutions

True. What is also true is that different solutions have different levels of efficiency... Your solution is extremely inefficient - this means slow.

Consider what you'll have to do to generate the last number. You'll have to keep generating random numbers until you find the one and only that is not already generated. That's a one-in-a-thousand chance.

On the average, you'll have to perform about 1000 linear searches through the 1000 element array just to generate that one last number. That's one million comparisons. On the average. For the last number.

 Work backwards the relative effort will decrease, and on the average require about 500 tries, so that's 500 searches through 1000 elements 1000 times.

 This works out to about 500 million comparisons on the average, just to generate 1000 numbers in random order. You can do better! Try the algorithm suggested.

 


Thursday, May 22, 2008 9:09 AM

 

Please note any requirement can be achieved with various solutions. Look at my code how I made it quite possible.

 

I agree that there's always more than one way to achieve the requirement.  Intro programming courses are as much about learning to think about how to develop simple algorithms as they are about learning the language constructs.   However the goal of algorithm design is always simplicity within the boundies of the requirements.  The algorithm you present is a pretty complex for a beginning programming course.  More over, by using Array.IndexOf, IMHO you've violated the constraint of not using anything but intrinsic types.  If you are satisfied with that code, by all means turn it in.  

 

Now that you've got a solution I dont feel bad about posting code.  so here's the algorithm I suggested earlier:

 

1    int[] theArray = new int[1000];
2    Random r = new Random();
3    for(int = 0; i<1000;i++)
4    {
5      theArray[i] = i+1;
6    }
7    for(int i = 0; i< 1000; i++)
8    {
9       int a = r.Next(1000);
10      int b = r.Next(1000);
11      int tmp = theArray[a];
12     theArray[a] = theArray[b];
13      theArray[b] = tmp;
14   }
15   for(int i = 0; i< 1000; i++)
16   {
17      Console.WriteLine(theArray[i]);
18   }
19   Console.ReadKey();

  Note that my version is 1) a little over half the size.  2) will always take the same ammount of time to run for a given array size.  3) is simply more straight forward in it's implementation.  No need for try-catch, just loop 3 times.

 


Thursday, May 22, 2008 10:05 AM

here's the algorithm I suggested earlier

Actually, not quite. There's a subtle flaw in this implementation. This is actually kind of cool... :-) Here goes:

There are (1000 * 1000)^1000 possible ways to run through this code. However, there are only 1000! (1 * 2 * 3 * 4 * ... * 999 * 1000) ways to shuffle 1000 numbers.

The problem is (1000 * 1000)^1000 cannot be evenly divisable by 1000!.

1000! is evenly divisible by 999 (i.e. 1000 - 1), this is trivially seen above by the partial expansion of 1000!.

Now, 999 shares no prime factors with 1000, that is - a prime factorization of 999 and 1000 will reveal that they share no prime factors. This means that (1000 * 1000)^1000 cannot be an even multiple of 1000!.

If (1000 * 1000)^1000 is not even multiple of 1000!, there must be at least one situation where one of the 1000! possible permutations gets at least one more that it's fair share of outcomes.

In other words - the shuffle is not quite unbiased - all outcomes are not quite equally likely.

Everyone with me so far?

Let's then do this right, since as JeffreyABecker notes, an effort has been made.

using System;

namespace ConsoleApplication1
{
    class Program
    {
        // See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
        static void Main(string[] args)
        {
            int[] theArray = new int[1000];
            int i = 0;
            while (i < theArray.Length)
            {
                theArray[i] = ++i;
            }

            // Work backward, swapping the last unswapped entry with any of the
            // remaining unswapped entries - including possibly itself.
            // This is really just slightly complicated way of doing a random 'draw',
            // which is exactly what is required to perform a shuffle.
            // Please note that the Random generator does not produce random numbers - it
            // produces a deterministic sequence of numbers with statistical properties similar
            // or at best equivalent to random numbers. For 'real' randomness, please turn
            // to System.Security.Cryptography.RNGCryptoServiceProvider.
            Random r = new Random();
            while (i > 1)
            {
                int j = r.Next(i);
                int t = theArray[--i];
                theArray[i] = theArray[j];
                theArray[j] = t;
            }

            for (i = 0; i < theArray.Length; ++i)
            {
                Console.WriteLine(theArray[i].ToString());
            }
        }
    }
}

 


Thursday, May 22, 2008 10:18 AM

 well that will teach me to write posts @ 3am and leave them sitting on my notepad for the morning :P


Monday, May 26, 2008 10:08 AM

Hi I am in college for computer programming and game developing I am new to this but am working on a texted based adventure and would like to know how to randomly generate 2 number from 1-6


Monday, May 26, 2008 10:15 AM

sorry for double posting but I am having problems with my char generation in my game

the problem is when I choose the overworld faction then when I say do not keep to test the loop and choose underworld faction it shows underworld but the class in overworld

using System;<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p>namespace gameDemo<o:p></o:p>{<o:p></o:p>    class gameIdea<o:p></o:p>    {<o:p></o:p>        static void <?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><st1:place w:st="on">Main</st1:place>(string[] args)<o:p></o:p>        {<o:p></o:p>            String name, Continue = "n", charClass = "k", Faction = "l";<o:p></o:p>            //UserInput and textIntput is used for userinput I dont need to keep<o:p></o:p>            int[] userInput = {0,0,0,0,0};<o:p></o:p>            String[] textInput = {"z", "z", "z", "z"};<o:p></o:p>            String[] Classes = {"skullzor", "Dragonkin", "Barbarians", "Sunstryders"};<o:p></o:p>            <o:p></o:p>            Console.WriteLine("Welcome to Gates of Aarath");<o:p></o:p>            <o:p></o:p>           Console.WriteLine("");<o:p></o:p><o:p> </o:p>            //insert loop<o:p></o:p>            while (Continue == "n")<o:p></o:p>            {//beginning of charactor gen... loop<o:p></o:p>                Console.WriteLine("please state your Name");<o:p></o:p>                name = Console.ReadLine();<o:p></o:p>                Console.WriteLine("Welcome: {0}", name);<o:p></o:p>                Console.WriteLine("please choos a faction \n 1) Underworld \n 2) Overworld");<o:p></o:p>                userInput[0] = Convert.ToInt32(Console.ReadLine());<o:p></o:p>               <o:p></o:p>                //Deciding what Class for underworld faction<o:p></o:p><o:p> </o:p>                if (userInput[0] == 1)<o:p></o:p>                {<o:p></o:p>                    Console.WriteLine("1) {0} \n 2) {1}", Classes[0], Classes[1]);<o:p></o:p>                    userInput[1] = Convert.ToInt32(Console.ReadLine());<o:p></o:p>                    Faction = "Underworld";<o:p></o:p>                }<o:p></o:p>                //Establashing Char class choice of underworld faction<o:p></o:p>                if (userInput[1] == 1) charClass = Classes[0];<o:p></o:p>                if (userInput[1] == 2) charClass = Classes[1];<o:p></o:p>                //Deciding what class for Overworld Faction<o:p></o:p>                if (userInput[0] == 2)<o:p></o:p>                {<o:p></o:p>                    Console.WriteLine("1) {0} \n 2) {1}", Classes[2], Classes[3]);<o:p></o:p>                    userInput[2] = Convert.ToInt32(Console.ReadLine());<o:p></o:p>                    Faction = "Overworld";<o:p></o:p>                }<o:p></o:p>                //Establashing Char class for Overworld Faction<o:p></o:p>                if (userInput[2] == 1) charClass = Classes[2];<o:p></o:p>                if (userInput[2] == 2) charClass = Classes[3];<o:p></o:p>                Console.WriteLine("\n\n Name {0} \n Faction {1} \n Class {2}", name, Faction, charClass);<o:p></o:p>                Console.WriteLine("Would you like to keep your char? (y/n)");<o:p></o:p>                textInput[0] = Console.ReadLine();<o:p></o:p><o:p> </o:p>                if (textInput[0] == "y")<o:p></o:p>                    break;<o:p></o:p>        }//end of loop<o:p></o:p>        }<o:p></o:p>    }<o:p></o:p>}<o:p></o:p>

 


Monday, May 26, 2008 10:16 AM

would like to know how to randomly generate 2 number from 1-6

That's fine - but please post this as a new question in a new thread, not as a reply to a somewhat but not really related thread.

To other members: Please do not reply in this thread.


Thursday, February 7, 2013 6:38 AM

I know this thread is quite old but I just had to post here. Jeffrey was just trying to guide you to the right way of going about this task. While it's true that your version works (very inefficiently as Jefrey described) his version is better. Since it's an old thread I will post some code to demonstrate:

            //instantiate a random number generator just once
            var rnd = new Random();

            //create an array to hold our numbers
            var n = new int[1000];

            //a variable where we can store a temporary random position number
            int rpos;

            //fill the array with the numbers 1 to n.Length (1000 in this case)
            for (var i = 0; i < n.Length; i++) n[i] = i + 1;

            //iterate over each element in the array from the bottom to the top. Do not include the first one
            for (var i = n.Length - 1; i > 0; i--)
            {
                //generate a new random position from 0 to i (inclusive)
                //i is included because we want the possibility of an item not moving. It can happen.
                //Since rnd.Next will give us a value smaller than the number we give it, we give it i + 1 so its output is from 0 to i
                //after generating the random number check if it is equal to i.
                if ((rpos = rnd.Next(i + 1)) != i)
                {
                    //if the random position is not equal to i, then swap the elements at positions i and our random position
                    //if the position is equal then we don't need to swap it with itself.
                    //in fact, since i'm using XOR swap here (so I can do the swap in one line)
                    //it's actually dangerous to try to swap a value with itself
                    //as it will end up as 0. So in this case we're also guarding against this possibility
                    n[i] = n[rpos] ^ n[i] ^ (n[rpos] = n[i]);
                }
            }

This is an implementation of the Fisher-Yates shuffle algorithm. I have added some comments to explain each step. If you remove allthe curly brackets (since each pair only contains one statement) you can get this done in 6 lines. Compare this with your old version. Sometimes your version works, but you miss out on a far better way of doing things.