-1

I'm currently trying to create a program that generates random numbers between 1 and 45 with no duplicates. My program works when I run it without the else statement whenever a duplicate comes up it inputs the number 0, when I use the else statement the function breaks. I want to display random numbers between 1 and 45 however the variable size must dictate the size of the array. For example random integers between 1 and 45 with an array size of 35.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RandomArray
{
public class RandomArrayNoDuplicates
{
    static void Main(string[] args)
    {
        int size = 45;
        int[] noDuplicateArray = new int[size];
        noDuplicateArray = InitializeArrayWithNoDuplicates(size);
        DisplayArray(noDuplicateArray);
        ExitProgram();

    } //end Main
    static Random rng = new Random();

    /// <summary>
    /// Creates an array with each element a unique integer
    /// between 1 and 45 inclusively.
    /// </summary>
    /// <param name="size"> length of the returned array < 45
    /// </param>
    /// <returns>an array of length "size" and each element is
    /// a unique integer between 1 and 45 inclusive </returns>
    ///
    static void ExitProgram()
    {
        Console.Write("\n\nPress any key to exit program: ");
        Console.ReadKey();
    }//end ExitProgram

    public static int[] InitializeArrayWithNoDuplicates(int size)
    {
    int number;
    int[] noDuplicates = new int[size];

        for (int i = 0; i < size; i++)
        {
            number = rng.Next(1, size);
            if (!noDuplicates.Contains(number))
                noDuplicates[i] = number;
           // else
           //     i--;
        }
        return noDuplicates;

    }
    static void DisplayArray(int[] noDuplicates)
    {
    foreach (int element in noDuplicates)
        {
            Console.Write("\t" + element + "\n");
        }
    }
}
}

The issue lies in this bit of code:

public static int[] InitializeArrayWithNoDuplicates(int size)
    {
    int number;
    int[] noDuplicates = new int[size];

        for (int i = 0; i < size; i++)
        {
            number = rng.Next(1, size);
            if (!noDuplicates.Contains(number))
                noDuplicates[i] = number;
           // else
           //     i--;
        }
        return noDuplicates;

but I'm unsure how to fix it. I would prefer to use the random.next function rather than using enumberable approach. Thanks

1
  • What exactly is the issue ? Commented Aug 27, 2017 at 13:38

2 Answers 2

2

Try following :

        public static int[] InitializeArrayWithNoDuplicates(int size)
        {
            Random rand = new Random();
            return Enumerable.Repeat<int>(0, size).Select((x, i) => new { i = i, rand = rand.Next() }).OrderBy(x => x.rand).Select(x => x.i).ToArray();
        }

The code creates an array of integers equal to size (Enumerable.Repeat(0, size)) filled with the value zero just to get an array equal to size. So the select creates a two dimensional array where i is the numbers 0 to size and rand is a random number. i doesn't repeat. The code then simply orders two dimensional array by the random number and then extracts the i values only.

Sign up to request clarification or add additional context in comments.

10 Comments

Nice answer. Can you break down what return Enumerable.Repeat<int>(0, size).Select((x, i) => new { i = i, rand = rand.Next() }).OrderBy(x => x.rand).Select(x => x.i).ToArray(); is doing please?
Add explanation in the answer.
This works if I want any number between 1 and 45. However I want it to consistently be random integers between 1 and 45 with the size of the array varying.
You would need to variables One indicating the range of random variables and the other for the number of variables you need. The code would be the same except you would add a Take() method indicating how many numbers you want..
One weakness here is the use of a new instance of Random each time the function InitializeArrayWithNoDuplicates is called. This would lead to crippling bias.
|
0

if you go to Next method's definition you will see

// Exceptions:
//   T:System.ArgumentOutOfRangeException:
//     minValue is greater than maxValue.

and

rng.Next(1, 0);

raise ArgumentOutOfRangeException exception

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.