Generating random numbers without repeating.C# [duplicate] - c#

This question already has answers here:
Random number generator with no duplicates
(12 answers)
Closed 2 years ago.
Hi everyone I am trying to generate 6 different numbers on the same line in c# but the problem that i face is some of the numbers are repeating on the same line.Here is my code to
var rand = new Random();
List<int> listNumbers = new List<int>();
int numbers = rand.Next(1,49);
for (int i= 0 ; i < 6 ;i++)
{
listNumbers.Add(numbers);
numbers = rand.Next(1,49);
}
somewhere my output is
17 23 23 31 33 48

Check each number that you generate against the previous numbers:
List<int> listNumbers = new List<int>();
int number;
for (int i = 0; i < 6; i++)
{
do {
number = rand.Next(1, 49);
} while (listNumbers.Contains(number));
listNumbers.Add(number);
}
Another approach is to create a list of possible numbers, and remove numbers that you pick from the list:
List<int> possible = Enumerable.Range(1, 48).ToList();
List<int> listNumbers = new List<int>();
for (int i = 0; i < 6; i++)
{
int index = rand.Next(0, possible.Count);
listNumbers.Add(possible[index]);
possible.RemoveAt(index);
}

listNumbers.AddRange(Enumerable.Range(1, 48)
.OrderBy(i => rand.Next())
.Take(6))

Create a HashSet and generate a unique random numbers
public List<int> GetRandomNumber(int from,int to,int numberOfElement)
{
var random = new Random();
HashSet<int> numbers = new HashSet<int>();
while (numbers.Count < numberOfElement)
{
numbers.Add(random.Next(from, to));
}
return numbers.ToList();
}

Make it a while loop and add the integers to a hashset. Stop the loop when you have six integers.

Instead of using a List, you should use an HashSet. The HashSet<> prohibites multiple identical values. And the Add method returns a bool that indicates if the element was added to the list, Please find the example code below.
public static IEnumerable<int> GetRandomNumbers(int count)
{
HashSet<int> randomNumbers = new HashSet<int>();
for (int i = 0; i < count; i++)
while (!randomNumbers.Add(random.Next()));
return randomNumbers;
}

I've switched your for loop with a do...while loop and set the stopping condition on the list count being smaller then 6.
This might not be the best solution but it's the closest to your original code.
List<int> listNumbers = new List<int>();
do
{
int numbers = rand.Next(1,49);
if(!listNumbers.Contains(number)) {
listNumbers.Add(numbers);
}
} while (listNumbers.Count < 6)

The best approach (CPU time-wise) for such tasks is creating an array of all possible numbers and taking 6 items from it while removing the item you just took from the array.
Example:
const int min = 1, max = 49;
List<int> listNumbers = new List<int>();
int[] numbers = new int[max - min + 1];
int i, len = max - min + 1, number;
for (i = min; i < max; i++) numbers[i - min] = i;
for (i = 0; i < 6; i++) {
number = rand.Next(0, len - 1);
listNumbers.Add(numbers[number]);
if (number != (len - 1)) numbers[number] = numbers[len - 1];
len--;
}

If you are not worried about the min, max, and range then you can use this.
var nexnumber = Guid.NewGuid().GetHashCode();
if (nexnumber < 0)
{
nexnumber *= -1;
}

What you do is to generate a random number each time in the loop. There is a chance of course that the next random number may be the same as the previous one. Just add one check that the current random number is not present in the sequence. You can use a while loop like: while (currentRandom not in listNumbers): generateNewRandomNumber

Paste the below in the class as a new method
public int randomNumber()
{
var random = new Random();
int randomNumber = random.Next(10000, 99999);
return randomNumber;
}
And use the below anywhere in the tests wherever required
var RandNum = randomNumber();
driver.FindElement(By.CssSelector("[class='test']")).SendKeys(**RandNum**);

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
int[] que = new int[6];
int x, y, z;
Random ran = new Random();
for ( x = 0; x < 6; x++)
{
que[x] = ran.Next(1,49);
for (y = x; y >= 0; y--)
{
if (x == y)
{
continue;
}
if (que[x] == que[y])
{
que[x] = ran.Next(1,49);
y = x;
}
}
}
listBox1.Items.Clear();
for (z = 0; z < 6; z++)
{
listBox1.Items.Add(que[z].ToString());
}
}
}

Related

Creating an array of 10 elements and assigning them by counting randomly

Creating an array of 10 elements and assigning them by counting randomly, assigning a new number if the same numbers are repeated
I tried to use the contains method but it didn't appear in the list after the array, I used the exists method but it didn't work either, what kind of way should I follow? thanks
static void Main(string[] args)
{
Random Rnd = new Random();
int[] Numbers = new int[10];
for (int i = 0; i < Numbers.Length; i++)
{
int rast = Rnd.Next(10);
bool b = Array.Exists(Numbers, element => element == rast);
if (!b)
{
i--;
}
else { Numbers[i] = rast; }
}
foreach (int item in Numbers)
{
Console.WriteLine(item);
}
}
It appears that you want the numbers from 0 to 9 in an array in random order. If that is so:
var rng = new Random();
var numbers = Enumerable.Range(0, 10).OrderBy(n => rng.NextDouble()).ToArray();
You're close, but there are two issues in your algorithm:
if (!b) should be if (b)
Rnd.Next(1,10) gets numbers between 1 and 9 so you will never get a 10 and the algorithm will never finish.
After fixing these two your program will work.
Anyway, here's a version that uses .Contains
Random Rnd = new Random();
int[] Numbers = new int[10];
for (int i = 0; i < Numbers.Length; i++)
{
// + 1 because the range of return values includes minValue but not maxValue.
int r = Rnd.Next(minValue: 1, maxValue: Numbers.Length + 1);
while(Numbers.Contains(r))
{
r = Rnd.Next(minValue: 1, maxValue: Numbers.Length + 1);
}
Numbers[i] = r;
}
Console.WriteLine(string.Join(",", Numbers));
Example output:
9,8,7,1,4,6,3,10,5,2
Here's an example. I hope this is the output you want.
public static void Main()
{
Random Rnd = new Random();
int[] Numbers = new int[10];
for (int i = 0; i < Numbers.Length; i++)
{
int rast = Rnd.Next(10);
bool b = Array.Exists(Numbers, element => element == rast);
if (!b)
{
Numbers[i] = rast;
Console.WriteLine(rast);
}
else {
i--;
}
}
}
As a result, I have found the solution, thanks to everyone who answered and showed me the way
int[] Numbers = new int[10];
int x, y;
Random ran = new Random();
for (x = 0; x < 10; x++)
{
Numbers[x] = ran.Next(1, 10);
for (y = x; y >= 0; y--)
{
if (x == y)
{
continue;
}
if (Numbers[x] == Numbers[y])
{
Numbers[x] = ran.Next(1, 10);
y = x;
}
}
Console.WriteLine(Numbers[x]);
}
when i created new project as Console .net in visual studio 2019 ,
it doesnt bring this libraries automatically ,
Because the following libraries are not attached, the codings I used before did not work, I developed another simple solution, and in this way, I realized that I had a problem due to these libraries not being attached.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
int[] Numbers= new int[10];
Random rnd = new Random();
for (int i = 0; i < Numbers.Length; i++)
{
int Num= rnd.Next(10);
if (Numbers.Contains(Num))
{
i--;
}
else
{
Console.WriteLine(Numbers[i] = Num);
}
}

How can I make so that my Values dont repeat with Random.Range()? [duplicate]

Basically I'm creating a program to randomly generate 6 unique lottery numbers so there is no duplicates in the same line, here is the code I have so far...
//Generate 6 random numbers using the randomiser object
int randomNumber1 = random.Next(1, 49);
int randomNumber2 = random.Next(1, 49);
int randomNumber3 = random.Next(1, 49);
int randomNumber4 = random.Next(1, 49);
int randomNumber5 = random.Next(1, 49);
int randomNumber6 = random.Next(1, 49);
textBox1.Text = randomNumber1.ToString();
textBox2.Text = randomNumber2.ToString();
textBox3.Text = randomNumber3.ToString();
textBox4.Text = randomNumber4.ToString();
textBox5.Text = randomNumber5.ToString();
textBox6.Text = randomNumber6.ToString();
}
I'm getting random numbers but sometimes there is the same number on the same line, how do I make each number unique????
Thanks in advance
You need to store them in a collection and each time you pick a new number you need to make sure it's not present already, otherwise you need to generate a new number until you find a unique number.
Instead of this, I would generate a sequence between 1 and 49, shuffle them and pick 6 number out of the sequence, for example:
var rnd = new Random();
var randomNumbers = Enumerable.Range(1,49).OrderBy(x => rnd.Next()).Take(6).ToList();
You can't. You've only specified that each number be a random number from 1 to 49, not that it shouldn't match any duplicates.
Since you've got a relatively small set of numbers, your best bet is probably to draw the random numbers, put them into a HashSet, then if you need more, pull more. Something like this:
HashSet<int> numbers = new HashSet<int>();
while (numbers.Count < 6) {
numbers.Add(random.Next(1, 49));
}
Here you're taking advantage of the HashSet's elimination of duplicates. This won't work with a List or other collection.
Returning repeat values is a necessity in order for a generator to satisfy a necessary statistical property of randomness: the probability of drawing a number is not dependent on the previous numbers drawn.
You could shuffle the integers in the range 1 to 49 and return the first 6 elements. See http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle for more details on such a shuffler.
However, I think you get a slight statistical bias by doing this.
The best way is probably to use random.Next(1, 49); and reject any repeat. That will be free from statistical bias and the fact that you're only wanting 6 from 49 possibilities, the number of collisions will not slow the algorithm appreciably.
Using this extension method for reservoir sampling:
public static IList<T> TakeRandom<T>(
this IEnumerable<T> source, int count, Random random)
{
var list = new List<T>(count);
int n = 1;
foreach (var item in source)
{
if (list.Count < count)
{
list.Add(item);
}
else
{
int j = random.Next(n);
if (j < count)
{
list[j] = item;
}
}
n++;
}
return list;
}
You can sample your collection like this:
var random = new Random();
var numbers = Enumerable.Range(1, 49).TakeRandom(6, random);
numbers.Shuffle(random);
Note the returned numbers will be uniformly sampled out of all (49 choose 6) possibilities for a set of 6 numbers out of {1, 2, ..., 49}, but they will neither remain in order nor be uniformly shuffled. If you want to have the order randomized as well, you can easily do a standard Fisher-Yates shuffle afterwards.
public static void Shuffle<T>(this IList<T> list, Random random)
{
for (int i = 0; i < list.Count; i++)
{
int j = random.Next(i, list.Count);
T temp = list[j];
list[j] = list[i];
list[i] = temp;
}
}
Note a more heavily optimized version of Fisher-Yates shuffle can be found in this answer: Randomize a List<T>
List<int> aux = new List<int>();
while(aux.Count < 6)
{
int rnd = random.Next(1,49);
if(!aux.Contains(rnd))aux.add(rnd);
}
if you put all Texbox in the same panel you can do that
int j = 0;
foreach(Control x in MyPanel.Controls)
{
if(x is TexBox)
{
x.Text = aux[j].toString();
j++;
}
}
It's my solution: generate array of number
/// <summary>
/// auto generate a array with number element and max value is max
/// </summary>
/// <param name="number">number element of array</param>
/// <param name="max">max value of array</param>
/// <returns>array of number</returns>
public static int[] createRandomArray(int number, int max)
{
List<int> ValueNumber = new List<int>();
for (int i = 0; i < max; i++)
ValueNumber.Add(i);
int[] arr = new int[number];
int count = 0;
while (count < number)
{
Random rd = new Random();
int index = rd.Next(0,ValueNumber.Count -1);
int auto = ValueNumber[index];
arr[count] = auto;
ValueNumber.RemoveAt(index);
count += 1;
}
return arr;
}
It's too late but I use a Method named M_Randomizer created by me. It may look as too much work, but it's technique is different from traditional which is based on generating a random number and checking the previously generated list for uniqueness. This code while generating a new random number, never looks for the previously generated. And if we talk about touching all combinations, I have tested this method till 9 factorial, maybe little bias for some but it touches all.
using System;
class Randomizer
{
public int[] M_Randomizer(int x)
{
bool b = false;
if (x < -1)
{
b = true;
x = -1 * x;
}
if(x == -1)
x = 0;
if (x < 2)
return new int[x];
int[] site;
int k = new Random(Guid.NewGuid().GetHashCode()).Next() % 2;
if (x == 2)
{
site = new int[2];
site[0] = k;
site[1] = 1 - site[0];
return site;
}
else if (x == 3)
{
site = new int[3];
site[0] = new Random(Guid.NewGuid().GetHashCode()).Next(0, 3);
site[1] = (site[0] + k + 1) % 3;
site[2] = 3 - (site[0] + site[1]);
return site;
}
site = new int[x];
int a = 0, m = 0, n = 0, tmp = 0;
int[] p = M_Randomizer(3);
int[] q;
if (x % 3 == 0)
q = M_Randomizer(x / 3);
else
q = M_Randomizer((x / 3) + 1);
if (k == 0)
{
for (m = 0; m < q.Length; m++)
{
for (n = 0; n < p.Length && a < x; n++)
{
tmp = (q[m] * 3) + p[n];
if (tmp < x)
{
site[a] = tmp;
a++;
}
}
}
}
else
{
while (n < p.Length)
{
while (a < x)
{
tmp = (q[m] * 3) + p[n];
if (tmp < x)
{
site[a] = tmp;
a++;
}
m = m + k;
if (m >= q.Length)
break;
}
m = m % q.Length;
n++;
}
}
a = (new Random(Guid.NewGuid().GetHashCode()).Next() % 2) + 1;
k = new Random(Guid.NewGuid().GetHashCode()).Next() % 10;
if (k > 5)
for (int i = a; i < k; i++)
while (a < site.Length)
{
if (k % (a + 1) == 0)
{
tmp = site[a - 1];
site[a - 1] = site[a];
site[a] = tmp;
}
a = a + 2;
}
k = new Random(Guid.NewGuid().GetHashCode()).Next() % 10;
if (k > 5)
{
n = x / 2;
k = 0;
if (x % 2 != 0)
k = (new Random(Guid.NewGuid().GetHashCode()).Next() % 2);
p = new int[n + k];
m = (x - n) - k;
for (a = 0; m < x; a++, m++)
p[a] = site[m];
m = n + k;
for (a = (x - m) - 1; a >= 0; a--, m++)
site[m] = site[a];
for (a = 0; a < p.Length; a++)
site[a] = p[a];
}
int[] site2;
int[] site3 = new int[x];
if (b)
return site;
else
site2 = M_Randomizer(-1 * x);
for (a = 0; a < site.Length; a++)
site3[site2[a]] = site[a];
return site3;
}
public int[] M_Randomizer(int x, int start)
{
int[] dm = M_Randomizer(x);
for(int a = 0; a < x; a++)
dm[a] = dm[a] + start;
return dm;
}
}
Look at using an array to hold your 6 numbers.
Each time you generate one, loop through the array to make sure it is not already there. If it is, then generate another & loop again until you have a non-match.
It's so easy with array and OOP (Object Oriented Programming). Before you start you have to add Linq (using System.Linq) library to your project.
Random random = new Random();
int[] array = new int[6];
int number;
for (int i = 0; i < 6; i++)
{
number = random.Next(1, 50);
if (!array.Contains(number)) //If it's not contains, add number to array;
array[i] = number;
else //If it contains, restart random process
i--;
}
for (int i = 1; i < 7; i++)
{
foreach (Control c in this.Controls) //Add random numbers to all Textboxes
{
if (c is TextBox && c.Name.EndsWith(i.ToString()))
{
c.Text = array[i - 1].ToString();
}
}
}
A functional approach could be to generate an infinite sequence of random numbers, filter out non-unique numbers and take the number of unique numbers you need.
For example:
private IEnumerable<int> RandomDigitStream(int seed)
{
Random random = new Random(seed);
while (true)
{
yield return random.Next(DIGIT_MIN, DIGIT_MAX);
}
}
private List<int> GenerateUniqueRandomNumbers(int seed, int count)
{
// Assert that DIGIT_MAX - DIGIT_MIN > count to ensure
// algorithm can finish
return RandomDigitStream(seed)
.Distinct()
.Take(count)
.ToList();
}
The efficiency of this algorithm is mainly dependent on how Distinct is implemented by the .NET team. Its memory usage would grow with the number of digits you require and the range of digits produced by the random function. It also has an unpredictable running time as it depends on the probability distribution of the random function. In fact it is possible for this algorithm to get stuck in an infinite loop if the range of digits produced by the random algorithm is less than the number of digits you require.
Looking at it practically however, it should be fine for a small amount of digits but if you are looking at a large number (100 +) you might want to look at other methods.
It would be more efficient to craft a random algorithm that only produces unique numbers in the first place if that is even possible without using a lookup table.
Here is a small program using recursion to generate number lines, and also uses recursion to randomize and get unique numbers.
using System;
using System.Linq;
using System.Collections.Generic;
public class Program
{
public static Random random;
public static List<int> lottoNumbers = Enumerable.Range(1, 49).ToList();
public static void Main()
{
random = new Random((int)DateTime.Now.Ticks);
var LinesToGenerate = 10;
GenerateNumbers(LinesToGenerate);
}
public static void GenerateNumbers(int LineCount)
{
int[] SelectedNumbers = new int[6];
for (var i = 0; i < 6; i++)
{
var number = GetRandomNumber(lottoNumbers.ToArray());
while (SelectedNumbers.Contains(number))
number = GetRandomNumber(lottoNumbers.ToArray());
SelectedNumbers[i] = number;
}
var numbersOrdered = SelectedNumbers.OrderBy(n => n).Select(n => n.ToString().PadLeft(2, '0'));
Console.WriteLine(string.Join(" ", numbersOrdered));
if (LineCount > 1)
GenerateNumbers(--LineCount);
}
//Recursively and randomly removes numbers from the array until only one is left, and returns it
public static int GetRandomNumber(int[] arr)
{
if (arr.Length > 1)
{
//Remove random number from array
var r = random.Next(0, arr.Length);
var list = arr.ToList();
list.RemoveAt(r);
return GetRandomNumber(list.ToArray());
}
return arr[0];
}
}
Yes. Use array.
Loop how many times you want:
Generate a random number,
Loop through array and compare all with the generated number.
If there's a match then loop again till there's no match.
Then store it.
Done:)

Lottery program that generates 6 random numbers between 1 and 59 C#

I have created a simple program which randomly generates 6 winning numbers. While the program works, I would also like for it to ensure that the same number isn't outputted twice as well as sorting them into numerical order when outputted. How would I go about doing such a thing while sticking to similar techniques already used? My code is down below. Any help is very much appreciated.
int temp;
int[] lotto = new int[6];
Random rand = new Random();
for (int i = 0; i < 6; i++)
{
temp = rand.Next(1, 59);
lotto[i] = temp;
}
Console.Write($"The lotterry winning numbers are: ");
for (int i = 0; i < 6; i++)
{
Console.Write(lotto[i] + " ");
}
Console.ReadKey();
Based on a Fisher-Yates shuffle, but saves some work because we know we don't need all the values (if we only need 6 values out of 10 million potentials, we only need to take the first six iterations of the fisher-yates algorithm).
public IEnumerable<int> DrawNumbers(int count, int MaxNumbers)
{
var r = new Random(); //ideally, make this a static member somewhere
var possibles = Enumerable.Range(1, MaxNumbers).ToList();
for (int i = 0; i < count; i++)
{
var index = r.Next(i, MaxNumbers);
yield return possibles[index];
possibles[index] = possibles[i];
}
}
var lottoNumbers = DrawNumbers(6, 59);
Console.Write("The lotterry winning numbers are: ");
Console.WriteLine(string.Join(" ", lottoNumbers.OrderBy(n => n)));
See it work here:
https://dotnetfiddle.net/NXYkpU
You can use Linq to create sequence [1..59] and order it by random to shuffle it.
Random rand = new Random();
var winners = Enumerable.Range(1, 59)
.OrderBy(x => rand.Next())
.Take(6)
.OrderBy(x => x)
.ToList();
Console.WriteLine(String.Join(" ", winners));
int temp;
int[] lotto = new int[6];
Random rand = new Random();
int i = 0;
while(i < 6)
{
temp = rand.Next(1, 59);
//check if lotto contains just generated number, if so skip that number
bool alreadyExist = false;
foreach (int item in lotto)
{
if (item == temp)
{
alreadyExist = true;
break;
}
}
if (alreadyExist)
continue;
lotto[i] = temp;
i++;
}
Console.Write($"The lotterry winning numbers are: ");
// Sort array in ascending order.
Array.Sort(lotto);
for (int j = 0; j < 6; j++)
{
Console.Write(lotto[j] + " ");
}
Console.ReadKey();
I would probably do it Dmitri's way because it is quick and obvious and performance isn't that important with an array this size.
But just for fun, this is slightly more efficient.
IEnumerable<int> GetNumbers(int min, int max, int count)
{
var random = new Random();
var size = max - min + 1;
var numbers = Enumerable.Range(min, size).ToArray();
while (count > 0)
{
size--;
var index = random.Next(0, size);
yield return numbers[index];
numbers[index] = numbers[size];
count--;
}
}
This solution creates an array containing all possible values and selects them randomly. Each time a selection is made, the array is "shrunk" by moving the last element to replace the element that was chosen, preventing duplicates.
To use:
var numbers = GetNumbers(1, 59, 6).ToList();
foreach (var number in numbers.OrderBy(x => x))
{
Console.WriteLine(number);
}

Generate and store 7 random numbers in a array

I made a program to generate 7 random numbers for a lottery using a array. I have generated a random number between 1, 50 but every number shows in order and not on the same line. I would also like to store the auto generated numbers in a array to use. I am not sure how to fix this any help would be appreciated
static void AutoGenrateNumbers()
{
int temp;
int number = 0;
int[] lotto = new int[7];
Random rand = new Random();
for (int i = 0; i <= 50; i++)
{
number = 0;
temp = rand.Next(1, 50);
while (number <= i)
{
if (temp == number)
{
number = 0;
temp = rand.Next(1, 50);
}
else
{
number++;
}
}
temp = number;
Console.WriteLine($"the new lotto winning numbers are:{number}Bonus:{number}");
}
}
Is this what you need?
static void AutoGenrateNumbers()
{
int temp;
int[] lotto = new int[7];
Random rand = new Random();
for (int i = 0; i < 7; i++)
{
temp = rand.Next(1, 50);
lotto[i]= temp;
}
Console.Write($"the new lotto winning numbers are: ");
for (int i = 0; i < 6; i++)
{
Console.Write(lotto[i]+" ");
}
Console.Write($"Bonus:{lotto[6]}");
}
edit: if you want the numbers to be unique:
static void AutoGenrateNumbers()
{
int temp;
int[] lotto = new int[7];
Random rand = new Random();
for (int i = 0; i < 7; i++)
{
do
{
temp = rand.Next(1, 50);
}
while (lotto.Contains(temp));
lotto[i]= temp;
}
Console.Write($"the new lotto winning numbers are: ");
for (int i = 0; i < 6; i++)
{
Console.Write(lotto[i]+" ");
}
Console.Write($"Bonus:{lotto[6]}");
}
A better way to do this is just to generate all the numbers 1-50, shuffle them and then just take 7. Using Jon Skeet's Shuffle extension method found here:
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng)
{
T[] elements = source.ToArray();
for (int i = elements.Length - 1; i >= 0; i--)
{
int swapIndex = rng.Next(i + 1);
yield return elements[swapIndex];
elements[swapIndex] = elements[i];
}
}
Now your code is very simple:
static void AutoGenrateNumbers()
{
var lotto = Enumerable.Range(0, 50).Shuffle(new Random()).Take(7);
Console.WriteLine("the new lotto winning numbers are: {0}", string.Join(",", lotto));
}
Fiddle here
Just to add to the existing answers tried to do that in one LINQ statement:
static void Main(string[] args)
{
var rand = new Random();
Enumerable
.Range(1, 7)
.Aggregate(new List<int>(), (x, y) =>
{
var num = rand.Next(1, 51);
while (x.Contains(num))
{
num = rand.Next(1, 51);
}
x.Add(num);
return x;
})
.ForEach(x => Console.Write($"{x} "));
}
The result is something like:
34 24 46 27 11 17 2

How to make this code work without repeating the numbers? [duplicate]

This question already has answers here:
Randomize a List<T>
(28 answers)
Closed 9 years ago.
I need to print numbers from 1 to 50 in random order without repeating
it .
static void Main(string[] args)
{
ArrayList r = new ArrayList();
Random ran = new Random();
for (int i = 0; i < 50; i++)
{
r.Add(ran.Next(1,51));
}
for (int i = 0; i < 50; i++)
Console.WriteLine(r[i]);
Console.ReadKey();
}
What you want here is the Fisher Yates Shuffle
Here is the algorithm as implemented by Jeff Atwood
cards = Enumerable.Range(1, 50).ToList();
for (int i = cards.Count - 1; i > 0; i--)
{
int n = ran.Next(i + 1);
int temp = cards[i];
cards[i] = cards[n];
cards[n] = temp;
}
If you don't want to repeat the numbers between 1 and 50, your best bet is to populate a list with the numbers 1 to 50 and then shuffle the contents. There's a good post on shuffling here:
Randomize a List<T>
All you need to do is this check if the number already exists in the list and if so get another one:
static void Main(string[] args)
{
ArrayList r = new ArrayList();
Random ran = new Random();
int num = 0;
for (int i = 0; i < 50; i++)
{
do { num = ran.Next(1, 51); } while (r.Contains(num));
r.Add(num);
}
for (int i = 0; i < 50; i++)
Console.WriteLine(r[i]);
Console.ReadKey();
}
Edit: This will greatly increase the effeciency, preventing long pauses waiting for a non-collision number:
static void Main(string[] args)
{
List<int> numbers = new List<int>();
Random ran = new Random();
int number = 0;
int min = 1;
int max = 51;
for (int i = 0; i < 50; i++)
{
do
{
number = ran.Next(min, max);
}
while (numbers.Contains(number));
numbers.Add(number);
if (number == min) min++;
if (number == max - 1) max--;
}
for (int i = 0; i < 50; i++)
Console.WriteLine(numbers[i]);
Console.ReadKey();
}

Categories