Generating unique random numbers in C#

  • (2 Pages)
  • +
  • 1
  • 2

16 Replies - 2196 Views - Last Post: 29 April 2014 - 07:34 AM Rate Topic: -----

#1 HaDaEx  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 15
  • Joined: 07-January 14

Generating unique random numbers in C#

Posted 28 April 2014 - 01:30 PM

Hey everyone. On Saturday I had an exam and in one of the questions we had to generate random, unique numbers in the range [1,15]. I couldn't figure it out but thankfully it didn't have much points on it.
Now I tried to solve it at home, and for a minute here I thought I did. But running the program for several times showed a bug: It wouldn't always generate a new number for every repeated number. I can't figure out the problem, especially since it works half the time and I can't figure out what's making it work some times and not others.
By the way I tried googling this but all I found were results saying to use a List or other things which I have not learned yet. It should be solvable without anything like that, right?

 bool flag1 = true, flag2 = true, flag3 = true;
            int i, j = 1;
            int[] A = new int[11];
            Random rnd = new Random();
            A[0] = rnd.Next(1, 15);
            Console.WriteLine("1. = " + A[0]);
            for (i = 1; i < A.Length; i++)
            {
                A[i] = rnd.Next(1, 15);
                Console.Write("{0}. = {1,-3}",i+1,A[i]);
                while (flag1)
                {
                    flag2 = true;
                    while ((flag2) && (j <= i))
                    {
                        if (i != j)
                        {
                            if (A[j] == A[i])
                            {
                                Console.WriteLine(i + 1 + ". = " + A[i] + " already exists!");
                                A[i] = rnd.Next(1, 15);
                                Console.WriteLine("New number is: " + A[i]);
                                flag3 = false;
                            }
                        }
                        j++;
                        if (flag3)
                            flag2 = false;
                    }
                    
                    flag1 = false;
                }
                Console.WriteLine();
                flag1 = true;
                flag3 = true;
                j = 0;
            }


Any idea why this may be wrong? Am I going about this the wrong way?
Thanks in advance. You guys rock.

Is This A Good Question/Topic? 0
  • +

Replies To: Generating unique random numbers in C#

#2 Martyr2  Icon User is offline

  • Programming Theoretician
  • member icon

Reputation: 4421
  • View blog
  • Posts: 12,286
  • Joined: 18-April 07

Re: Generating unique random numbers in C#

Posted 28 April 2014 - 01:46 PM

Well ideally you want to keep a list of past generated numbers. Your rnd.Next(1,15) is going to give you a random number in that range... meaning it could regenerate a number it already generated before. If you want only unique numbers, you will have to know what had been generated before. You would generate the number, check the list, if found you would have to regenerate again until unique. Once unique, you add it to the list.

See this statement you have in your code?

int[] A = new int[11];



That is all you need... an array is a list of items. You would generate your number, add it to the "A" array and check that array to see if it has already been generated before. Everything you have there, an array, a loop and if statements are the only things you need to implement the list and make sure that it is all unique.

:)
Was This Post Helpful? 1
  • +
  • -

#3 HaDaEx  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 15
  • Joined: 07-January 14

Re: Generating unique random numbers in C#

Posted 28 April 2014 - 02:07 PM

Thanks. I guess I was over complicating it. I think I have got it right this time.
int[] A = new int[14];
            int i, j, x;
            bool flag = false;
            Random rnd = new Random();
            for (i = 0; i < A.Length; i++)
            {
                x = rnd.Next(1, 31);
                Console.WriteLine(i+1+"  "+x);
                for (j = 0; j <= i; j++)
                {
                    
                    while ((i!=j)&&(x == A[j]))
                    {

                        x = rnd.Next(1, 31);
                        Console.WriteLine("new x = " + x);
                    }
                    A[i] = x;
                }
            }




Oh and I don't know how I can edit my post, but there's no need for the flag.
Was This Post Helpful? 0
  • +
  • -

#4 Martyr2  Icon User is offline

  • Programming Theoretician
  • member icon

Reputation: 4421
  • View blog
  • Posts: 12,286
  • Joined: 18-April 07

Re: Generating unique random numbers in C#

Posted 28 April 2014 - 02:08 PM

In case you want to cheat a little...

Edit: Correction, you could use the find method or the exists method.

Find: http://msdn.microsof...(v=vs.100).aspx
Exists: http://msdn.microsof...(v=vs.100).aspx

Or you can use contains, just on the array itself...

int[] A = new int[11];
A.contains(somevalue);



:)

This post has been edited by Martyr2: 28 April 2014 - 02:17 PM
Reason for edit:: Added more options

Was This Post Helpful? 2
  • +
  • -

#5 HaDaEx  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 15
  • Joined: 07-January 14

Re: Generating unique random numbers in C#

Posted 28 April 2014 - 02:21 PM

It appears that there's a function for everything I get stuck on. Still, it can't hurt to know how to do these things without a ready function. Thanks! I'll keep that in mind =)

Edit: Okay, I'll check these two out as well. I should really familiarize myself with MDSN. Thanks!
Was This Post Helpful? 0
  • +
  • -

#6 Curtis Rutland  Icon User is online

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4576
  • View blog
  • Posts: 8,016
  • Joined: 08-June 10

Re: Generating unique random numbers in C#

Posted 28 April 2014 - 02:39 PM

So I'm not sure what's going on in your code, because some things changed between the first post and the last that you wouldn't think would change, like your array size and your upper bounds for your random numbers.

Either way, I think you're still somewhat overcomplicating it. There are simpler ways to do this than I'm even going to show, since I'm assuming that you're working through school and haven't covered much past loops and arrays, so I'm sticking with those. Here's how I would do this:

int incMin = 1, excMax = 16, arraySize = 15;
int[] numbers = new int[arraySize];
Random random = new Random();
for(int i = 0; i < numbers.Length; i++)
{
	int num = random.Next(incMin, excMax);
	for(int j = 0; j < i; j ++)
	{
		if(numbers[j] == num)
		{
			num = random.Next(incMin, excMax);
			j = -1;
		}
	}
	numbers[i] = num;
}


First of all, notice that I've got variables for my "Inclusive Minimum", "Exclusive Maximum", and "Array Size". Since you're going to re-use almost all of those values, it's best to store that kind of thing in a variable, so that if you have to change it, you don't have to change it in a dozen places, just one. It also prevents the kind of bug where you forget that one spot you have to change it in.

Second, notice variable names. Everything says exactly what it is, or an abbreviation of what it is. incMin = "inclusive minimum", for example. The only ones that don't are the loop control variables, and using i and j are considered standard practice there. But, for example, in your code, I don't know what x or A refers to without looking at how they're used. I called them "num" and "numbers", I think that's much more self explanatory.

Third is somewhat more personal. I'm not sure if your instructor is telling you to pre-declare all your variables like that, but I can't stand that style. C# allows you to declare variables as needed, as long as you understand the implications of variable scopes. For instance, loop control variables. They don't need to be used anywhere except inside their loops. So why declare them at the top, which makes them available to the entire method they're declared in? Plus, if you had two loops, back to back, not inside each other, you could re-use the name i and not have to keep track of multiple loop variables. Same with the variable I declared called num. It's not important outside the loop. We have no need to track it; we actually don't care if it gets re-created each time the loop runs, because we're giving it a new value right away each time too. IMO, declaring variables close to where they're needed/used is the best way to go about things. OTOH, if your instructor has told you to pre-declare your variables at the top, do what he/she says. Better to code for the grade than for best practices while you're in class (as long as you eventually learn the right way, no sense failing a class on principle).

Next, notice that i'm only using one internal loop. It's not that what I'm doing is that much more efficient, since I'm effectively "reseting" the loop any time a duplicate number is found. It's just more readable, IMO. Also my inner loop goes while j < i, so I don't need to check j against i inside. If it does find a duplicate, it re-generates the random number, sets j to -1. Since the loop increases j by 1 every time it loops, when it goes back to the beginning of the inner loop, j is back to 0 and we've started again. No reason to have an internal while-loop; just keep resetting the inner loop until it makes it all the way through.

Hope this helps a bit.
Was This Post Helpful? 2
  • +
  • -

#7 HaDaEx  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 15
  • Joined: 07-January 14

Re: Generating unique random numbers in C#

Posted 28 April 2014 - 03:06 PM

Resetting a loop that way is something I wouldn't have thought about by myself. I kept trying to think of a way to reset the loop every time a number got regenerated, but I couldn't come up with anything, hence the while loop. As for the changes in the array size and boundary, these things didn't matter so much as I wanted to check if the program was doing what its supposed to when I print the values.

Yes, we haven't covered anything past arrays and loops, unfortunately. I was looking forward to OOP, which we haven't started yet, because of a lazy teacher, classmates who don't want to learn, and now we don't have enough time left this year, so it'll have to wait for next year. We barely even made it to 2D arrays, and next week we have a bagrut (I think its called AP test in the states? idk). If we had learned properly throughout the year then we would've finished arrays by Christmas, or February at most. Oh well =/

About the variable names, I usually use variables named x, a,b,c etc... if the program is small. If it gets longer (such as if it needs multiple functions and methods) I use names that represent what they are because otherwise I'd get confused. It's a good point, though, and I should start naming them properly no matter the size of the program. Thanks for the tip there.

Anyway, each time one of you posts I learn something new, so thanks for your help, Martyr and Curtis!
Was This Post Helpful? 0
  • +
  • -

#8 Curtis Rutland  Icon User is online

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4576
  • View blog
  • Posts: 8,016
  • Joined: 08-June 10

Re: Generating unique random numbers in C#

Posted 28 April 2014 - 03:42 PM

From what I've read, AP exams are similar to bagrut; they're used for higher-level classes ("AP" stands for "advanced placement"). I believe that they can stand in as college credit for certain classes. But I don't know anything more than Wikipedia says about bagrut, so who knows?

Don't worry that you wouldn't have thought of "resetting" the loop that way. Logical thinking is something that comes with practice and experience. I don't honestly think I've ever used that particular trick before, but I know how to do it because I've been working with loops for...damn, fourteen years? Fifteen? Can't remember when I started programming.

And yeah, you should get into the pattern of using good names for all your variables. Especially since Visual Studio and pretty much every other IDE has good autocompletion, descriptive variable names are no more of a pain to type than short ones. And you'd be surprised how complicated even small programs can be to read, when you come back to them after a few days/weeks. Learn to love good variable names, you'll thank your past self over and over again for it in the future.

Last bit of advice: pencil and paper are a surprisingly good tool for programmers. Write out logic (not code), then try to code for that logic. It's always easy if you break down your problem into it's individual pieces. That also benefits an Object Oriented mindset, because OOP is supposed to model real-world things; breaking a problem down into its components is effectively breaking the problem down into actions and objects.

Have fun with programming in school, you'll learn a ton. But always remember that your real programming education starts the day you get your first real-world job (assuming you're going to work in programming); you're going to realize that a ton of what you'll do isn't taught at school, and a ton of what's taught at school isn't going to be useful to you day-to-day. Which parts depends on your career path, of course. For example, as a business programmer, the most advanced math skills I need is basic algebra. But if I were a game programmer, I'd need a lot more, but less of some other skills, like knowing about web services and such. But it's wonderful sometimes, every day has a new puzzle to solve.
Was This Post Helpful? 1
  • +
  • -

#9 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3662
  • View blog
  • Posts: 11,463
  • Joined: 05-May 12

Re: Generating unique random numbers in C#

Posted 28 April 2014 - 07:24 PM

If the goal was to get a set of non-repeating random numbers within a known range, wouldn't the Fisher-Yates Shuffle have been a better approach to this?
Spoiler

Was This Post Helpful? 1
  • +
  • -

#10 Momerath  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1012
  • View blog
  • Posts: 2,444
  • Joined: 04-October 09

Re: Generating unique random numbers in C#

Posted 28 April 2014 - 07:32 PM

That was my thought too, Skydiver, when I first read this. But I'd have used Enumerable.Range to fill the array :)
Was This Post Helpful? 0
  • +
  • -

#11 Curtis Rutland  Icon User is online

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4576
  • View blog
  • Posts: 8,016
  • Joined: 08-June 10

Re: Generating unique random numbers in C#

Posted 28 April 2014 - 07:39 PM

Same here, but I was trying to keep it on the level of his assignment.
Was This Post Helpful? 0
  • +
  • -

#12 HaDaEx  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 15
  • Joined: 07-January 14

Re: Generating unique random numbers in C#

Posted 28 April 2014 - 11:53 PM

View PostCurtis Rutland, on 28 April 2014 - 02:39 PM, said:

for(int i = 0; i < numbers.Length; i++)
{	[b]int num[/b] = random.Next(incMin, excMax);	
... 


A question here. My teacher says to always declare variables outside of loops. Is there any difference between declaring outside or inside the loop?


View PostSkydiver, on 28 April 2014 - 07:24 PM, said:

  public IEnumerable<int> GetNumbers()        

I haven't learned about that part yet, nor about the foreach loop. Hopefully I'll be able to study these things in the summer, when I'm done with all of these exams, and all the novels and video games on my to-do list =)
Was This Post Helpful? 0
  • +
  • -

#13 Momerath  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1012
  • View blog
  • Posts: 2,444
  • Joined: 04-October 09

Re: Generating unique random numbers in C#

Posted 29 April 2014 - 12:29 AM

View PostHaDaEx, on 28 April 2014 - 11:53 PM, said:

A question here. My teacher says to always declare variables outside of loops. Is there any difference between declaring outside or inside the loop?

Your teacher would be wrong. It has to do with scope and reducing the chance of errors. If you declare the variable inside the loop it is only available inside the loop. If you try to use it outside the loop you will get an error that the variable is undeclared.

Given that, there are times you want to declare stuff outside the loop, and sometimes you want it in the loop. I always start with the most restrictive scope (inside the loop) and if I find I need it outside, move it.
Was This Post Helpful? 1
  • +
  • -

#14 HaDaEx  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 15
  • Joined: 07-January 14

Re: Generating unique random numbers in C#

Posted 29 April 2014 - 12:35 AM

So, similar to how if I declare a variable in a method/function and try to use it in Main()? Interesting.
Was This Post Helpful? 0
  • +
  • -

#15 HaDaEx  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 15
  • Joined: 07-January 14

Re: Generating unique random numbers in C#

Posted 29 April 2014 - 02:10 AM

Correct me if I'm wrong, but does this mean that for every block of code, it can use the variables outside of that block, but something outside the block can't use variables declared inside it?
For example,
class Example
{
      int x = 5;
      static void method1()
           {
              int y, i;
              y=x;
              //x can be used here.
              for (i=0;i<10;i++)
               {
                 int z = i * y;
                 Console.WriteLine(z);
               }
              //z can't be used here
           }
       //y and i can't be used here
      static void Main()
          {
             method1();
          }
}
class Example2
{
//none of the variables of class Example1 can be used here
}


Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2