Reputation: 477
I have input from textbox let´s say "abc". I want from random to randomize characters from this input. I can do that but from here I don´t know how to code to randomize only with all characters in final. So random final should be only one of these: "abc" "acb "bac" "bca" "cab" "cba". Now I have output like "abb" "ccc" "bba".
Random random = new Random();
int _length = _input.Length;
return new string(Enumerable.Repeat(_input, _length)
.Select(s => s[random.Next(s.Length)]).ToArray());
Upvotes: 0
Views: 143
Reputation: 30464
Use the modern version of the Fisher-Yates shuffle
From Wikipedia: The Fisher–Yates shuffle is an algorithm for generating a random permutation of a finite sequence — in plain terms, the algorithm shuffles the sequence
The following is implemented as extension function, so you can use it in a concatenation of LINQ statements:
private static readonly Random rnd = new Random();
public static IEnumerable<TSource> Shuffle<TSource>(this IEnumerable<TSource> source)
{
// TODO: exception if source equals null
// copy the source items to a new List, we don't want to shuffle the input, do we?
List<TSource> sourceItems = source.ToList();
int lastIndex = sourceItems.Count-1;
for (int i = 0; i < lastIndex; ++i)
{
// pick an index number on or after i
// if the picked number equals i, then do not shuffle element [i]
int j = rnd.Next(i, sourceItems.Count);
if (i != j)
{ // swap:
var tmp = sourceItems[i];
sourceItems[i] = sourceItems[j];
sourceItems[j] = tmp;
}
// yield return the next element of the shuffled sequence
yield return sourceItems[i];
}
}
usage:
List<MyClass> input = ...
IEnumerable<MyClass> output = input.Shuffle();
Note that the input is not shuffled.
The nice thing is, that if you only want a few outputs, no more items are shuffled then necessarry. The following will only take 3 elements from your original list:
var output = Enumerable.Range(0, 10)
.Shuffle()
.Take(3)
.ToList();
output is 3 distinct random numbers between 0 and 9
Upvotes: 0
Reputation: 38179
Sorting the letters by random:
var random = new Random();
var randomized = new string(_input.OrderBy(letter => random.Next()).ToArray());
Should do it
Upvotes: 3
Reputation: 181
You seem looking for a shuffling method :
string s = "abc";
char[] ar = s.ToCharArray();
Random rnd = new Random();
int n = ar.Length;
while (n > 1)
{
n--;
int k = rnd.Next(n + 1);
var x = ar[k];
ar[k] = ar[n];
ar[n] = x;
}
string result= new string(ar);
Upvotes: 1
Reputation: 1062780
One way to do this would be to create a list of the input characters, and select random elements, removing them each time. Otherwise, you need to track which ones you've "used", etc.
For example:
string s = "abc";
var candidates = new List<char>(s); // the as-yet-unused data
var result = new char[s.Length];
var random = new Random();
for(int i = 0; i < result.Length; i++)
{
int index = random.Next(candidates.Count); // pick an unused element
result[i] = candidates[index];
candidates.RemoveAt(index); // remove, so we don't repeat it
}
string final = new string(result);
Upvotes: 2