4

I am trying to generate a random alphanumeric array that consist of 3 letters and 6 digits. The entire array must be random. The only way I could think of is generating 2 individual random arrays and then merging them and randomizing the merged array. Any help would be appreciated. I specifically need help on ensuring that the correct number of variable types are stored. Here is my semi-working code:

 static void Main(string[] args)
    {
        var alphabetic = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        var numeric = "0123456789";
        var stringChars = new char[9];
        var random = new Random();


        for (int i = 0; i < 3; i++)
        {
            stringChars[i] = alphabetic[random.Next(alphabetic.Length)];
        }
        for(int i = 3; i< stringChars.Length; i++)
        {
            stringChars[i] = numeric[random.Next(numeric.Length)];
        }


        var ranChars = new char[9];
        var semisorted = new String(stringChars);

        for (int i=0; i< ranChars.Length; i++)
        {
            ranChars[i] = semisorted[random.Next(semisorted.Length)];
        }


        var final = new string(ranChars);

        Console.WriteLine("{0}", final);
        Console.ReadLine();


    }
  • 1
    Possible duplicate of [How can I generate random alphanumeric strings in C#?](http://stackoverflow.com/questions/1344221/how-can-i-generate-random-alphanumeric-strings-in-c) – Rion Williams Apr 26 '16 at 16:57
  • 2
    @RionWilliams I disagree, this time there are specific counts of letter and digit, which requires a very different technique – harold Apr 26 '16 at 16:59
  • Fair point. I was on the fence about it and while there are many techniques within that thread, I don't believe any cover specific numbers of characters. I've retracted the close vote. – Rion Williams Apr 26 '16 at 17:00
  • There is no mention of whether characters and numbers can be repeated in the results. Do you want combinations or permutations? – JerryM Apr 26 '16 at 17:17
  • This smells like homework to me. – BrainSlugs83 Apr 26 '16 at 18:47
  • @JerryM It is actually required to be a unique set of characters. Would the code be much different to harold's solution then? – pineapple_music495 Apr 27 '16 at 03:43
  • @pineapple_music495 yes because then the first part your code has to be replaced also – harold Apr 27 '16 at 11:50

2 Answers2

4

You're close. But the problem here is that you're selecting randomly from the "semi-sorted" array, while what's really necessary at that point is picking a random permutation. One way to do that is with a Fisher-Yates shuffle.

So combining that with the code you had that worked: (not tested)

for (int i = 0; i < 3; i++)
{
    stringChars[i] = alphabetic[random.Next(alphabetic.Length)];
}
for(int i = 3; i< stringChars.Length; i++)
{
    stringChars[i] = numeric[random.Next(numeric.Length)];
}
int n = stringChars.Length;
while (n > 1) 
{
    int k = random.Next(n--);
    char temp = stringChars[n];
    stringChars[n] = stringChars[k];
    stringChars[k] = temp;
}
string result = new string(stringChars);
Community
  • 1
  • 1
harold
  • 61,398
  • 6
  • 86
  • 164
0

Harold's answer is way cleaner, but here's another approach for the whole '100 ways to do the same thing in programming' concept. [Edit: Doh, I reversed the number of digits and letters. Here's a fix:]

public static void Main(string[] args)
    {
        var random = new Random();
        var finalString = string.Empty;
        var finalArray = new string[9];

        for (var i = 0; i < 3; i++)
        {
            var alphabet = random.Next(0, 26);
            var letter = (char) ('a' + alphabet);
            finalArray[i] = letter.ToString().ToUpper();
        }

        for (var i = 3; i < 9; i++)
        {
            var number = random.Next(0, 9);
            finalArray[i] = number.ToString();
        }

        var shuffleArray = finalArray.OrderBy(x => random.Next()).ToArray();
        for (var i = 0; i < finalArray.Length; i++)
        {
            finalString += shuffleArray[i];
        }
        Console.WriteLine(finalString);
        Console.ReadKey();    
    }
Ryan Intravia
  • 420
  • 6
  • 12
  • Cleaned up again since I didn't realize I left remains of my testing. – Ryan Intravia Apr 26 '16 at 19:10
  • 1
    It's not very obvious, but that way of shuffling has a bias towards leaving items in their original order. It's not a big effect because the range of random.Next is pretty big. But pretend you had `random.Next(2)` and you're shuffling a list of 2 items. OrderBy is stable, so 3/4 of the outcomes (for the random numbers) make it give the original order. For `Next(3)` it's 6/9 and so on, until ((2^31+1) choose 2) / ((2^31)^2) approx 0.50000000023. Lists longer than 2 have a similar problem obviously but the thought experiment is harder. – harold Apr 26 '16 at 19:46
  • Great insight and something I didn't consider, but a very valid point. I appreciate the feedback! – Ryan Intravia Apr 26 '16 at 20:06