-5

I have tried variations of code for this, but some of the characters are repeating in the text boxes.

I want seven different characters in seven text boxes.

See picture for reference.... thank you in advance

enter image description here

James
  • 15,754
  • 12
  • 73
  • 91

2 Answers2

2
Random rnd = new Random();
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var sevenRandomChars = chars.OrderBy(_ => rnd.Next()).Take(7).ToList();
EZI
  • 15,209
  • 2
  • 27
  • 33
  • Are you sure your algorithm doesn't fall in the http://stackoverflow.com/questions/859253/why-does-this-simple-shuffle-algorithm-produce-biased-results-what-is-a-simple – xanatos Mar 14 '15 at 22:24
  • @xanatos Sorry, but yes, I am sure. (I have already read that http://ericlippert.com/2011/01/20/bad-comparisons-part-one/) – EZI Mar 14 '15 at 22:25
  • I've given a little thought... It is a little biased, but not so much. [OrderBy](https://msdn.microsoft.com/en-us/library/bb534966%28v=vs.110%29.aspx) is guaranteed to be stable (`This method performs a stable sort; that is, if the keys of two elements are equal, the order of the elements is preserved`), so if two elements gets the same `rnd.Next()` value, the one with a lower index is guaranteed to remain with the lower index. So elements on top have a little more chance to remain on top. But the bias is very very small for small arrays. – xanatos Mar 14 '15 at 22:36
  • @xanatos you may try it with a very large array :) `Enumerable.Range(0,10000000).OrderBy(_ => rnd.Next()).Take(7).ToList()` – EZI Mar 14 '15 at 22:42
  • No, it's easier to reduce the maximum value of `rnd.Next()`, in this way the collisions will raise. – xanatos Mar 14 '15 at 22:45
  • @xanatos OK, do it. Why don't you try it instead of posting a lot of comments. Do your tests and post the results. – EZI Mar 14 '15 at 22:50
  • I have tested this approach. There is no bias. – Enigmativity Mar 14 '15 at 23:02
  • textBox1.Text = letters[0].ToString(); textBox2.Text = letters[1].ToString(); textBox3.Text = letters[2].ToString(); textBox4.Text = letters[3].ToString(); textBox5.Text = letters[4].ToString(); textBox6.Text = letters[5].ToString(); textBox7.Text = letters[6].ToString(); I use this line after ur code letters.removeAt(i); its work fine but when I am hitting button for the second time it is not generating any thing plzz help ..... @xanatos – Rajsekhar pakalapati Mar 15 '15 at 05:47
  • @EZI Done http://pastebin.com/5CDnUxPG For an array of 3 elements, you do need at least r.Next(512) before having an unbiased shuffle. For 5 elements, at least r.Next(1024). As I've told, increasing the range of the random number generator makes the shuffler less biased. – xanatos Mar 15 '15 at 08:31
1

The simplest way is:

// The 26 letters, A...Z, in a char[] array
char[] letters = Enumerable.Range(0, 26).Select(x => (char)('A' + x)).ToArray();

Take all the 26 upper case letters

// http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
public static void Shuffle<T>(IList<T> list, Random r)
{
    for (int i = list.Count - 1; i > 0; i--)
    {
        int j = r.Next(0, i + 1);

        // Do the swap
        T temp = list[i];
        list[i] = list[j];
        list[j] = temp;
    }
}

// This is the method that does the shuffling
Shuffle(letters, new Random());

Shuffle them with the Fisher-Yates algorithm,

and take the first 7 elements of the shuffled letters array letters[0]...letters[6]. In this way you are gauranteed that the letters are unique, and that each letter has the same chance of being used.

An even easier way to do it:

// The 26 letters, A...Z, in a List<char>!
List<char> letters = Enumerable.Range(0, 26).Select(x => (char)('A' + x)).ToList();

Random r = new Random();

// The letters you "select"
char[] usedLetters = new char[7];

for (int i = 0; i < usedLetters.Length; i++)
{
    int j = r.Next(0, letters.Count);
    usedLetters[i] = letters[j];

    // When you select a letter, you remove it!
    letters.RemoveAt(i);
}

When you select a letter, you remove it. In this way any one letter can be used 0...1 times.

xanatos
  • 109,618
  • 12
  • 197
  • 280