I'm having trouble randomizing X-amounts of strings and adding them to my listbox. it keeps adding the same string over and over. i want it to add 1 line per string. if i say that amount is 11, it just makes one string and adds it 11 times to listbox. what am i doing wrong?
here is my code:
for (int i = 0; i < amount; i++)
{
Random adomRng = new Random();
string rndString = string.Empty;
char c;
for (int t = 0; t < 8; t++)
{
while (!Regex.IsMatch((c = Convert.ToChar(adomRng.Next(48, 128))).ToString(), "[a-z0-9]")) ;
rndString += c;
}
listBox1.Items.Add(rndString);
}
Random adomRng = new Random();
for (int i = 0; i < amount; i++)
{
string rndString = string.Empty;
char c;
for (int t = 0; t < 8; t++)
{
while (!Regex.IsMatch((c = Convert.ToChar(adomRng.Next(48, 128))).ToString(), "[a-z0-9]")) ;
rndString += c;
}
listBox1.Items.Add(rndString);
}
Put the random init code outside of the loop, it will get you the correct result
Explanation: creating multiple new random objects in the short period of time (let's say inside a for loop) will always give you the same output because it will use the current timestamp as random seed.
You are almost there,just make two simple changes in your code to achieve the target:
for (int t = 0; t < 8; t++)
{
rndString =""; //Change 1
while (!Regex.IsMatch((c = Convert.ToChar(adomRng.Next(48, 128))).ToString(), "[a-z0-9]")) ;
rndString += c;
listBox1.Items.Add(rndString);// change 2
}
Related
I can't fill it with numbers to 0 - 15 then shuffle the array, so that's not the solution
I used this code in C but now in c# it doesn't work, for some reason this code let some numbers pass the do while.
Random r = new Random();
bool unique;
int rand_num;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
do
{
unique = true;
rand_num = r.Next(16);
for (int k = 0; k < 4; k++)
{
for (int l = 0; l < 4; l++)
{
if (numbers[k, j] == rand_num)
{
unique = false;
}
}
}
} while (!unique);
numbers[i, j] = rand_num;
}
}
}
If the list of possible numbers is small, as in this case, just create the full list and randomise it first, then take the items in the order they appear. In your case, you can put the randomised numbers into a queue, then dequeue as required.
var r = new Random();
var numberQueue = new Queue<int>(Enumerable.Range(0, 16).OrderBy(n => r.NextDouble()));
var numbers = new int[4, 4];
for (var i = 0; i <= numbers.GetUpperBound(0); i++)
{
for (var j = 0; j <= numbers.GetUpperBound(1); j++)
{
numbers[i, j] = numberQueue.Dequeue();
}
}
I suggest you to use the Fisher-Yates algorithm to generate your non-repeatable sequence of random numbers.
It would be very straight-forward to implement a code to fill in a 2d array with those numbers, then.
List<int> seq = Enumerable.Range(0,16).ToList();
int[,] numbers = new int[4,4];
Random r = new();
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
int n = r.Next(0, seq.Count);
numbers[i,j] = seq[n];
seq.RemoveAt(n);
}
}
The approach you have taken may end up in continuous looping and take lot of time to complete.
Also checking for value in 2D using nested for loop is not efficient.
You can use HashSet to keep track of unique value. Searching in HashSet is fast.
following is the code approach I suggest.
var hashSet = new HashSet<int>();
var r = new Random();
var arr = new int[4, 4];
for(var i = 0;i<4;i++)
{
for(var j = 0;j<4;j++)
{
// Generate random value between 0 and 16.
var v = r.Next(0, 16);
// Check if the hashSet has the newly generated random value.
while(hashSet.Contains(v))
{
// generate new random value if the hashSet has the earlier generated value.
v = r.Next(0, 16);
}
//Add value to the hashSet.
hashSet.Add(v);
// add value to the 2D array.
arr[i, j] = v;
}
}
I hope this will help solving your issue.
The problem with your current approach is that as you get closer to the end of the array, you have to work harder and harder to get the next random value.
Imagine you roll a die, and each time you want to get a unique value. The first time you roll, any result will be unique. The next time, you have a 1/6 chance of getting a number that has already been obtained. And then a 2/6 chance, etc. and in the end most of your rolls will be non-unique.
In your example, you have 16 places that you want to fill with numbers 0 to 15. This is not a case of randomly generating numbers, but randomly placing them. How do we do this with a deck of cards? We shufle them!
My proposal is that you fill the array with unique sequential values and then shuffle them:
Random random = new Random();
int dim1 = array.GetLength(0);
int dim2 = array.GetLength(1);
int length = dim1 * dim2;
for (int i = 0; i < length; ++i)
{
int x = i / dim1;
int y = i % dim1;
array[x, y] = i; // set the initial values for each cell
}
// shuffle the values randomly
for (int i = 0; i < length; ++i)
{
int x1 = i / dim1;
int y1 = i % dim1;
int randPos = random.Next(i, length);
int x2 = randPos / dim1;
int y2 = randPos % dim1;
int tmp = array[x1, y1];
array[x1, y1] = array[x2, y2];
array[x2, y2] = tmp;
}
The shuffle in this code is based on the shuffle found here
int[,] numbers = new int[4, 4];
Random r = new Random();
bool unique;
int rand_num;
List<int> listRandom = new List<int> { };
for ( int i = 0; i < 4; i++ )
{
for ( int j = 0; j < 4; j++ )
{
do
{
unique = false;
if (!listRandom.Contains( rand_num = r.Next( 0, 16 )))
{
listRandom.Add( rand_num );
numbers[i, j] = rand_num;
unique = true;
}
} while ( !unique );
}
}
I need to streamwrite into a file.txt a 10 random numbers combinations (NOT REPEATED) like lottery program. I got everything except Non-repeated random numbers. it has to be seen (file.txt) like a 2D array with 10 combinations thx.
class Matriz
{
private int[,] array;
private int nfilas, ncols;
public void Ingresar()
{
Random aleatori = new Random();
nfilas = 10;
ncols = 6;
Console.WriteLine("\n");
array = new int[nfilas, ncols];
for (int filas = 0; filas < nfilas; filas++)
{
for (int columnas = 0; columnas < ncols; columnas++)
array[filas, columnas] = aleatori.Next(0, 50);
}
}
public void Imprimir()
{
StreamWriter fitxer = new StreamWriter(#"C:\andres\lotto649.txt");
int contador = 0;
for (int f = 0; f < nfilas; f++)
{
for (int c = 0; c < ncols; c++)
fitxer.Write(array[f, c] + " ");
fitxer.WriteLine();
contador++;
}
fitxer.WriteLine($"\n\n\tHay {contador} combinaciones de la Loteria 6/49");
fitxer.Close();
}
static void Main(string[] args)
{
Matriz array_menu = new Matriz();
array_menu.Ingresar();
array_menu.Imprimir();
}
}
Something like this should work.
Before inserting the new number in the given position, check the row thus far if the same number is already in there and if so, repeat the process until you get a number that isn't yet in there.
for (int filas = 0; filas < nfilas; filas++)
{
for (int columnas = 0; columnas < ncols; columnas++)
{
bool cont = true;
while(cont)
{
cont = false;
int newRand = aleatori.Next(0, 50);
for(int i = 0; i < columnas; i++)
if(array[filas, i] == newRand)
cont = true;
if(cont)
continue;
array[filas, columnas] = newRand;
break;
}
}
}
Alternatively, since the number is small you could also work with a list of ints and remove the given value from there.
This has the advantage, that you'll never have to redo your random number as it will always produce a valid result. The above example could (theoretically) run indefinitely long.
for (int filas = 0; filas < nfilas; filas++)
{
List<int> nums = new List<int>(49);
for(int i = 0; i < 49; i++)
nums.Add(i + 1); //num 1...49
for (int columnas = 0; columnas < ncols; columnas++)
{
int index = aleatori.Next(0, nums.Count)
array[filas, columnas] = nums[index];
nums.RemoveAt(index);
}
}
I'm trying to fill one dimensional array with random BUT unique numbers (No single number should be same). As I guess I have a logical error in second for loop, but can't get it right.
P.S I'm not looking for a more "complex" solution - all I know at is this time is while,for,if.
P.P.S I know that it's a really beginner's problem and feel sorry for this kind of question.
int[] x = new int[10];
for (int i = 0; i < x.Length; i++)
{
x[i] = r.Next(9);
for (int j = 0; j <i; j++)
{
if (x[i] == x[j]) break;
}
}
for (int i = 0; i < x.Length; i++)
{
Console.WriteLine(x[i);
}
Here is a solution with your code.
int[] x = new int[10];
for (int i = 0; i < x.Length;)
{
bool stop = false;
x[i] = r.Next(9);
for (int j = 0; j <i; j++)
{
if (x[i] == x[j]) {
stop = true;
break;
}
}
if (!stop)
i++;
}
for (int i = 0; i < x.Length; i++)
{
Console.WriteLine(x[i]);
}
A simple trace of the posted code reveals some of the issues. To be specific, on the line…
if (x[i] == x[j]) break;
if the random number is “already” in the array, then simply breaking out of the j loop is going to SKIP the current i value into the x array. This means that whenever a duplicate is found, x[i] is going to be 0 (zero) the default value, then skipped.
The outer i loop is obviously looping through the x int array, this is pretty clear and looks ok. However, the second inner loop can’t really be a for loop… and here’s why… basically you need to find a random int, then loop through the existing ints to see if it already exists. Given this, in theory you could grab the same random number “many” times over before getting a unique one. Therefore, in this scenario… you really have NO idea how many times you will loop around before you find this unique number.
With that said, it may help to “break” your problem down. I am guessing a “method” that returns a “unique” int compared to the existing ints in the x array, may come in handy. Create an endless while loop, inside this loop, we would grab a random number, then loop through the “existing” ints. If the random number is not a duplicate, then we can simply return this value. This is all this method does and it may look something like below.
private static int GetNextInt(Random r, int[] x, int numberOfRandsFound) {
int currentRand;
bool itemAlreadyExist = false;
while (true) {
currentRand = r.Next(RandomNumberSize);
itemAlreadyExist = false;
for (int i = 0; i < numberOfRandsFound; i++) {
if (x[i] == currentRand) {
itemAlreadyExist = true;
break;
}
}
if (!itemAlreadyExist) {
return currentRand;
}
}
}
NOTE: Here would be a good time to describe a possible endless loop in this code…
Currently, the random numbers and the size of the array are the same, however, if the array size is “larger” than the random number spread, then the code above will NEVER exit. Example, if the current x array is set to size 11 and the random numbers is left at 10, then you will never be able to set the x[10] item since ALL possible random numbers are already used. I hope that makes sense.
Once we have the method above… the rest should be fairly straight forward.
static int DataSize;
static int RandomNumberSize;
static void Main(string[] args) {
Random random = new Random();
DataSize = 10;
RandomNumberSize = 10;
int numberOfRandsFound = 0;
int[] ArrayOfInts = new int[DataSize];
int currentRand;
for (int i = 0; i < ArrayOfInts.Length; i++) {
currentRand = GetNextInt(random, ArrayOfInts, numberOfRandsFound);
ArrayOfInts[i] = currentRand;
numberOfRandsFound++;
}
for (int i = 0; i < ArrayOfInts.Length; i++) {
Console.WriteLine(ArrayOfInts[i]);
}
Console.ReadKey();
}
Lastly as other have mentioned, this is much easier with a List<int>…
static int DataSize;
static int RandomNumberSize;
static void Main(string[] args) {
Random random = new Random();
DataSize = 10;
RandomNumberSize = 10;
List<int> listOfInts = new List<int>();
bool stillWorking = true;
int currentRand;
while (stillWorking) {
currentRand = random.Next(RandomNumberSize);
if (!listOfInts.Contains(currentRand)) {
listOfInts.Add(currentRand);
if (listOfInts.Count == DataSize)
stillWorking = false;
}
}
for (int i = 0; i < listOfInts.Count; i++) {
Console.WriteLine(i + " - " + listOfInts[i]);
}
Console.ReadKey();
}
Hope this helps ;-)
The typical solution is to generate the entire potential set in sequence (in this case an array with values from 0 to 9). Then shuffle the sequence.
private static Random rng = new Random();
public static void Shuffle(int[] items)
{
int n = list.Length;
while (n > 1) {
n--;
int k = rng.Next(n + 1);
int temp = items[k];
items[k] = items[n];
items[n] = temp;
}
}
static void Main(string[] args)
{
int[] x = new int[10];
for(int i = 0; i<x.Length; i++)
{
x[i] = i;
}
Shuffle(x);
for(int i = 0; i < x.Length; i++)
{
Console.WritLine(x[i]);
}
}
//alternate version of Main()
static void Main(string[] args)
{
var x = Enumerable.Range(0,10).ToArray();
Shuffle(x);
Console.WriteLine(String.Join("\n", x));
}
You can simply do this:
private void AddUniqueNumber()
{
Random r = new Random();
List<int> uniqueList = new List<int>();
int num = 0, count = 10;
for (int i = 0; i < count; i++)
{
num = r.Next(count);
if (!uniqueList.Contains(num))
uniqueList.Add(num);
}
}
Or:
int[] x = new int[10];
Random r1 = new Random();
int num = 0;
for (int i = 0; i < x.Length; i++)
{
num = r1.Next(10);
x[num] = num;
}
My program is supposed to generate 24 random numbers then add them all together and display them.
I've gotten them to do everything, except I can't get the first 24 numbers to add.
I tried moving the statement that collects the numbers but it didn't work.
Im not sure how to go forward.
int x = 0;
int number = 0;
int i = 0;
while (i < listBox1.Items.Count)
{
number += Convert.ToInt32(listBox1.Items[i++]);
}
totaltextBox.Text = Convert.ToString(number);
Random ran = new Random();
for(x = 0;x <= 23; x++)
{
listBox1.Items.Add(Convert.ToString(ran.Next(0,100)));
}
fileNumbers.Text = listBox1.Items.Count.ToString();
Just replace for and while loop. if not, it cant take listBox1.Items.Count.
int x = 0;
int number = 0;
int i = 0;
Random ran = new Random();
for (x = 0; x <= 23; x++)
{
listBox1.Items.Add(Convert.ToString(ran.Next(0, 100)));
}
while (i < listBox1.Items.Count)
{
number += Convert.ToInt32(listBox1.Items[i++]);
}
totaltextBox.Text = Convert.ToString(number);
fileNumbers.Text = listBox1.Items.Count.ToString();
As mentioned in the comments, you set your totaltextbox text too early. That way the listbox is empty when you try to accumulate the values.
Try this:
Random ran = new Random();
for (var x = 0; x <= 23; x++)
{
listBox1.Items.Add(Convert.ToString(ran.Next(0, 100)));
}
var number = listBox1.Items.Cast<string>().Select(Int32.Parse).Sum();
var count = listBox1.Items.Count;
I also replaced your while loop with a LINQ-Expression. Also note, that in c# you can declare for-variables like in my example code. No need to declare them for the whole method (unless you want to use them after the for loop for whatever reason).
The other answers are correct. However I will add my solution which avoids some back and forth conversions and reduces iterations:
Random ran = new Random();
int total = 0;
for (int x = 0; x <= 23; x++)
{
int rn = ran.Next(0, 100);
total += rn;
listBox1.Items.Add(rn.ToString());
}
totaltextBox.Text = total.ToString();
The user basically enters a number of hex values into a textbox separated by commas eg. AA,1B,FF. These are then displayed in a listbox box. if the number of hex values in the textbox exceeds the size to transfer defined by the user, the listbox only displays the this number of values or if the size to transfer is bigger that adds zero values to the listbox.
this works fine until you enter a value with a zero in front of it such as AA,BB,CC,DD,EE,0F, if sizeToTransfer = 2, the listbox should display 0xAA and 0xBB. but instead it only removes the 0F value?
I'm pretty new to programming so it may be something obvious I'm missing any help would be appreciated.
private void WriteSPI1_Click(object sender, EventArgs e)
{
string hexstring = textbox1.Text;
HexValues.Items.Clear();
string[] hexarray = hexstring.Split((",\r\n".ToCharArray()), StringSplitOptions.RemoveEmptyEntries);
byte[] hexbytes = new byte[hexarray.Length];
uint num = Convert.ToUInt32(hexarray.Length);
for (int j = 0; j < hexarray.Length; j++)
{
hexbytes[j] = Convert.ToByte(hexarray[j], 16);
Hexlist.Add(hexbytes[j]);
writebuff = Hexlist.ToArray();
x = writebuff[j].ToString("X2");
HexValues.Items.Add("0x" + x);
}
if (hexarray.Length > sizeToTransfer)
{
diff = num - sizeToTransfer;
for (i = 0; i < diff+1; i++)
{
HexValues.Items.Remove("0x" + x);
}
}
else
{
diff = sizeToTransfer - num;
for (i = 0; i < diff; i++)
{
HexValues.Items.Add("0x00");
}
}
}
CHANGE
for (int j = 0; j < sizeToTransfer; j++)
{
hexbytes[j] = Convert.ToByte(hexarray[j], 16);
Hexlist.Add(hexbytes[j]);
writebuff = Hexlist.ToArray();
x = writebuff[j].ToString("X2");
HexValues.Items.Add("0x" + x);
}
WITH
for (int j = 0; j < hexarray.Length; j++)
{
hexbytes[j] = Convert.ToByte(hexarray[j], 16);
Hexlist.Add(hexbytes[j]);
writebuff = Hexlist.ToArray();
x = writebuff[j].ToString("X2");
HexValues.Items.Add("0x" + x);
}
and remove the if stantment that follow