J'ai une liste d'éléments qui peuvent être facilement comparés en utilisant Equals()
. Je dois mélanger la liste, mais ce mélange doit satisfaire une condition :
Le i'me élément shuffledList[i]
ne doivent pas être égaux aux éléments à i +/- 1
ni d'éléments à i +/- 2
. La liste doit être considérée comme circulaire, c'est-à-dire que le dernier élément de la liste est suivi du premier, et vice versa.
De plus, si possible, j'aimerais vérifier si le shuffle est même possible.
Note :
J'utilise C# 4.0.
EDIT :
Sur la base de certaines réponses, je vais vous en dire un peu plus :
-
La liste n'aura pas plus de 200 éléments, il n'y a donc pas de réel besoin de bonnes performances. S'il faut 2 secondes pour la calculer, ce n'est pas la meilleure chose, mais ce n'est pas non plus la fin du monde. La liste mélangée sera sauvegardée, et à moins que la liste réelle ne change, la liste mélangée sera utilisée.
-
Oui, c'est un hasard "contrôlé", mais je m'attends à ce que plusieurs exécutions de cette méthode renvoient des listes mélangées différentes.
-
Je ferai d'autres modifications après avoir essayé certaines des réponses ci-dessous.
EDIT 2 :
- Deux exemples de listes qui échouent avec la mise en œuvre de Sehe (les deux ont des solutions) :
Echantillon1 :
`List<int> list1 = new List<int>{0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,9,10};`
Solution possible :
List<int> shuffledList1 = new List<int> {9,3,1,4,7,9,2,6,8,1,4,9,2,0,6,5,7,8,4,3,10,9,6,7,8,5,3,9,1,2,7,8}
Exemple 2 :
`List<int> list2 = new List<int> {0,1,1,2,2,2,3,3,4,4,4,4,5,5,5,6,6,6,7,7,7,7,8,8,8,8,8,9,9,9,9,10};`
-
Vérification : J'utilise cette méthode, ce n'est pas le code le plus efficace ni le plus élégant que j'ai fait, mais il fait son travail :
public bool TestShuffle<T>(IEnumerable<T> input) { bool satisfied = true; int prev1 = 0; int prev2 = 0; int next1 = 0; int next2 = 0; int i = 0; while (i < input.Count() && satisfied) { prev1 = i - 1; prev2 = i - 2; next1 = i + 1; next2 = i + 2; if (i == 0) { prev1 = input.Count() - 1; prev2 = prev1 - 1; } else if (i == 1) prev2 = input.Count() - 1; if (i == (input.Count() - 1)) { next1 = 0; next2 = 1; } if (i == (input.Count() - 2)) next2 = 0; satisfied = (!input.ElementAt(i).Equals(input.ElementAt(prev1))) && (!input.ElementAt(i).Equals(input.ElementAt(prev2))) && (!input.ElementAt(i).Equals(input.ElementAt(next1))) && (!input.ElementAt(i).Equals(input.ElementAt(next2))) ; if (satisfied == false) Console.WriteLine("TestShuffle fails at " + i); i++; } return satisfied; }
EDIT 3 :
Une autre entrée de test qui échoue parfois :
List<int> list3 = new List<int>(){0,1,1,2,2,3,3,3,4,4,4,5,5,5,5,6,6,6,6,7,7,7,8,8,8,8,9,9,9,9,10,10};