I want to select a random number from 1 to 99. And then select the number again but this time discard the previous number. Can someone help me.
private List<int> numbers = Enumerable.Range(0, 100).ToList();
private Random rnd = new Random();
public int GetRandomInt()
{
var index = rnd.Next(0, numbers.Length);
var number = numbers[index];
numbers.RemoveAt(index);
return number;
}
Here's what I'd do:
var rnd = new Random();
var numbers = new Stack<int>(Enumerable.Range(1, 99).OrderBy(x => rnd.Next()));
You effectively are randomizing the list of numbers and then adding them to a stack. Now you just have to do this to get each number:
var next = numbers.Pop()
You stop when numbers.Count == 0. Simple.
Here is the revised version of Khanh TO, because it is not correct:
List<int> usedNumbers = new List<int>();
Random rand = new Random(new object().GetHashCode());
int number = 0;
for (int i = 0; i < 99; i++)
{
do
{
number = 1 + rand.Next(0, 99);
} while (usedNumbers.Contains(number));
usedNumbers.Add(number);
}
I usually do it with arrays.
Whenever you create a random number just put on the array. so next time check if the number is already generated by checking in the array.
Try this
IList<int> arr = Enumerable.Range(1, 99).ToList();
int randNum;
Random rnd = new Random();
randNum = rnd.Next(1, arr.Count());
MessageBox.Show(randNum.ToString());
arr = arr.Where(x => x != randNum).ToList();
Can I go for the shortest code, without a nested loop, or removing list elements.
Code 1
class Program
{
static Random rnd=new Random();
static void Main(string[] args)
{
var list=new SortedDictionary<double, int>();
// Fill list
for (int i=1; i<=99; i++)
{
list.Add(rnd.NextDouble(), i);
}
// List Automatically random
var random_int=list.Values.ToArray();
// random_int = {45, 7, 72, .. }
}
}
Code 2
class Program
{
static Random rnd=new Random();
static void Main(string[] args)
{
var list=new int[99];
// Fill list
for (int i=1; i<=99; i++)
{
list[i-1]=i;
}
Comparison<int> any=(x, y) =>
{
var z=2*rnd.NextDouble()-1;
return z.CompareTo(0);
};
// Randomize List
Array.Sort(list, any);
// list = { 49, 59, 21, 7, 18 ...}
}
}
Related
The program will generate a sequence of randomly chosen numbers between 1 – 100. The sequence will consist of 20 elements.
Your program should display the sequence once it is generated.
Then, it will display all prime numbers within this sequence.
The code so far:
class Program
{
int[] rnum = new int[100];
int[] selecting = new int[20];
static void Main(string[] args)
{
Program myProgram = new Program();
myProgram.Numbers();
myProgram.PrimeN();
Console.ReadLine();
}
public void Numbers()
{
int[] rnum = new int[100];
// Filling the array with values 1 to 100:
for (int i = 0; i < rnum.Length; i++)
{
rnum[i] = i + 1;
}
// Shuffling the elements of the array:
Random rnd = new Random();
for (int i = 0; i < rnum.Length; i++)
{
int j = rnd.Next(i, rnum.Length);
int temp = rnum[i];
rnum[i] = rnum[j];
rnum[j] = temp;
}
// Selecting and presenting 20 numbers:
int[] selecting = new int[20];
for (int i = 0; i < 20; i++)
selecting[i] = rnum[i];
selecting.ToList().ForEach(i => Console.Write(i.ToString() + ", "));
Console.WriteLine();
}
public void PrimeN()
{
List<int> primeNumbers = new List<int>();
for (int i = 0; i < selecting.Length; i++)
{
if (IsPrime(selecting[i]))
{
primeNumbers.Add(selecting[i]);
}
}
Console.Write("Non-Prime Numbers:");
for (int i = 0; i < primeNumbers.Count; i++)
{
Console.Write(primeNumbers[i] + " ");
}
}
bool IsPrime(int number)
{
for (int i = 2; i < Math.Sqrt(number); i++)
{
if (number % i == 0) return false;
}
return true;
}
}
}
You created local variable called selecting inside Numbers() function. Scope of this local variable is within Numbers() function.
When you are trying to read same variable in PrimeN(), it is referring to the globally defined selecting variable.
As there is nothing stored in global selecting variable you are getting 0 as result in primeNumbers array.
To Solve this issue, do not create local variable called selecting inside Numbers() function, use globally defined variable i.e. selecting defined at class level
...
public void Numbers()
{
...
// Selecting and presenting 20 numbers:
//COMMENT BELOW LINE
//int[] selecting = new int[20];
for (int i = 0; i < 20; i++)
selecting[i] = rnum[i]; //This will refer member which is defined globally
selecting.ToList().ForEach(i => Console.Write(i.ToString() + ", "));
Console.WriteLine();
}
The first problem I see, is you are creating local variables, instead of using the instance members you have declared, after your method runs, nothing gets changed... it all happened locally in the method.
Comment out the below lines, you have already declared them
public static void Numbers(int size)
{
//int[] rnum = new int[size];
...
//int[] selecting = new int[20];
Though it could all be reduced to
private static readonly Random _r = new Random();
static void Main(string[] args)
{
var numbers = Generate(100);
var selected = numbers.Take(20).ToArray();
Console.WriteLine("Selected : " + string.Join(", ", selected));
Console.Write("Primes : " + string.Join(",", selected.Where(IsPrime)));
Console.ReadLine();
}
public static int[] Generate(int size)
{
var numbers = Enumerable.Range(1, 100).ToArray();
// Shuffling the elements of the array:
for (var i = 0; i < numbers.Length; i++)
{
var j = _r.Next(i, numbers.Length);
var temp = numbers[i];
numbers[i] = numbers[j];
numbers[j] = temp;
}
return numbers;
}
private static bool IsPrime(int number)
{
for (var i = 2; i < Math.Sqrt(number); i++)
if (number % i == 0) return false;
return true;
}
Output
Selected : 92, 79, 1, 44, 83, 48, 70, 49, 80, 19, 27, 65, 50, 40, 20, 10, 68, 25, 9, 28
Primes : 79,1,83,49,19,25,9
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
I have a list of strings containing loads of hashtags with texts.
ex #csharp #java ect.
each hashtag is a own string in a List. I now want to randomly always console.writeline 30 items of that list.
List
List<string> Hashtags = new List<string>();
Writeline
foreach (var x in Hashtags) {
Console.WriteLine(x);
}
Ideally i never wanna have the same hashtag in the random 30.
You should try this:
var rnd = new Random();
foreach (var x in Hashtags.OrderBy(x => rnd.Next()).Take(30))
{
Console.WriteLine(x);
}
This has O(n^2) complexity, but is easily readable.
If you want efficiency try a Fisher-Yates Shuffle, it's O(n), but less readable:
var take = 30;
var rnd = new Random();
for (var i = 0; i < (Hashtags.Count < take ? Hashtags.Count : take); i++)
{
var j = rnd.Next(Hashtags.Count);
(Hashtags[i], Hashtags[j]) = (Hashtags[j], Hashtags[i]);
}
foreach (var x in Hashtags.Take(take))
{
Console.WriteLine(x);
}
Keep in mind, though, that it's best to instantiate Random once per thread, so this would be a better way:
[ThreadStatic]
private static Random rnd = new Random();
This should do. It is efficient, as it shuffles only the required amount of items, not the whole collection. You pass how many elements you want to fetch from the array as parameter(elementCount).
private static Random randomGenerator = new Random();
static void Main()
{
var hashtags = new List<string>() { "c#", "javascript", "ef", "asp.net" };
var result = GetRandomItems<string>(hashtags, 2);
foreach (var item in result)
{
Console.WriteLine(item);
}
}
private static IEnumerable<T> GetRandomItems<T>(IEnumerable<T> collection, int elementCount)
{
var collectionCount = collection.Count();
if (elementCount > collectionCount)
{
elementCount = collectionCount;
}
var collectionCopy = collection.ToList();
var randomIndex = randomGenerator.Next(0, collectionCopy.Count);
for (var index = 0; index < elementCount; index++)
{
var tempElement = collectionCopy[index];
collectionCopy[index] = collectionCopy[randomIndex];
collectionCopy[randomIndex] = tempElement;
randomIndex = randomGenerator.Next(index + 1, collectionCopy.Count);
}
return collectionCopy.Take(elementCount);
}
Call 30 times Random.next
https://learn.microsoft.com/en-us/dotnet/api/system.random.next
var random = new Random();
//calls this n times in a loop:
Console.writeline(Hashtags[random.next(Hashtags.Count])
Got it working myself, little more verbose but hopefully easier to follow.
var random = new Random();
var uniques = Hashtags;
for (var i = 0; i < 30; i++) {
var index = random.Next(0, uniques.Count());
Console.WriteLine(uniques[index]);
uniques.RemoveAt(index);
}
My function to generate random numbers is this:
public static List<int> GetRandomNumbers(int count)
{
HashSet<int> randomNumbers = new HashSet<int>();
Random random = new Random();
for (int i = 0; i < count; i++)
{
while(!randomNumbers.Add(random.Next(100, 999)));
}
return randomNumbers.ToList();
}
This is how I call it:
private void button1_Click(object sender, EventArgs e)
{
List<int> list = new List<int>();
list = GetRandomNumbers(5);
for (int i = 0; i < list.Count; i++)
{
MessageBox.Show(list[i].ToString());
}
}
Ok, so, what I want to do is, for example, if the list generated is the following:
152 582 254 891 421
I want to make the list be:
152 152 582 582 254 254 891 891 421 421
Basically, each number to be added one more time after itself in the list. How can I do this? (It would be good if you include a simple way to do this considering time not a problem, and maybe a better way to save time)
Thanks
Your question is unclear.
You can take a list (not a HashSet) with repeating elements and move every repetition to immediately follow the first occurrence like this:
var numbers = Enumerable.Range(1, count).Select(i => random.NextInt(0, 300));
return numbers.GroupBy(i => i).SelectMany(s => s).ToList();
You can take an existing list and make each element repeat twice like this:
list.SelectMany(o => Enumerable.Repeat(o, 2));
You could change your function slightly to:
private static Random random = new Random();
public static List<int> GetRandomNumbers(int count)
{
int value;
List<int> values = new List<int>();
HashSet<int> randomNumbers = new HashSet<int>();
for (int i = 0; i < count; i++)
{
while (!randomNumbers.Add(value = random.Next(100, 999)));
values.Add(value);
values.Add(value);
}
return values;
}
I think you just want something like this:
var list2 = new List<int>(list1.Count * 2);
foreach (var n in list1)
{
list2.Add(n);
list2.Add(n);
}
That will loop through the list and put each value into the second list twice.
I think you need to change your function as follows:
public static List<int> GetRandomNumbers(int count)
{
List<int> Result = new List<int>();
Random random = new Random();
for (int i = 0; i < count; i++)
{
int NewNumber = random.Next(100, 999);
Result.Add(NewNumber);
Result.Add(NewNumber);
}
return Result;
}
I tried the function above, it worked just like you said.
I am trying to generate 10 unique random numbers and save it to an array.
Here is my code, but there is run-time error, but I dunno how.
Can someone help me please ?
static void Main(string[] args)
{
int [] generatedNum = new int[10];
bool duplicated;
int tempo;
Random random = new Random();
// Create first number
generatedNum[0] = random.Next(1, 25);
for (int i = 1; i < 10; i++)
{
tempo = random.Next(0, 25);
do
{
duplicated = false;
foreach (int x in generatedNum)
{
if (x == tempo)
duplicated = true;
}
if (duplicated == true)
tempo = random.Next(0, 25);
} while (duplicated == true);
// Save unique number to array
generatedNum[i] = tempo;
}
// To check the number saved
foreach (int i in generatedNum)
{
Console.WriteLine("{0}", generatedNum[i]);
}
}
This may helps:
public List<int> GetNumber()
{
Random random = new Random();
List<int> values = new List<int>();
values.Add(random.Next(0, 25));
while (values.Count < 10)
{
int newValue;
do
{
newValue = random.Next(0, 25);
} while (values.Contains(newValue));
values.Add(newValue);
}
return values;
}
To have x unique items out of an array of y, you need a shuffle bag.
You put your numbers 1-25 in a bag, shuffle it and then take the first 10 items. You will now have 10 random items between 1 & 25.
Your last foreach loop is invalid. i is the value, not index, so you can write it directly:
// To check the number saved
foreach (int i in generatedNum)
{
Console.WriteLine("{0}", i);
}
Change
foreach (int i in generatedNum)
{
Console.WriteLine("{0}", generatedNum[i]);
}
to
for (int j=0;j<generatedNum.Length;j++)
{
Console.WriteLine("{0}", generatedNum[j]);
}
Would this work
If you are allowed to use Linq you can try something like this
You can set the range you want
Random rnd = new Random();
var randomNumbers = Enumerable.Range(1, 100)
.Select(x => new { val = x, order = rnd.Next() })
.OrderBy(i => i.order)
.Select(x => x.val)
.Take(10).ToArray();
static void Main(string[] args)
{
var generatedNum = new List<int>();
var random = new Random();
while (generatedNum.Count < 10)
{
var tempo = random.Next(0, 25);
if (generatedNum.Contains(tempo)) continue;
generatedNum.Add(tempo);
}
foreach (var i in generatedNum)
{
Console.WriteLine("{0}", i);
}
}
And you problem was here no?
// To check the number saved
foreach (int i in generatedNum)
{
Console.WriteLine("{0}", generatedNum[i]);
}
/*try this,i used an arraylist to store the digits
using System;
using System.Collections;
public class SamplesArrayList
{
public static void Main()
{
// Creates and initializes a new ArrayList.
ArrayList values = new ArrayList();
Random random = new Random();
values.Add(random.Next(0, 25));
while (values.Count < 10)
{
int newValue;
do
{
newValue = random.Next(0, 25);
} while (values.Contains(newValue));
values.Add(newValue);
}
PrintValues(values);
}
public static void PrintValues(IEnumerable myList)
{
foreach (Object obj in myList)
Console.Write(" {0}", obj);
Console.WriteLine(myList);
}
}