C# fill 2D array matrix using single for loop - c#

I'm currently messing around with 2D arrays. I want to Fill a 2D array with a count. I've managed to do this using 2 nested for loops. (That's probably the easiest way of doing it right?)
//create count
int count = 1;
for (int row = 0; row < matrix.GetLength(0); row++)
{
for (int col = 0; col < matrix.GetLength(0); col++)
{
matrix[row, col] = count++;
}
}
I was just curious, is it also possible to fill this 2D array using only a single for loop?
I thought of making a loop that counts the rows. When the rows reaches the end of the array the column wil be increased by 1. This could probably be done by using some if, if else and else statements right?
Does someone here have any idea how to make this work?

Here you go
int[,] matrix = new int[5, 10];
int row = matrix.GetLength(0);
int col = matrix.GetLength(1);
for (int i = 0; i < row * col; i++)
{
matrix[i / col , i % col] = i + 1;
}
https://dotnetfiddle.net/Lv9DvT

Yes, of course you can.
for(int i = 0; i < matrix.GetLength(0) * matrix.GetLength(1); i++)
{
int row = i / matrix.GetLength(1);
int column = i % matrix.GetLength(1);
matrix[row, column] = i;
}
Works with NxN arrays.

Related

How to eliminate duplicates in 2D arrays in C#

just started to learn programming and I need 2D array without duplicates. This code (well edited for 1D) worked just fine for 1D but doesn't for 2D and have no clue why.
Would be very happy if someone helped me. Thanks.
Random r = new Random();
int[,] array = new int[10, 8];
for (int i = 0; i < array.GetLength(0); i++)
{
for (int j = 0; j < array.GetLength(1); j++)
{
array[i, j] = r.Next(10, 100);
for (int k = 0; k < i; k++)
{
for (int l = 0; l < j; l++)
{
if (array[i,j] == array[k,l])
{
i--;
j--;
break;
}
}
}
}
}
With the nested j loop you are filling the entire second dimension for each i, but in the k and l loops you are only checking the grid to the upper and left of current cell. You could place a number twice because you are not checking every previously filled location.
If we change the code to this:
for (int k = 0; k < array.GetLength(0); k++)
{
for (int l = 0; l < array.GetLength(1); l++)
{
if (i != k && j != l && array[i, j] == array[k, l])
{
i--;
j--;
break;
}
}
}
Then you eliminate that problem, but you very quickly find that you get a IndexOutOfRangeException because you're decrementing both i & j at the same time. That's not moving you to the previous value - it's jumping back a whole row and left one cell - and that's ultimately sending i or j to -1 and that's not good.
If you want to do it like you're attempting then you need to have a way to simply move back to the previously filled cell, regardless of the row or column you're on.
Try this:
for (int x = 0; x < array.GetLength(0) * array.GetLength(1); x++)
{
array[x % array.GetLength(0), x / array.GetLength(0)] = r.Next(10, 100);
for (int y = 0; y < x; y++)
{
if (array[x % array.GetLength(0), x / array.GetLength(0)] == array[y % array.GetLength(0), y / array.GetLength(0)])
{
x--;
break;
};
}
}
However, that's not very efficient. Try this instead:
var values = Enumerable.Range(10, 90).OrderBy(_ => r.Next()).ToArray();
for (int x = 0; x < array.GetLength(0) * array.GetLength(1); x++)
{
array[x % array.GetLength(0), x / array.GetLength(0)] = values[x];
}
So, first of all, that just seems inefficient. Not sure why you want to do it this way, but then again, don't know the reason. Looks like a programming assignment.
My guess, you need a sort of double break going on. When you break finding a match, you don't break out to the "k" for loop, so you continue looking for a match even though you found one. Try setting a boolean value to say it's found, then use that in the criteria for the for loop for k. That'll break it out and let you start over on the outside loops for i and j.
Even then, it won't work because you indescriminately subtracted i and j. So if you're on position 1,2 you will jump back to 0,1 rather than 1,2. So you need to subtract j, if it drops below 0, then subtract from i and add "array.GetLength(1)" to j.
This solution depends on HashSet's property of containing unique elements. It has an Add method that returns false when we try to add existing elements.
Random r = new Random();
int[,] array = new int[10, 8];
var usedValues = new HashSet<int>();
for (int i = 0; i < array.GetLength(0); i++)
{
for (int j = 0; j < array.GetLength(1); j++)
{
int uniqueValue;
while (true)
{
uniqueValue = r.Next(10, 100);
if (usedValues.Add(uniqueValue)) break; // It is unique indeed
// It is not unique, try again.
}
array[i, j] = uniqueValue;
}
}
The above solution is more suitable when the range of the acceptable unique values is large. In this specific case the range is very small (10-99), and the solution offered by #Enigmativity is preferable.

Building Conways game of life with C#

I am trying to calculate the Neighbour near my cells, but the code works for only the middle cells and not for the corner ones, for which I can use many if loops but I wanna know how it works with for and if loops.
I tried creating extra if loops or writing like if row ==0 etc. but everything seems to give me wrong answer. btw bool[,] grid has the values of false and true. and we need to calculate how many trues and false are their in give row/ col.
public static int CountNeighbours(bool[,] grid, int row, int col)
{
int total = 0;
for (int i = row - 1; i < row + 2; i++)
{
for (int j = col - 1; j < col + 2; j++)
{
if (grid[i, j] == grid[row, col])
{
total += 1;
}
}
}
Console.WriteLine("total neighbours for row {0} and column {1}: {2}",row,col,total-1);
return total-1;
}
The result should give perfect answer for corners and rows.
Your problem is that you count the cell itself as its own neighbour and that you don't check the boundaries of your grid.
Change your loop conditions like that:
for (int i = Math.Max(0, row - 1); i < row + 2 && i < grid.GetLength(0); i++)
{
for (int j = Math.Max(0, col - 1); j < col + 2 && j < grid.GetLength(1); j++)
{
if (i == row && j == col) continue; // skip current cell
So with Math.Max() you ensure that you don't use a negative i or j, because that would lead to an IndexOutOfRangeException.
With grid.GetLength() you get the array size in the respective dimension, because using a i or j greater or equal to that length would again raise an IndexOutOfRangeException.
And finally the last line checks that you don't count the cell in question itself.

In C#, How can I iterate through a entire 2D Array and count the number of 0s?

I've been trying to iterate through an entire 2D array and count the number of 0s. How can I do this?
I'm sure I have to use the following to make the program work:
Use an outer for loop to iterate through the rows of the array
Use an inner for loop to iterate through the columns of the array
if matrix[row,col] == 0, increment a variable
To get the number of rows of the 2D array, use the method matrix.GetLength(0), and to get the number of columns of the array, use the method matrix.GetLength(1)
Here's what I have attempted so far:
public int Test9(int[,] matrix)
{
int b = 0;
for (int i = 0; i < matrix.GetLength(0); i++)
for (int j = 0; j < matrix.GetLength(1); i++)
{
b = matrix[i, j];
}
}
This is how you can do it..
public int Test9(int[,] matrix)
{
int zeroCounter = 0;
for (int i = 0; i < matrix.GetLength(0); i++)
for (int j = 0; j < matrix.GetLength(1); j++)
{
if(matrix[i, j] == 0)
{
zeroCounter++;
}
}
}

How can I fill a 2d array recursively?

I have a string filled with 9 numbers. I want to fill a 3x3 array with the numbers. I've managed to do it using a foreach and 2 for loops, but I feel this is quite messy. How can I modify my code to recursively enter the values into the array? This is my code currently:
int[,] matrix = new int[3, 3];
if(key.Length < 9 || key.Length > 9)
{
keyfield.GetComponent<InputField>().text = " Key Not Valid";
}
else
{
foreach(char c in key)
{
for (int k = 0; k < 3; k++)
{
for (int j = 0; j < 3; j++)
{
matrix[j, k] = c - 0;
}
}
}
}
Note, I'm working with Unity.
Well, just iterate over the chars in your key and assign them to the array, one field at a time. It's just a matter of calculating the correct columns and rows:
for (int i = 0; i < 9; ++i)
{
int row = i / 3;
int col = i % 3;
matrix[row, col] = (int)key[i];
}
Also note that neither the code in your question nor the code in my answer solves the problem in a recursive way. Recursion is given when a method calls itself directly or indirectly, which is not required to solve this particular problem.

Filling matrix with for loops

Firstly, I fill the array with "0"s and then want to replace the first row with "1"s. Can not understand why the 2nd "for" loop fills the whole matrix with "1"s.
int i, j, array[length][width];
for (i = 0; i < length; i++) {
for (j = 0; j < width; j++) {
array[i][j] = 0;
}
}
for (i = 0; i < width; i++) {
array[0][i] = 1;
}`
I ran the code and it only filled the first row of the matrix with 1's. Try running it again.

Categories

Resources