I'm struggling to think of the most elegant/simple way of doing this. Perhaps I'm overthinking it a little.
Lets say I've got a 5x5 array of integers that looks like this:
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
And another 2x2 array of integers that looks like this:
5 1
2 3
I want to pick a location in the 5x5 array, say [2][2], and place the values from the second array into the first, so it looks like this:
0 0 0 0 0
0 0 0 0 0
0 0 5 1 0
0 0 2 3 0
0 0 0 0 0
My initial thought was to use a for loop after determining the number of rows/columns in the array to be copied, but I can't seem to puzzle out a way in my head to do that this morning.
Any suggestions?
Edit:
Sorry, here's the way I'm doing it currently. Just wondering if there's a better way.
This is actually part of a unity thing I'm doing - "RoomDoors" is our smaller array, and "map" is the larger array it's being moved into. It's part of a random map generator that needs to know which "edges" of tiles in rooms have doors on them that can connect to other rooms. RoomDoors stores 4 booleans, one for each direction telling me if there's a door there.
roomDoors = previousRoom.GetComponent<RoomDataInterface> ().rooms; //2d array of room/door arrangement in new room
sizeCol = roomDoors.GetLength (0);
sizeRow = roomDoors.GetLength (1);
map [10, 10] = roomDoors [0, 0]; // top left of the room goes in the spot
for (int i = 0; i < sizeCol; i ++){
for (int j = 0; j < sizeRow; j ++) {
map [i + 10,j + 10] = roomDoors[i,j];
}
I think you can't do much better, just remove the unnecessary assignment:
roomDoors = previousRoom.GetComponent<RoomDataInterface> ().rooms;
sizeCol = roomDoors.GetLength (0);
sizeRow = roomDoors.GetLength (1);
for (int i = 0; i < sizeCol; i ++)
for (int j = 0; j < sizeRow; j ++)
map [i + 10, j + 10] = roomDoors[i, j];
The line
map [10, 10] = roomDoors [0, 0];
is redundant, as the same assignment will be performed by the first iteration of the loop. Removal of the line will result in a solution that is smaller and more efficient.
Related
I have a code:
int[,] mas = new int[5, 5];
Random rnd = new Random();
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
mas[i, j] = rnd.Next(0, 100);
Console.Write(mas[i, j] + "\t");
}
Console.WriteLine();
but i can`t understand what mas[i, j] means. Like first our matrix is filled by default 0, but we inject i and j into our array and then i and j are filled by random numbers from 0 to 100? And what does"\t" mean?
It's just a coordinate to a position in a rectangular array (in your case a 5x5). This code will loop over ever row, and every column in each row, putting a random number in each
You start out with everything set to 0 when you make a new int[5,5]:
0 1 2 3 4
-+--------------
0| 0 0 0 0 0
1| 0 0 0 0 0
2| 0 0 0 0 0
3| 0 0 0 0 0
4| 0 0 0 0 0
And after the loops have finished running you end up with every array slot set to a random number:
0 1 2 3 4
-+--------------
0|22 75 43 97 45
1|11 4 97 28 33
2|84 92 51 89 32
3|32 54 63 91 60
4|71 2 39 74 1
i and j are not filled with random numbers; they are incremented by the loops so both will cycle through 0 to 5, i will do it once and j will do it 5 times:
i, j
0, 0
0, 1
0, 2
0, 3
0, 4
1, 0 <=j restarted from 0 when i went to 1
1, 1
...
4, 2
4, 3
4, 4
This is how each coordinate in the array is filled with a random number given by rnd.Next()
'\t' is a TAB character
I have an image that is stored in a DenseMatrix, using MathNet Numerics.
For rotating the image by 90 degrees counter-clockwise I want to get the transpose and then flip the result vertically by multiplying by the anti-diagonal identity matrix.
Is there a quick way to initialize that identity matrix?
For a 2x2 matrix that would look like:
0 1
1 0
Update:
I ended up doing pretty much what #Joseph suggested. Turns out to be sufficiently fast.
public static Matrix<double> CreateAntiIdentityMatrix(int n)
{
var output = Matrix<double>.Build.Dense(n, n, 0);
for (int i = 0; i <= n - 1; i++)
{
output[i, n - i - 1] = 1;
}
return output;
}
Something like this should work:
var M = MathNet.Numerics.LinearAlgebra.Double.Matrix.Build.Dense(N, N, 0);
for (i = 0; i <= N - 1; i++)
{
M(i, N - i - 1) = 1;
}
#Joseph's way is fast. But I'd like to introduce a way which is expressively shows MathNet functionality:
var size = 3;
var diagonal = DenseMatrix.CreateDiagonal(size, size, 1);
Console.WriteLine(diagonal);
var reversedColumns = diagonal.EnumerateColumns().Select(c => c.Reverse());
var anti = DenseMatrix.OfColumns(reversedColumns);
Console.WriteLine(anti);
To get an anti-diagonal matrix one can take a diagonal one and reflect it by width (reverse columns).
Result is:
DenseMatrix 3x3-Double
1 0 0
0 1 0
0 0 1
DenseMatrix 3x3-Double
0 0 1
0 1 0
1 0 0
Here is my code:
ShopButton[] allButtons = FindObjectsOfType<ShopButton> ();
for (int i = 0; i < allButtons.Length; i++)
{
allButtons [i].UpdateButtonState ((GameDataManager.publicInstance.skinAvailability & 1 << allButtons [i - 1].ninjaNumber) == 1 << allButtons [i - 1].ninjaNumber);
}
When I run it this code gives me an IndexOutOfRangeException.
I think the reason is because of the first index that causes a problem.
if i starts with 1 then i-1 will be 0 and therefore the index 0 exists in array allbuttons.
Clearly : if starting i is 0, then i-1 will be -1; this will cause index out of range exception because all arrays start with index 0 and have no index -1. ;
Starting with i = 1 the error will be solved because then i-1 will be 0 which is in range of indexes of any array.
change part of loop to :
for (int i = 1; i < allButtons.Length; i++)
For a given number n I have to print the following matrix (n = 3 example):
3 3 3 3 3
3 2 2 2 3
3 2 1 2 3
3 2 2 2 3
3 3 3 3 3
the count of rows and columns should be (2 * n) - 1. I tried to find the pattern but couldn't figured it out. Any help would be helpful. Thanks
Something like this:
private static int[][] Matrix(int n) {
// Create arrays
int[][] result = Enumerable.Range(0, 2 * n - 1)
.Select(_ => new int[2 * n - 1])
.ToArray();
// Feed arrays
for (int i = 1; i <= n; ++i) {
int from = i - 1;
int to = 2 * n - i - 1;
int v = n - i + 1;
for (int j = from; j <= to; ++j) {
result[from][j] = v;
result[to][j] = v;
result[j][from] = v;
result[j][to] = v;
}
}
return result;
}
....
int n = 3;
String report = String.Join(Environment.NewLine, Matrix(n)
.Select(line => String.Join(" ", line)));
Console.Write(report);
Output for n = 3 is
3 3 3 3 3
3 2 2 2 3
3 2 1 2 3
3 2 2 2 3
3 3 3 3 3
And for n = 4:
4 4 4 4 4 4 4
4 3 3 3 3 3 4
4 3 2 2 2 3 4
4 3 2 1 2 3 4
4 3 2 2 2 3 4
4 3 3 3 3 3 4
4 4 4 4 4 4 4
Here's a version that doesn't use any intermediate storage:
static void printMatrix(int n)
{
int x = 2*n - 1;
for (int i = 0, p = n; i < x; ++i, p += (i > x/2) ? 1 : -1)
{
for (int j = 0, q = n; j < x; ++j, q += (j > x/2) ? 1 : -1)
Console.Write(Math.Max(p, q) + " ");
Console.WriteLine();
}
}
This works as follows:
The outer loop (i) and inner loop (j) both go from 0 .. 2*n-1.
However, the values that we want to print (p and q) start at n and decrease until halfway across/down the matrix, at which point they start increasing again.
We can determine whether to increment or decrement these values by checking the loop variable to see if it is halfway across/down the matrix yet. If it is, we decrement, otherwise we increment.
That's what this is doing: p += (i > x/2) ? 1 : -1.
If i > x/2 then the value 1 will be used for the increment, otherwise -1 will be used for the increment (i.e. it will be decremented).
(Similarly for q.)
The final piece of the puzzle is that the value we want to use is actually the maximum of p and q. If you inspect the matrix, you will see that if you consider each row value and each column value, the maximum of each is used for the corresponding cell.
Hence the use of Math.Max(p, q) in the output.
Here a simpler solution less complicated and fastest here so far:
private static void printMatrix(int n)
{
// length of the matrix in one dimension
int length = (2 * n) - 1;
// iterate through y axis of the matrix
for (int i = 0; i < length; i++)
{
int value = n;
// iterate through x axis of the matrix
for (int j = 0; j < length; j++)
{
Console.Write(value);
if (i > j && i + j < length - 1)
{
value--;
}
else if (i <= j && i + j >= length - 1)
{
value++;
}
}
Console.WriteLine();
}
}
Explanation for the if statements
First take a look on the matrix like it would be an array and look at the indexes and values and what changes when iterating through the array in the two for statements whereas the value of i is for the y axis, from up to down and the value of j is for the x axis, from left to right.
// +1 and -1 means the changes of the values
0,0 0,1 0,2 0,3 0,4 // values of i,j (first is i, second is j)
[3] [3] [3] [3] [3] // printed value
1,0 1,1 1,2 1,3 1,4
[3] -1 [2] [2] [2] +1 [3]
2,0 2,1 2,2 2,3 2,4
[3] -1 [2] -1 [1] +1 [2] +1 [3]
3,0 3,1 3,2 3,3 3,4
[3] -1 [2] [2] [2] +1 [3]
4,0 4,1 4,2 4,3 4,4
[3] [3] [3] [3] [3]
As you can see, the value changes only in specific circumstances.
And this happens -1 if i > j and if i + j < length - 1, otherwise after index 3,1 you will have wrong values, after that it shouldn't subtract the value any more.
This two if statements lead us to the first statement in the code:
if (i > j && i + j < length - 1)
{
value--;
}
Now it also happens +1 if i + j >= length - 1 but that not other values like 3,1 also add +1 to the value it only increments it, if i <= j, which leads us to the second if-statement in the code:
else if (i <= j && i + j >= length - 1)
{
value++;
}
If none of these statements are true, the value simply stays the same as it should.
I'm trying to create a piece of code that will show this at the end
1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
4 4 4 4 4
5 5 5 5 5
But what I've written shows this instead
1 1 1 1 1
2 0 0 0 0
3 0 0 0 0
4 0 0 0 0
5 0 0 0 0
Here's the code I've written
int col, lig, test;
col = 0;
test = 0;
for (lig = mat.GetLowerBound(0); lig <= mat.GetUpperBound(0); lig++)
{
mat[lig, col] = 1 + test++;
}
for (col = mat.GetLowerBound(0) + 1; col <= mat.GetUpperBound(0); col++)
{
mat[0, col] = mat[0, col] + 1;
}
I've tried multiple things but none of them worked, what can I modify so that it gives the result I'm trying to get?
There are a few things wrong with your code:
You are checking the bounds of the array in dimension 0 for the second loop (for col), but using col in dimension 1 of the array: you should be using GetLowerBound(1) and GetUpperBound(1) instead. This isn't an issue here because you have a square array, but you should be aware.
You need to use a nested loop over the row and column, not two separate j loops. Your code is doing what you tell it to:
In the first loop you're setting mat[lig, col] but col is zero so you only set values in the first column. By declaring lig and col in the loops (see my code below) you can avoid this mistake.
In the second loop you're setting mat[0, col] which will only change values in the first row.
Additionally, you're starting the second loop at mat.GetLowerBound(0) + 1 which will miss the first element out. Presumably you did this on purpose because it set the element at (0,0) to 2.
The code you need is:
int test = 0;
for ( int lig = mat.GetLowerBound(0); lig <= mat.GetUpperBound(0); lig++ )
{
test++;
for ( int col = mat.GetLowerBound(1); col <= mat.GetUpperBound(1); col++ )
mat[lig, col] = test;
}
You can further simplify this by noting that test is always lig + 1 and eliminate test altogether:
for ( int lig = mat.GetLowerBound(0); lig <= mat.GetUpperBound(0); lig++ )
{
for ( int col = mat.GetLowerBound(1); col <= mat.GetUpperBound(1); col++ )
mat[lig, col] = lig + 1;
}