2010-01-07 4 views
5

Je veux générer un tableau qui a 144 nombre de 1-> 36 dans un ordre aléatoire (donc chaque nombre est répété 4 fois). Pouvons-nous utiliser Enumerable.Repeat et Enumerable.Range pour le faire. Si oui, merci de m'expliquer comment?Générer et répéter nombre en C#

Répondre

10

Eh bien, la création de la séquence avec tous les nombres est facile:

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

Ensuite, vous pouvez simplement utiliser ToArray pour l'obtenir dans un tableau et mélangez. Il y a de nombreuses questions sur le mélange d'un tableau en C# sur SO, tel que this one. Vous pouvez soit utiliser directement ce code, soit appeler le ToArray et mélanger le tableau sans le céder à la fin.

+0

hey, c'est plus lisible que ma solution. +1 –

+0

et plus élégant que mon concat multiple;) –

+0

merci pour le commentaire, mais maintenant je dois remplir le tableau généré à un tableau [9,16], pouvez-vous suggérer un bon moyen pour moi? –

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

Probablement pas important dans ce cas, mais cette façon de mélanger finit par être O (n log n) où il suffit d'être O (n). –

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

Permuter des éléments aléatoires de cette manière ne donne pas une bonne distribution aléatoire - il y a une meilleure façon de mélanger une collection, comme liée à ma réponse. –

+0

Je ne m'en suis pas rendu compte ... merci pour le pourboire –

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();