2010-01-07 16 views
5

Quiero generar una matriz que tiene 144 números de 1 a 36 en orden aleatorio (por lo que cada número se repite 4 veces). ¿Podemos usar Enumerable.Repeat y Enumerable.Range para hacer eso? Si es así, por favor explícame ¿cómo?Generar y repetir el número en C#

Respuesta

10

Bueno, la creación de la secuencia con todos los números en es fácil:

var items = from x in Enumerable.Range(1, 36) 
      from y in Enumerable.Repeat(x, 4) 
      select y; 

a continuación, puedes utilizar ToArray conseguirlo en una matriz y barájalo. Existen numerosas preguntas sobre cómo mezclar una matriz en C# en SO, como this one. Puede usar ese código directamente, o llamar al ToArray y mezclar la matriz en su lugar sin cederla al final.

+0

bueno, eso es más fácil de leer que mi solución. +1 –

+0

y más elegante que mi Concat múltiple;) –

+0

gracias por el comentario, pero ahora tengo que llenar la matriz generada a una matriz [9,16], ¿me puede sugerir una buena manera? –

0
int[] numbers = Enumerable.Range(0, 144).Select(i => (i % 36)+1).OrderBy(g => Guid.NewGuid()).ToArray(); 
+0

Probablemente no es importante en este caso, pero esta manera de mezclar termina siendo O (n log n) donde solo tiene que ser O (norte). –

0
// 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; 
} 
+0

Al intercambiar elementos aleatorios de esta forma no se obtiene una buena distribución aleatoria; hay una forma mejor de barajar una colección, como se relaciona en mi respuesta. –

+0

No me di cuenta de eso ... gracias por la propina –

0
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(); 
Cuestiones relacionadas