I want to generate an array that has 144 number from 1->36 in random order (so each number is repeated 4 times). Can we use Enumerable.Repeat and Enumerable.Range to do that. If yes than please explain to me how?. Thanks you very much.
+8
A:
Well, creating the sequence with all the numbers in is easy:
var items = from x in Enumerable.Range(1, 36)
from y in Enumerable.Repeat(x, 4)
select y;
Then you can just use ToArray
to get it into an array and shuffle it. There are numerous questions about shuffling an array in C# on SO, such as this one. You could either use that code directly, or call ToArray
and shuffle the array in place without yielding it at the end.
Jon Skeet
2010-01-07 11:36:44
hey, that's more readable than my solution. +1
David Hedlund
2010-01-07 11:38:24
and more elegant that my multiple Concat ;)
Thomas Levesque
2010-01-07 11:43:22
thanks for the comment, but now I need to fill the generated array to an [9,16] array, can you suggest a good way for me?
A New Chicken
2010-01-07 13:11:52
@A New Chicken: I suspect that using Buffer.BlockCopy will work for you... it's worth trying, anyway. (i.e. create the 2D array and use Buffer.BlockCopy to copy the 1D array into it.)
Jon Skeet
2010-01-07 13:25:41
A:
int[] numbers = Enumerable.Range(0, 144).Select(i => (i % 36)+1).OrderBy(g => Guid.NewGuid()).ToArray();
David Hedlund
2010-01-07 11:37:36
Probably not important in this case, but this way of shuffling ends up being O(n log n) where it only needs to be O(n).
Jon Skeet
2010-01-07 12:33:28
A:
// Generate the list (not in random order)
var one_to_36 = Enumerable.Range(1, 36);
var lst = one_to_36.Concat(one_to_36).Concat(one_to_36).Concat(one_to_36).ToList();
// Randomize the list by swapping random elements
Random rnd = new Random();
for(int i = 0; i < lst.Count; i++)
{
int i1 = rnd.Next(lst.Count);
int i2 = rnd.Next(lst.Count);
int tmp = lst[i1];
lst[i1] = lst[i2];
lst[i2] = tmp;
}
Thomas Levesque
2010-01-07 11:39:33
Swapping random elements in this way doesn't give a good random distribution - there's a better way of shuffling a collection, as linked to in my answer.
Jon Skeet
2010-01-07 12:32:54
A:
var seq = Enumerable.Range(0, 144);
var all = seq.ToList();
var random = new Random();
var result = seq.Select(i => {
var index = random.Next()%all.Count;
var r = all[index] % 36 + 1; all.RemoveAt(index);
return r;
}).ToList();
George Polevoy
2010-01-07 16:33:02