I need to generate in a loop 200 numbers and signs that will create something like this:
1+1 or 20*1252
Is there a way to do this?
I am new to c#. Can someone help?
Random randonNum = new Random();
for (int i = 0; i < 200; i++)
{
int nums = randonNum.Next(0, 500);
//dont know how to continue
}
You seem to know how to generate a random number, so generating two random numbers shouldn't prove any problem. It looks like you're having trouble generating a random "sign", called operators.
You can do so by creating an array containing the possible choices, generating a random index for that array and retrieving that element through the array's indexer as explained in Access random item in list:
var operators = new[] { "+", "-", "/", "*" };
int operatorIndex = randomNum.Next(operators.Length);
var selectedOperator = operators[operatorIndex];
What about using Random for all three factors? Random can be used to find an operator from a list or array too for example.
You could use something like this (where operators is an array of string objects):
string[] operators = new string[] { "+", "-", "*" };
string oper = operators[randonNum.Next(operators.Length)];
Take a look at this working example:
// this list will contain the results
List<string> list = new List<string>();
// create an array of allowed operators
string[] operators = new string[] { "+", "-", "*" };
Random randonNum = new Random();
for (int i = 0; i < 200; i++)
{
// pick two numbers
int num1 = randonNum.Next(0, 500);
int num2 = randonNum.Next(0, 500);
// pick an operator from the array
string oper = operators[randonNum.Next(operators.Length)];
// add it to the list
list.Add(string.Format("{0}{1}{2}", num1, oper, num2));
}
Something like this
string[] operands = new[] {"+", "-", "*", "/"};
Random random = new Random();
List<string> results = new List<string>();
for (int i = 0; i < 200; i++)
{
int firstNum = random.Next(0, 500);
int secondNum = random.Next(0, 500);
string operand = operands[random.Next(0, 3)];
results.Add(string.Format("{0}{1}{2}", firstNum, operand, secondNum));
}
Related
Alright, so I was trying to do a part of my program which just tallies all the numbers in a number (i'm good at translating polish mathematical arguments to english) and I wanted to implement a loop in which new variables are created, and those variables have names from a table array.
Here's the snippet of my code:
Random rand = new Random();
int[] a = { rand.Next(100,999), rand.Next(100, 999), rand.Next(100, 999), rand.Next(100, 999) }; // random numbers
int j = -1;
string[] inty = { "k", "l", "m", "n" }; // the array from which i want to extract variable names
for (int i = 0;i<=a.Length;i++) // loop
{
j++;
int inty[j] = new int(); // create a new int, where the name of the int is some letter from that array
Console.WriteLine(a[j]);
}
Console.ReadKey();
So that int that's supposed to be created in the loop should have a name from the next letters in that string array (inty). Does anyone have an idea on how to do this (or replace the code in another way)?
Sincerely,
some random dude on the internet.
You can use a Dictionary for this:
Random rand = new Random();
int[] a = { rand.Next(100,999), rand.Next(100, 999), rand.Next(100, 999), rand.Next(100, 999) }; // random numbers
string[] inty = { "k", "l", "m", "n" };
var variables = new Dictionary<string, int>();
for (int i = 0; i<a.Length; i++)
{
variables.Add(inty[i], a[i]);
Console.WriteLine(variables[inty[i]]);
}
//example using a variable
Console.WriteLine($"k: {variables["k"]}");
Console.ReadKey();
or:
Random rand = new Random();
int[] a = { rand.Next(100,999), rand.Next(100, 999), rand.Next(100, 999), rand.Next(100, 999) }; // random numbers
string[] inty = { "k", "l", "m", "n" };
var variables = new Dictionary<string, int>();
foreach (var item in a.Zip(inty, (i, n) => (i, n)))
{
variables.Add(item.i, item.n);
}
//example using a variable
Console.WriteLine($"k: {variables["k"]}");
Console.ReadKey();
Remember C# is strongly-typed. Variables must be declared to the compiler. If you want an identifier to be available as a variable in the IDE, it must be declared that way. Otherwise, you just use the name as data held in some other type.
If I understand your question... you may use the modulus function and a hashset maybe
HashSet<string> names = new HashSet<strings>();
for (int i = 0;i<=a.Length;i++)
{
j = j++ % 3; // Will give 0,1,2,0,1,2,0,1,2... or use ranbd.Next(0,4)
string forName = inty[j]; // Restricted to 0,1,2
string newName = $"{forName}{a[j]}";
if (! names.Contains(newName)
{
names.Add(newName);
Console.WriteLine("Name: {newName}");
}
else
{
Console.WriteLine("Ups!: {newName} already used!");
}
}
I feel like this task should not be done this way...
My sequenceY length is not equal to number of steam numbers because you can't assign int[] length with int that have 0 as a starting value.
Therefore my sequenceY have a lot of 0 inside and I can't print the whole sequence. I even tried adding this after for loop:
sequenceY = new int[steamnumbercounter];
But it didn't work ... Why ?
My other question is how do programmers deal with sequences that have unknown length?
I managed to print only steam numbers but the task says print sequenceY not only part of it.
// 4. sequenceX[20] is made of random numbers from 1 to 30 ,
// sequenceY is made of steam numbers from sequenceX. Print sequneceY.
int[] nizx = new int[20];
int[] nizy = new int[20];
int n = 0;
int steamnumbercounter = 0;
Random rnd = new Random();
for (int i = 0; i < nizx.Length; i++)
{
nizx[i] = rnd.Next(1, 30);
if (nizx[i]%2==0)
{
nizy[n] = nizx[i];
n++;
steamnumbercounter++;
}
Console.Write("{0} , ", nizx[i]);
}
for (int i = 0; i < steamnumbercounter; i++)
{
Console.WriteLine("{0} , ",nizy[i]);
}
Partial code review along with an answer.
But it didn't work ... Why ?
That code didn't work because you're reassigning sequenceY to a completely new value.
My other question is how do programmers deal with sequences that have unknown length?
So, with that known we can do a few things here: create an array and use Array.Resize, use a List<T>, fill the initial array then swap it for one of the right size which is filled.
I'm going to assume a "steam" number is an even one.
Your naming is not good: nizx and nizy don't convey the meaning or line up with the problem.
I'm going to demonstrate the last option (since you stated that you don't know how to use many of the moderately complex parts of .NET in this class yet, which is fine): fill the initial array and swap it for a new one. This will run in O(n^2) time (sorta).
So, let's start with our source array.
int[] sequenceX = new int[20];
Next we'll define our destination array to be the same size as our source array. (This is the maximum number of values that could be stored in it, we'll shrink it later.)
int[] sequenceY = new int[sequenceX.Length];
Then we need a variable to hold how many numbers we found that meet our criteria:
int steamNumbers = 0;
And lastly, our Random.
Random random = new Random();
Then, we look through all our sequenceX as you did, but we'll update the logic a bit.
for (int i = 0; i < sequenceX.Length; i++)
{
sequenceX[i] = random.Next(1, 30);
if (sequenceX[i] % 2 == 0)
{
sequenceY[steamNumbers] = sequenceX[i];
steamNumbers++;
}
}
So our code looks almost the same as yours, but we have one more thing to do: since you only want sequenceY to contain steamNumbers we have to shrink it or something.
int[] tempSequenceY = sequenceY;
sequenceY = new int[steamNumbers];
for (int i = 0; i < steamNumbers; i++)
{
sequenceY[i] = tempSequenceY[i];
}
Now sequenceY only has your steam numbers in it.
Final code:
int[] sequenceX = new int[20];
int[] sequenceY = new int[sequenceX.Length];
int steamNumbers = 0;
Random random = new Random();
for (int i = 0; i < sequenceX.Length; i++)
{
sequenceX[i] = random.Next(1, 30);
if (sequenceX[i] % 2 == 0)
{
sequenceY[steamNumbers] = sequenceX[i];
steamNumbers++;
}
}
int[] tempSequenceY = sequenceY;
sequenceY = new int[steamNumbers];
for (int i = 0; i < steamNumbers; i++)
{
sequenceY[i] = tempSequenceY[i];
}
// Print your `sequenceY` here.
You could extract this to a method pretty easily as well:
public int[] GetSteamNumbers(int sequenceCount, int randomMinimum, int randomMaximum)
{
int[] sequenceX = new int[sequenceCount];
int[] sequenceY = new int[sequenceX.Length];
int steamNumbers = 0;
Random random = new Random();
for (int i = 0; i < sequenceX.Length; i++)
{
sequenceX[i] = random.Next(randomMinimum, randomMaximum);
if (sequenceX[i] % 2 == 0)
{
sequenceY[steamNumbers] = sequenceX[i];
steamNumbers++;
}
}
int[] tempSequenceY = sequenceY;
sequenceY = new int[steamNumbers];
for (int i = 0; i < steamNumbers; i++)
{
sequenceY[i] = tempSequenceY[i];
}
return sequenceY;
}
And then call it with:
int[] steamNumbers = GetSteamNumbers(20, 1, 30);
Of course, for the more advanced users (this doesn't help you, but it may help others) we can do something as follows using LINQ:
var random = new Random();
var sequenceY = Enumerable.Range(1, 20)
.Select(x => random.Next(1, 30))
.Where(x => x % 2 == 0)
.ToArray();
Which should have the same effect. (Just demonstrating that there are still things in C# to look forward to in the future.)
Disclaimer: I wrote this entire answer outside of the IDE and without actually compiling it, I make no guarantees to the accuracy of the code but the procedure itself should be fairly straight forward.
The thing with arrays in C# is that they are of fixed size.
You'll have to iterate through and re-create it or use a IEnumerable that has dynamic sizes, such as Lists.
Solution here would be to use a List that contains your integers and then you would use nizx.Add(rnd.Next(1, 30));
Elaborating on my comment above: You can create a 'fake' list by concatenating the values you need in a string, separated by commas. The string.Split(',') will give you the resulting array that you need.
Given a string of form "a,b,c,d" string.Split(',') will create the array ["a","b,"c","d"]. The code:
{
int[] nizx = new int[20];
string numberString = string.Empty;
int n = 0;
Random rnd = new Random();
for (int i = 0; i < nizx.Length; i++)
{
nizx[i] = rnd.Next(1, 30);
if (nizx[i] % 2 == 0)
{
numberString += nizx[i] + ",";
n++;
}
}
var numberArray = numberString.Split(',');
for (int i = 0; i < n; i++)
{
Console.WriteLine("{0} , ", numberArray[i]);
}
}
I'm trying to change the elements of an array randomly, by changing the indexes.
My code so far is the following:
public static string[] Shuffle(string[] wordArray)
{
int swapIndex = 0;
string temp;
Random random = new Random();
for (int i = 0; i < wordArray.Length; i++)
{
System.Console.WriteLine("random " + random.Next(0, wordArray.Length));
swapIndex = (int)(random.Next(0, wordArray.Length));
temp = wordArray[i];
wordArray[i] = wordArray[swapIndex];
wordArray[swapIndex] = temp;
}
return wordArray;
}
And the function that calls that method is the following:
static string[] words1 = new string[] { "1", "2", "3" };
static string[] days = new string[] { "M", "T", "W", "Th", "F", "S", "Su" };
public static void playListCreation()
{
for (int j = 0; j < days.Length; j++)
{
var result = Shuffle(words1);
foreach (var i in result)
{
System.Console.WriteLine(i + " ");
}
System.Console.WriteLine("/n");
}
}
The problem with the code is that every time Im getting the same number in the swapIndex value. I always get:
random 2
random 2
random 0
In all the iterations. And I don't know what I'm doing wrong.
Any ideas? thanks in advance.
Addition
Now the solution is good. But not perfect. As I have random values, I can get two results that are the same.
for example:
Monday:
song 1
song 2
song 3
Tuesday:
song 2
song 1
song 3
Wednesday:
song 1
song 2
song 3
And so on...
And the list from
Monday
and
Wednesday
in this case is the same. I need to control that, but as you can see on the code, once I get the list from one day, I just print it. I thought about putting it on an array or Tuples and check if that tuple exists, but I think its too complicated. How can I solve this situation? Thanks!!
You need to declare and initialize the Random only once. You are declaring it inside the Shuffle method and calling it in a loop. This means that your Randomobject is getting initialized with the same seed every time, so obviously it will generate the same sequence of "random" numbers.
private static Random random = new Random();
public static string[] Shuffle(string[] wordArray)
{
int swapIndex = 0;
string temp;
for (int i = 0; i < wordArray.Length; i++)
{
System.Console.WriteLine("random " + random.Next(0, wordArray.Length));
swapIndex = (int)(random.Next(0, wordArray.Length));
temp = wordArray[i];
wordArray[i] = wordArray[swapIndex];
wordArray[swapIndex] = temp;
}
return wordArray;
}
Also, stop-cran had a valid point - the Console.WriteLine gets a different random number then the swapIndex variable.
If you want to print out the value of the swapIndex variable, do it like this:
swapIndex = (int)(random.Next(0, wordArray.Length));
System.Console.WriteLine("random {0}", swapIndex);
So basically, I need to have the numbers 1-10 randomly ordered upon startup into an array, and on when the form loads, it should load the first number. Each time the user clicks a button, it will load the info associated with the next number.
This is my code, but for some reason it generates a number that is not an integer a lot.
Random rng = new Random(10);
int[] QuestionOrder = new int[10];
for (int i = 0; i < QuestionOrder.Length; i++)
{
int temp = rng.Next(1,10);
while(!(QuestionOrder.Contains(temp)))
{
QuestionOrder[i] = temp;
}
}
each time it generates a number 1 - 10 and checks if it has already been stored in the array, if not, stores it and runs again.
For some reason, its generating numbers that are not integers 1 - 10, and i cant figure out why.
I think you need to overwrite the value of temp inside the while loop and change your range to 1-11 instead of 1-10 and use an if statement before the loop:
int temp = rng.Next(1, 11);
if(!QuestionOrder.Contains(temp)) QuestionOrder[i] = temp;
else
{
while(QuestionOrder.Contains(temp))
{
temp = rng.Next(1, 11);
QuestionOrder[i] = temp;
}
}
You could generate ten random numbers first, then iterate through them.
var rnd = new Random(Environment.TickCount);
var arr = Enumerable.Range(1,10).OrderBy(x => rnd.Next()).ToArray();
this does work nicely
static void Main(string[] args)
{
Random random = new Random();
var range = Enumerable.Range(1, 10).ToList();
int[] rnd = new int[10];
int j = 0;
do
{
int i = random.Next(0, range.Count);
rnd[j++] = range[i];
range.RemoveAt(i);
}
while(range.Count > 1);
rnd[j] = range[0];
}
less cpu intensive than using a contains in a loop
First, your seed is always the same. Either omit it, or use maybe the current date.
Second, you're generating numbers between 1 and 9, so you will never get 10, and one of your array cell will stay empty.
Change temp = rng.Next(1, 11);
As others have pointed out, you're not regenerating a new number when the generated number is already present in the list, leaving you with various default values of 0 in your result.
There are however better ways to 'shuffle' a list of numbers, see Randomize a List in C#:
public static IList<T> Shuffle<T>(this IList<T> list)
{
Random rng = new Random();
int n = list.Count;
while (n > 1)
{
n--;
int k = rng.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
return list;
}
Which you can call like this:
IList<int> QuestionOrder = Enumerable.Range(1, 10)
.ToList()
.Shuffle();
The best algorithm to shuffle an array is Knuth-Fisher-Yates, that can be implemented as follows:
public static class Extensions
{
public static void Shuffle<T>(this IList<T> list, Random rand)
{
for (int i = list.Count - 1; i > 0; i--)
{
int n = rand.Next(i + 1);
int tmp = list[i];
list[i] = list[n];
list[n] = tmp;
}
}
}
Usage:
// to get different random sequences every time, just remove the seed (1234)
Random rng = new Random(1234);
// create an array containing 1,2...9,10
int[] questionOrder = Enumerable.Range(1,10).ToArray();
// shuffle the array
questionOrder.Shuffle(rand);
Side note:
To know why Knuth-Fisher-Yates algorithm is better than a naive implementation, read this interesting post by Jeff
listBox1.Items.Clear();
int[] sayısal = new int[6];
Random rastgele = new Random();
for (int i = 0; i < 6; i++)
{
do
{
sayısal = rastgele.Next(1, 50);
}
while (listBox1.Items.IndexOf(sayısal) != -1);
listBox1.Items.Add(sayısal);
}
When I did like this, I take an error that calls
"Cannot implicitly convert type 'int' to 'int[]' "
in line "sayısal = rastgele.Next(1, 50);". What can I do for it?
You can generate sequence 1..50 and shuffle it (i.e. sort by random value):
Random rastgele = new Random();
int[] sayısal = Enumerable.Range(1, 50) // generate sequence
.OrderBy(i => rastgele.Next()) // shuffle
.Take(6) // if you need only 6 numbers
.ToArray(); // convert to array
Your code is not working, because you are trying to assign generated item to array variable.
sayısal = rastgele.Next(1, 50);
It should be instead:
do {
sayısal[i] = rastgele.Next(1, 50);
} while(listBox1.Items.IndexOf(sayısal[i]) != -1);
As I already pointed in comments, it's better to separate UI logic and array generation. I.e.
// generate array (optionally move to separate method)
int itemsCount = 6;
int[] items = new int[itemsCount]; // consider to use List<int>
Random random = new Random();
int item;
for(int i = 0; i < itemsCount; i++)
{
do {
item = random.Next(1, 50);
} while(Array.IndexOf(items, item) >= 0);
items[i] = item;
}
// display generated items
listBox1.Items.Clear();
for(int i = 0; i < items.Length; i++) // or use foreach
listBox1.Items.Add(items[i]);
Because Random.Next method returns an int, not int[]. And there is no implicit conersation from int[] to int.
Return Value
Type: System.Int32
A 32-bit signed integer greater than or equal to minValue and less than maxValue; that is, the range of return values includes minValue but not maxValue. If minValue equals maxValue, minValue is returned.
If you want to fill your array, you can use Enumerable.Range like lazyberezovsky mentioned.
This method takes an integer array and randomly sorts them.
So fill an array with a loop then use this to randomly sort the array.
You should credit one of the others as they were first to post with valid answers. I just thought another way to do this would be good.
amount is the amount of times you want the array to randomize. The higher the number the higher the chance of numbers being random.
private Random random = new Random();
private int[] randomizeArray(int[] i, int amount)
{
int L = i.Length - 1;
int c = 0;
int r = random.Next(amount);
int prev = 0;
int current = 0;
int temp;
while (c < r)
{
current = random.Next(0, L);
if (current != prev)
{
temp = i[prev];
i[prev] = i[current];
i[current] = temp;
c++;
}
}
return i;
}
Be careful in your choice of data structures and algorithms, pick the wrong one and you'll wind up with O(n^2). A reasonable solution IMHO is a typed hash table (i.e. dictionary) which will give you O(n):
Random rnd = new Random();
var numbers = Enumerable
.Range(1, 1000000)
.Aggregate(new Dictionary<int, int>(), (a, b) => {
int val;
do {val = rnd.Next();} while (a.ContainsKey(val));
a.Add(val, val);
return a;
})
.Values
.ToArray();
Still not ideal though as performance depends on the array size being significantly smaller than the set of available numbers and there's no way to detect when this condition isn't met (or worse yet when it's greater, in which case the algorithm will go into an infinite loop).