0

I have an int array[] with a length of 12, and i want to fill it with numbers from 0 to 3 randomly, but i want to make sure that there are exactly three of 0, 1, 2, and 3 in the array. Any ideas on how to do this?

awesomeguy
  • 290
  • 3
  • 10

6 Answers6

5

Fill it non-randomly and then shuffle:

int[] myArray = new int(12);
for (i = 0; i < 12; ++i)
{
    myArray[i] = i/3;
}

Random rnd = new Random();
for (i = 0; i < 12; ++i)
{
    //int swapWith = rnd.Next(12);
    // Corrected to avoid bias.  See comments.
    int swapWith = rnd.Next(i+1);
    int temp = myArray[i];
    myArray[i] = myArray[swapWith];
    myArray[swapWith] = temp;
}
Jim Mischel
  • 131,090
  • 20
  • 188
  • 351
  • +1 other answers are correct too, but you wrote the code something like 45 seconds – Joel Lee Mar 24 '11 at 00:03
  • 1
    +1 for the principle, but your shuffle implementation isn't a true Fisher-Yates-Durstenfeld shuffle and will exhibit some bias: See the second paragraph of the "Implementation errors" section of http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#Implementation_errors and also http://www.codinghorror.com/blog/2007/12/the-danger-of-naivete.html. – LukeH Mar 24 '11 at 02:04
  • @LukeH: Thanks. I typed that in from (faulty) memory. Fixed now. – Jim Mischel Mar 24 '11 at 04:17
2

You can start with an ordered array (such as 0,0,0,1,1,1... etc.) and do a shuffle, like shuffling cards. Go through each index and swap the contents with the contents of another random one.

AlbeyAmakiir
  • 2,217
  • 6
  • 25
  • 48
1

Several of the other answers here suggest simply swapping randomly selected elements. That won't yield truly random results. See here for the details why and a better way of randomly sorting: http://www.codinghorror.com/blog/2007/12/the-danger-of-naivete.html

Robert Levy
  • 28,747
  • 6
  • 62
  • 94
0

Fill the array and then shuffle the numbers. How to do shuffling you can find here: Randomize a List<T>

Community
  • 1
  • 1
ChrisWue
  • 18,612
  • 4
  • 58
  • 83
0
Random rnd=new Random();
var array = new[] {0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3}
                           .OrderBy(i => rnd.Next() )
                           .ToArray();
Bala R
  • 107,317
  • 23
  • 199
  • 210
0

Here's yet one more way...

        var rnd = new Random();
        var items = Enumerable.Repeat(Enumerable.Range(0, 4), 3).SelectMany(item => item).OrderBy(item => rnd.Next()).ToArray();
Rudy
  • 920
  • 9
  • 19