3

It is all in the title basically. It is simple, but I don't know why my While loop is failing sometimes. Every now and then I would get a list that is of length 2 instead of 3.

Here is my C# code:

public List<int> generateRequiredSecretCode()
{
    List<int> placeHolder = new List<int>();
    Random random = new Random();
    int randomNo = random.Next(0, 10);
    while (!placeHolder.Contains(randomNo) && placeHolder.Count != 3)
    {
        placeHolder.Add(randomNo);
        randomNo = random.Next(0, 10);
    }
    return placeHolder;
}

Summary of my aim: I want a List of integers that is of length 3 and where each number in the list is between 0 and 9 and is unique

J86
  • 14,345
  • 47
  • 130
  • 228

4 Answers4

7

You can have a neat LINQ two-liner using

var random = new Random();
return Enumerable.Range(0,10).OrderBy(i => random.NextDouble()).Take(3).ToList();
Jens
  • 25,229
  • 9
  • 75
  • 117
3

!placeHolder.Contains(randomNo) is your problem here because the while ends if the list contains the randomNo. Check that !placeHolder.Contains(randomNo) in an inner if like this:

while (placeHolder.Count != 3)
{
    if( !placeHolder.Contains(randomNo) )
      placeHolder.Add(randomNo);
    randomNo = random.Next(0, 10);
}
Moriya
  • 7,750
  • 3
  • 35
  • 53
0

It sometimes fails because, in the rare cases when Rand.Next does return an identical number to thise already in the list, !placeHolder.Contains(randomNo) will return false; false && anything = false, so the loop ends. If you'd run it long enough, you'd eventually get a list of length 1 ;)

Possible replacement:

List<int> placeHolder = new List<int>();
Random random = new Random();
int randomNo;
do {
    randomNo = random.Next(0, 10);
    if (!placeHolder.Contains(randomNo) && placeHolder.Count != 3)
    {
         placeHolder.Add(randomNo);
         randomNo = random.Next(0, 10);
    }
} while (placeHolder.Count < 3);
return placeHolder;

[edit]: This thread moved fast... and Animal's solution is much better than mine :(

Liz
  • 378
  • 3
  • 19
0

A little late to the party, but set arithmetic seems quite elegant so couldn't resist:

private static Random RNG = new Random();

...

public static List<int> RandomNumbers() {
  var numbers = new HashSet<int> { RNG.Next(0, 9), RNG.Next(0, 9), RNG.Next(0, 9) };
  while (numbers.Count < 3) 
  {
    numbers.Add(RNG.Next(0, 9));
  }

  return numbers.ToList();
}
Rich O'Kelly
  • 41,274
  • 9
  • 83
  • 114