im trying to create a lottery ticket generator where i have 5 numbers (from 1 to 50) and 2 other numbers (from 1 to 12) called stars. The five numbers cant be the same and the 2 stars cant be the same too (but can be equal to the numbers). I have to make the code in c# and put in a cshtml page with a ViewBag. My output somehow is giving me this: Output
My c# code is:
Random random = new Random();
int number = random.Next();
int[] numbers = new int[5];
int[] stars = new int[2];
bool repeated = false;
int newnumber = 0;
for (int i = 0; i < 5; i )
{
repeated = false;
while (repeated == true)
{
newnumber = random.Next(1, 50);
repeated = numbers.Contains(newnumber);
}
numbers[i] = newnumber;
}
ViewBag.numbers = numbers;
for (int i = 0; i < 2; i )
{
repeated = false;
while (repeated == true)
{
newnumber = random.Next(1, 12);
repeated = stars.Contains(newnumber);
}
stars[i] = newnumber;
}
ViewBag.stars = stars;
return View("MyView");
Then i put this in cshtml so it appear in my website:
<div style="width: 400px; height: 125px; margin: auto">
<div >
<h3 style="text-align:center">Lottery</h3>
<p style="text-align:center">Winning numbers!</p>
<p style="text-align:center">
Nº:@for (int i=0; i <5;i )
{
@Html.Raw(ViewBag.numbers[i] ";")
}
|
<i ></i>:@for (int i=0; i <2;i )
{
@Html.Raw(ViewBag.stars[i] ";")
}
</p>
</div>
</div>
Can you guys help me? I really dont know where is the mistake that makes the lottery ticket have just zeros.
Thank you.
CodePudding user response:
Here:
repeated = false;
while (repeated == true)
It will always skip while
.
CodePudding user response:
You assign repeated == false so it would never go into the while loop. Change the code to do while it should work for you.
do
{
//Create random number
//Check whether it's repeated
newnumber = random.Next(1, 12);
repeated = stars.Contains(newnumber);
}while (repeated == true);
CodePudding user response:
Regenerating numbers if there are repetitions is not very efficient. Try this:
var random = new Random();
var allNumbers = Enumerable.Range(1, 50);
var stars = allNumbers
.OrderBy(x => random.Next())
.Take(2)
.ToArray();
var numbers = allNumbers
.Except(stars)
.OrderBy(x => random.Next())
.Take(5);
CodePudding user response:
There are two typical methods to create unique random k
numbers from n
:
1. Create all n
numbers, shuffle and then take k
of them (this method is efficient when k ~ n
):
// Simplest, Fisher-Yates algorithm is faster
// https://en.wikipedia.org/wiki/Fisher–Yates_shuffle
int[] numbers = Enumerable
.Range(1, n)
.OrderBy(item => random.NextDouble())
.Take(k)
.ToArray();
2. Generare k
random numbers while testing for being unique (do it when k << n
):
HashSet<int> data = new HashSet<int>();
while (data.Count < k)
data.Add(random.Next(1, n 1));
numbers = data.ToArray();
In your case we can extract the method:
private static Random s_Random = new Random();
private static int[] Generate(int count, int total) => Enumerable
.Range(1, total)
.OrderBy(_ => s_Random.NextDouble())
.Take(count)
.ToArray();
Then you can just call the routine:
ViewBag.numbers = Generate(5, 50);
ViewBag.stars = Generate(2, 12);