This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Random number generator in C# - unique values
I'm trying to write a C# program that will generate a random number, check if this number is in my array, if it is, repeat generating the number, else insert this number into slot [i] of my array.
Here is my code so far:
int check = 0;
Random rand = new Random();
int[] lotto = new int[6];
for (int i = 0; i < lotto.Length; )
{
check = rand.Next(1, 41);
while (!(lotto.Contains(check)))
{
lotto[i] = check;
i++;
}
Console.WriteLine("slot " + i + " contains " + check);
}
Console.Read();
}
UPDATE: Thanks figured it out, replaced the if with while :)
I'm Guessing your question is what is not working, I am guessing that you have forgotten one ! and used an undeclared variable i:
if (!lotto.Contains(check)) // Ensure the number has not been chosen
{
lotto[count] = check; // Set the number to its correct place
count=count+1
}
If you want to generate random numbers without repeats, use a FIPS 140-2 validated random number generator (see section 4.9.3 on page 36 of http://www.hhs.gov/ocr/privacy/hipaa/administrative/securityrule/fips1402.pdf).
If this is being used for any serious gaming purpose, as your variable naming suggests, I would recommend something with better randomness than Random.
You can try this:
for (int i = 0; i < lotto.Length;)
{
check = rand.Next(1, 41);
Console.WriteLine("Random number to be checked is -> "+check);
if (!lotto.Contains(check))
{
lotto[i] = check;
i++;
}
Console.WriteLine("slot " + i + " contains " + check);
}
Notice that I have removed i++ from the for statement and has been put inside the if block.
You can try this with other loop constructs also, but this is to have the least amount of edit to your code.
Edit:
Well, I tried the code and seems to be working for me. Here is the complete code:
int check = 0;
int[] lotto = new int[6];
Random rand = new Random();
for (int i = 0; i < lotto.Length; )
{
check = rand.Next(1, 41);
Console.WriteLine("Random number to be checked is -> " + check);
if (!lotto.Contains(check))
{
lotto[i] = check;
i++;
}
Console.WriteLine("slot " + i + " contains " + check);
}
Console.ReadKey();
You can also use the while construct:
int check = 0;
int[] lotto = new int[6];
Random rand = new Random();
int i = 0;
while (i < lotto.Length)
{
check = rand.Next(1, 41);
Console.WriteLine("Random number to be checked is -> " + check);
if (!lotto.Contains(check))
{
lotto[i] = check;
i++;
}
Console.WriteLine("slot " + i + " contains " + check);
}
Console.ReadKey();
Basically, this is functions same as the previous code.
Related
I'm trying to create an array list using random numbers. But sometimes I get a zero in results. I do not understand why.
I'm grateful if anyone can explain.
int[] number = new int[6];
Random rnd = new Random();
for (int i = 0; i < number.Length; i++)
{
int random = rnd.Next(1, 26);
if (!number.Contains(random))
{
number[i] = random;
}
}
foreach (int nr in number)
{
Console.Write("|" + nr + "|");
}
//results
|6||12||0||22||25||11|
int[] number = new int[6];
Here number array is created with default int value i.e 0
The issue with your code is in some cases this value is not getting updated due to the check
if (!number.Contains(random))
You can change your code to include a loop to guarantee your random number doesn't lie in the array.
int[] number = new int[6];
Random rnd = new Random();
for (int i = 0; i < number.Length; i++)
{
int random = rnd.Next(1, 26);
while (number.Contains(random))
{
random = rnd.Next(1, 26);
}
number[i] = random;
}
foreach (int nr in number)
{
Console.Write("|" + nr + "|");
}
Please note that current approach is quite performance hungry as for every new random value we are iterating through entire array everytime to check if it exists. You can reduce the performance by using as HashSet<int> if possible
When you declare the array in following statement it initializes with 6 integers as 0
int[] number = new int[6];
While the random number generated for each array element, check for duplication in following statement may have resulted false
if (!number.Contains(random))
That's why it was never updated to new assigned number.
You can add else condition to it and regenerate random number
Just use your debugger to step through your code and inspect your variables to see what's happening. Apart from all the suggestions here, which are bad because they can loop way too many times or even forever, you appear to want to get 6 random, unique numbers between 1 and 26.
The de facto way to do that, is to generate a list with those numbers (Enumerable.Range()), shuffle them (Fisher-Yates) and Take() the first six.
Use while loop.
int[] number = new int[6];
Random rnd = new Random();
int i = 0;
while (i < number.Length)
{
int random = rnd.Next(1, 26);
if (!number.Contains(random))
{
number[i] = random;
i++;
}
}
foreach (int nr in number)
{
Console.Write("|" + nr + "|");
}
I've created an array which generate 10 random numbers, and I want it to be compared to user input of 10 numbers. If 6 numbers are equal to the random generated numbers (from 1 to 25) then it should show a 6.
Also, the order should not matter. If the user input the number 8 as his or her first selection, it should be able to be compared to the random generated number if it generated number 8 as its last selection. Which in the end should show the result of minimum 1.
Random r = new Random();
int MyRandomNr = r.Next(1, 26);
// Random Generator
var ArrayRandom = new int[] { MyRandomNr, MyRandomNr, MyRandomNr, MyRandomNr, MyRandomNr, MyRandomNr, MyRandomNr, MyRandomNr, MyRandomNr, MyRandomNr };
Console.Write("HELLO AND WELCOME!"
+ System.Environment.NewLine + "Type in 10 numbers."
+ System.Environment.NewLine + "A number between from 1 to 25, one number at the time " + System.Environment.NewLine);
string[] ArrayUser = new string[10];
for (int i = 0; i < 10; i++)
{
Console.Write((i + 1) + ". Next number is: ");
ArrayUser [i] = Console.ReadLine();
}
I've looked through the Stackoverflow and the following code doesn't really compare the two arrays in the way I want it to compare to each other. The following code works more like an exam, but I'm looking for something similar to this...
int[] answer = { 1, 3, 4};
int[] exam = { 4, 1, 3};
int correctAnswers = 0;
int wrongAnswers = 0;
for (int index = 0; index < answer.Length; index++)
{
if (answer[index] == exam[index])
{
correctAnswers += 1;
}
else
{
wrongAnswers += 1;
}
}
Console.Write("The matching numbers are " + correctAnswers +
"\n" + "The non matching numbers are " + wrongAnswers);
This question already has answers here:
Random number generator only generating one random number
(15 answers)
Closed 7 years ago.
I've run into a strange issue. When I run the following code, each of my text boxes get's filled with the same randomly generated number.
public void diceAdd()
{
int[] die = new int[4];
for(int i = 0; i < total.Length; i++)
{
for (int r = 0; r < die.Length; r++)
{
//Simulates rolling a 6 sided die
Random rand = new Random();
randomNumber = rand.Next(1, 7);
die[r] = randomNumber;
}
int smallest = die[0];
for (int c = 1; c < die.Length; ++c)
{
if (die[c] < smallest)
{
smallest = die[c];
}
}
total[i] = die[0] + die[1] + die[2] + die[3] - smallest;
}
strTxt.Text = total[0].ToString();
dexTxt.Text = total[1].ToString();
conTxt.Text = total[2].ToString();
intTxt.Text = total[3].ToString();
wisTxt.Text = total[4].ToString();
chaTxt.Text = total[5].ToString();
The thing is, if I add this messagebox
MessageBox.Show(i.ToString());
after
total[i] = die[0] + die[1] + die[2] + die[3] - smallest;
the numbers each get unique outputs, as intended.
I'm thinking it has something to do with threading, but figured I'd ask here before messing something up.
you are recreating the random number generator every time in the loop, create one before the loop:
Random rand = new Random();
for(int i = 0; i < total.Length; i++)
{
...
}
see also here and here, it explains why the numbers don't change
wrote a program to calculate and display the first 20 fibonacci numbers, the sequence goes as follows:
1, 1, 2, 3, 5, 8, 13... (each number is the sum of the previous two numbers)
The problem is that the numbers that get displayed are from 2 onwards , the first and second numbers of the sequence do not get displayed , could someone tell me what needs to be done to correct this?
Code:
private void button1_Click(object sender, EventArgs e)
{
int previousNumber = 1;
int currentNumber = 1;
int nextNumber = 1;
while (currentNumber <= 11000)
{
nextNumber = previousNumber + currentNumber;
previousNumber = currentNumber;
currentNumber = nextNumber;
textBox1.AppendText(Convert.ToString(nextNumber) + " ");
nextNumber++;
}
}
I suggest carefully tracing through the logic and predicting what the computer will do at each step. Since the bug affects the very first output, you won't have to look at very many statements to encounter the problem. This is a basic skill for a programmer, so it will be well worth the time, especially since this sounds like homework.
Initially you need to display the current number twice before next number calculation. Also you need to move the number display before the next number calculation. Also next number should be previous number + currentNumber. I have made the changes to your code below which should work.
private void button1_Click(object sender, EventArgs e)
{
int previousNumber = 1;
int currentNumber = 1;
int nextNumber = 1;
textBox1.AppendText(Convert.ToString(currentNumber) + " ");
while (currentNumber <= 11000)
{
textBox1.AppendText(Convert.ToString(currentNumber) + " ");
nextNumber = previousNumber + currentNumber;
previousNumber = currentNumber;
currentNumber = nextNumber;
nextNumber = previousnNumber + currentNumber;
}
}
Since the first two digits in a Fibonacci are the seed values (1 and 1 or 0 and 1) you should print those first and then calculate the next values.
I would simplify the code. You can test it out at https://dotnetfiddle.net/3cV96L
int initialSeed = 1;
int currentNumber = 1;
//Write seed values
Console.Write("{0} {1} ", initialSeed, currentNumber);
while (currentNumber <= 11000)
{
currentNumber += currentNumber;
Console.Write(currentNumber + " ");
}
Just change int currentNumber = 0;
System.Random generator = new Random(DateTime.Now.Millisecond);
int[] lotteryNumber = new int[7];
Console.WriteLine("Your lottery numbers: ");
for (int i = 0; i<7; i++)
{
lotteryNumber[i] = generator.Next(1, 37);
Console.Write("{0} ",lotteryNumber[i]);
}
Console.ReadLine();
I need to make a program that prints 7 lottery numbers, but without duplicates. The code above prints 7 random numbers in the range of (1-37), but duplicates appaer. I need a way to prevent duplicate numbers from appearing.
The simplest approach IMO would be to generate a sequence of all the possible numbers (i.e. 1-37), shuffle the collection, then take the first seven results.
Searching on Stack Overflow for "Fisher-Yates shuffle C#" will find lots of examples.
In fact, you could modify the Fisher-Yates shuffle to yield results as you took them, so you could write a method such as:
var numbers = Enumerable.Range(1, 37).Shuffle().Take(7).ToList();
You could take a dictionary but make sure that you prevent duplicate key insertion. Keys of dictionary would serve as the unique numbers you need
You could toss them into a HashSet<int>. If you Add and it returns false, generate a new number.
If you're trying to pick numbers from a range without repetitions, you need to create an array of all the possible numbers and then "shuffle" a random selection out:
int[] allPossibleNumbers = Enumerable.Range(1, 37).ToArray();
int[] lotteryNumber = new int[7];
for (int i = 0; i < 7; i++)
{
int index = r.Next(i, 37);
lotteryNumber[i] = allPossibleNumbers[index];
allPossibleNumbers[index] = allPossibleNumbers[i];
// This step not necessary, but allows you to reuse allPossibleNumbers
// rather than generating a fresh one every time.
// allPossibleNumbers[i] = lotteryNumber[i];
}
Generate a list with your 37 items.
Then in your for, select one and delete the selected
Maybe this could help, if you get the existing number just try to find new one that isn't in the array:
static void Main(string[] args)
{
System.Random generator = new Random(DateTime.Now.Millisecond); int[] lotteryNumber = new int[7];
Console.WriteLine("Your lottery numbers: ");
for (int i = 0; i < 7; i++)
{
int lNumber = 0;
do
{
lNumber = generator.Next(1, 37);
}
while (lotteryNumber.Contains(lNumber));
lotteryNumber[i] = lNumber;
Console.Write("{0} ", lotteryNumber[i]);
}
Console.ReadLine();
}
HashSet<int> set = new HashSet<int>();
System.Random generator = new Random(DateTime.Now.Millisecond);
while(set.Count < 7){
set.Add(generator.Next(1,37);
}
That should work, since a HashSet will automatically ignore duplicates. Just loop until the set reaches the number of units you need. Only potential problem is it has the POTENTIAL (unlikely) to loop for a long time, but it should eventually respond.
so I took your original code...found some logic errors and added the fix you were looking for to prevent random number duplicates.
Enjoy!
System.Random generator = new Random(DateTime.Now.Millisecond);
int[] lotteryNumber = new int[7];
int lowerBounds = 1;
int upperBounds = 8;
int maxNumberLotteryValues = 7;
if ( ( upperBounds - lowerBounds ) < (maxNumberLotteryValues))
{
Console.Write("Warning: Adjust your upper and lower bounds...there are not enough values to create a unique set of Lottery numbers! ");
}
else
{
Console.WriteLine("Your lottery numbers: ");
for (int i = 0; i < maxNumberLotteryValues; i++)
{
int nextNumber = generator.Next(lowerBounds, upperBounds);
int count = lowerBounds; //Prevent infinite loop
while ((lotteryNumber.Contains(nextNumber))
&& (count <= upperBounds))
{
nextNumber = generator.Next(lowerBounds, upperBounds);
count++; //Prevent infinite loop
}
lotteryNumber[i] = nextNumber;
Console.Write("{0} ", lotteryNumber[i]);
}
}
Console.ReadLine();
const int nBalls = 37;
const int nPicks = 6;
int[] balls = new int[nPicks];
Random rnd = new Random(DateTime.Now.Millisecond);
int remainingBalls=nBalls;
int remainingPicks=nPicks;
for (int i = 1; i <= nBalls; i++)
{
if (rnd.Next(1, remainingBalls+1) <= remainingPicks)
balls[--remainingPicks]=i;
remainingBalls--;
}
Console.WriteLine(string.Join(",",balls));
Will outperform Shuffle and HashSet methods as nPicks/nBalls gets larger.