I would like to have 4 list of data which are 12 randomly picked data on each row in those table with a designated pattern of "*".
I did try use Random() function but it was not working as the desire output.
Below are my sample code :
for (int i = 0; i < dgvA1.Rows.Count; i++)
{
int row = 0; int col = 0;
//Get First Row
for (int x = 0; x < 12;x++)
{
Random r = new Random();
int randomNumber = r.Next(1, 35); //for ints
row = randomNumber;
col = randomNumber;
rbLog.Text += row.ToString() + ";" + col.ToString();
}
}
Below are the picture of the table, and the red line are the coordinate that i wanted to be randomly selected on each of the line.
Total will be 4 line of random picked with 12 data each line. Any other method or linQ can done that?
Thanks
Here's some code to get you started -
List<(int, int)> principalDiagonalIndices = new List<(int, int)>();
List<(int, int)> secondaryDiagonalIndices = new List<(int, int)>();
int rowCount = dgvA1.Rows.Count;
for (int i = 0; i < rowCount; i++)
{
for (int j = 0; j < rowCount; j++)
{
if (i == j)
{
principalDiagonal.Add((i, j));
}
else if ((i + j) == (rowCount - 1))
{
secondaryDiagonalIndices.Add((i, j));
}
}
}
Random r = new Random();
for (int i = 0; i < 12; i++)
{
var principalIdx = principalDiagonalIndices[r.Next(0, principalDiagonalIndices.Count)];
Console.WriteLine("Random principal diagonal index - {0}", dgvA1[principalIdx.Item1, principalIdx.Item2]);
var secondaryIdx = secondaryDiagonalIndices[r.Next(0, secondaryDiagonalIndices.Count)];
Console.WriteLine("Random secondary diagonal index - {0}", dgvA1[secondaryIdx.Item1, secondaryIdx.Item2]);
}
Collect the principal and secondary diagonal in the list and iterate 12 times to get a pseudo-random index.
For principal diagonal, if you observe the row and column are equal (i == j).
And for secondary diagonal it should be row and col index summed up should equal to one minus the row-count.
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 was wondering how can I stop the iteration through the rows and columns of a 2d matrix if a value is found.
int[,] matrix = new int[8, 10];
Random rnd = new Random();
bool value = false;
for (int row = 0; row < matrix.GetLength(0); row++)
{
for (int col = 0; col < matrix.GetLength(1); col++)
{
int number = rnd.Next(1, matrix.Length + 1);
matrix[row, col] = number;
Console.Write("{0,3}", number);
if (number == 8)
{
value = true;
break;
}
}
}
Hi I am very new to coding and was trying to figure out how to create a 2d array. That asks the user to input row and column size than fills those chosen row and column sizes with random numbers. After days of trying to figure it out I decided to come on here for help. Here is what I have so far, its all over the places I KNOW.
char row = 'i';
char column = 'j';
int[,] twoDarray = new int[row, column];
int min = 0;
int max = 100;
Random randNum = new Random();
for (int i = 0; i < twoDarray.Length; ++i)
for (int j = 0; j < twoDarray.Length; ++j)
{
twoDarray[i, j] = Convert.ToInt32(In.ReadLine());
}
Not sure if I understand your question. I will assume that it is a console application. In that case, the code could look like:
int row, column;
string rowVal;
Console.Write("\nEnter Number of Rows: ");
rowVal = Console.ReadLine();
string colVal;
Console.Write("\nEnter Number of Columns: ");
colVal = Console.ReadLine();
bool allGood = true;
if(!int.TryParse(rowVal, out row))
{
allGood = false;
Console.Write("Number of Rows is wrong: ");
}
if (!int.TryParse(colVal, out column))
{
allGood = false;
Console.Write("Number of Columns is wrong: ");
}
if (!allGood)
throw new Exception("Wrong input data"); //or just return from your method
int[,] twoDarray = new int[row, column];
int min = 0;
int max = 100;
Random randNum = new Random();
for (int i = 0; i < twoDarray.GetLength(0); ++i)
{
for (int j = 0; j < twoDarray.GetLength(1); ++j)
{
twoDarray[i, j] = randNum.Next(min,max);
}
}
I am wanting to create multiple arrays of ints(in C#). However they all must have a unique number in the index, which no other array has that number in that index. So let me try show you what I mean:
int[] ints_array = new int[30];
for (int i = 0; i < ints_array.Count(); i++)
ints_array[i] = i;
//create a int array with 30 elems with each value increment by 1
List<int[]> arrayList = new List<int[]>();
for(int i = 0; i < ints_array.Count(); i++)
arrayList.Add(ints_array[i]. //somehow sort the array here randomly so it will be unique
So I am trying to get the arrayList have 30 int[] arrays and each is sorted so no array has the same int in the same index as another.
Example:
arrayList[0] = {5,2,3,4,1,6,7,8,20,21... etc }
arrayList[1] = {1,0,5,2,9,10,29,15,29... etc }
arrayList[2] = {0,28,4,7,29,23,22,17... etc }
So would this possible to sort the array in this unique kind of way? If you need anymore information just ask and ill fill you in :)
Wouldn't it be easier to create the arrays iteratively using an offset pattern?
What I mean is that if you created the first array using 1-30 where 1 is at index 0, the next array could repeat this using 2-30 where 2 is at index 0 and then wrap back to 1 and start counting forward again as soon as you go past 30. It would be an easy and repeatable way to make sure no array shared the same value/index pair.
You can do it like that:
List<int[]> arrayList = new List<int[]>();
Random rnd = new Random();
for (int i = 0; i < ints_array.Length; i++)
{
ints_array = ints_array.OrderBy(x => rnd.Next()).ToArray();
var isDuplicate = arrayList.Any(x => x.SequenceEqual(ints_array));
if (isDuplicate)
{
while (arrayList.Any(x => x.SequenceEqual(ints_array)))
{
ints_array = ints_array.OrderBy(x => rnd.Next()).ToArray();
}
}
arrayList.Add(ints_array);
}
I think, this wouldn't be so efficient for bigger numbers than 30.But in this case it shouldn't be a problem, in my machine it takes 7 milliseconds.
Jesse's idea would be best unless you needed a pure random pattern. In that case I would recommend generating a random number, checking all your previous arrays, and then placing it in an array if it did not match any other arrays current index. Otherwise, generate a new random number until you find a fresh one. Put that into a loop until all your arrays are filled.
Use a matrix (2D-array). It is easier to handle than a list of arrays. Create a random number generator. Make sure to initialize it only once, otherwise random number generator may create bad random numbers, if created in too short time intervals, since the slow PC-clock might not have ticked in between. (The actual time is used as seed value).
private static Random random = new Random();
Create two helper arrays with shuffeled indexes for rows and columns:
const int N = 30;
int[] col = CreateUniqueShuffledValues(N);
int[] row = CreateUniqueShuffledValues(N);
Then create and initialize the matrix by using the shuffeled row and column indexes:
// Create matrix
int[,] matrix = new int[N, N];
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
matrix[row[i], col[j]] = (i + j) % N;
}
}
The code uses these two helper methods:
private static int[] CreateUniqueShuffledValues(int n)
{
// Create and initialize array with indexes.
int[] array = new int[n];
for (int i = 0; i < n; i++) {
array[i] = i;
}
// Shuffel array using one variant of Fisher–Yates shuffle
// http://en.wikipedia.org/wiki/Fisher-Yates_shuffle#The_modern_algorithm
for (int i = 0; i < n; i++) {
int j = random.Next(i, n);
Swap(array, i, j);
}
return array;
}
private static void Swap(int[] array, int i, int j)
{
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
int size = 10;
// generate table (no duplicates in rows, no duplicates in columns)
// 0 1 2
// 1 2 0
// 2 0 1
int[,] table = new int[size, size];
for (int y = 0; y < size; y++)
for (int x = 0; x < size; x++)
table[y, x] = (y + x) % size;
// shuffle rows
Random rnd = new Random();
for (int i = 0; i < size; i++)
{
int y1 = rnd.Next(0, size);
int y2 = rnd.Next(0, size);
for (int x = 0; x < size; x++)
{
int tmp = table[y1, x];
table[y1, x] = table[y2, x];
table[y2, x] = tmp;
}
}
// shuffle columns
for (int i = 0; i < size; i++)
{
int x1 = rnd.Next(0, size);
int x2 = rnd.Next(0, size);
for (int y = 0; y < size; y++)
{
int tmp = table[y, x1];
table[y, x1] = table[y, x2];
table[y, x2] = tmp;
}
}
// sample output
for (int y = 0; y < size; y++)
{
for (int x = 0; x < size; x++)
Console.Write("{0} ", table[y, x]);
Console.WriteLine();
}
I need to fill an array and display that array to the console (in table format).
Here is what I have so far:
static void Main()
{
//Declare variables, strings and constants.
const int ROWS = 10;
const int COLS = 5;
const int MIN = 1;
const int MAX = 100;
int total = 0;
int[,] numbers = new int[ROWS, COLS];
Random rand = new Random();
//Populate the array
for (int r = 0; r < ROWS; ++r)
{
for (int c = 0; c < COLS; ++c)
{
numbers[r, c] = rand.Next(MIN, MAX + 1);
}
}
//Display the array to console (table format)
for (int r = 0; r < numbers.GetLength(0); ++r)
{
for (int c = 0; c < numbers.GetLength(1); ++c)
{
Console.Write("{0,6} ", numbers[r, c]);
if (c % 5 == 0) Console.WriteLine();
}
}
When i do this, my display if off by 1 and doesn't align properly for a 10x5 table.
You could check if the column index plus one, c + 1, is equal to the given column count, COLS, then write a new line:
if (c + 1 == COLS) Console.WriteLine();
Another way is to print a new line after all columns are printed:
for (int r = 0; r < numbers.GetLength(0); ++r)
{
for (int c = 0; c < numbers.GetLength(1); ++c)
{
Console.Write("{0,6} ", numbers[r, c]);
}
Console.WriteLine();
}
This happens because of your next line:
if (c%5 == 0) Console.WriteLine();
Notice that the first output, r=0, c=0, so it prints a new line