rotate a 4x4 array by 180 degrees c# - c#

hi i need to know how to rotate an array by 180 degrees in place. currently i can get it to rotate 90 degrees but just cannot get it to rotate any further. If anyone can help me that would be great as I've been stuck on this question for a couple of days now. Thanks, here is my code:
namespace Question_2_1_
{
class Program
{
static void Main(string[] args)
{
int[,] array = new int[4, 4] {
{ 1,2,3,4 },
{ 5,6,7,8 },
{ 9,0,1,2 },
{ 3,4,5,6 } };
int[,] rotated = RotateMatrix(array, 4);
var rowCount = array.GetLength(0);
var colCount = array.GetLength(1);
for (int i = 0; i < rowCount; i++)
{
for (int j = 0; j < colCount; j++)
{
Console.Write(String.Format("{0}", rotated[i, j]));
}
Console.Write(Environment.NewLine);
}
Console.ReadLine();
}
static int[,] RotateMatrix(int[,] matrix, int n)
{
int[,] ret = new int[n, n];
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
ret[i, j] = matrix[n - j - 1, i];
}
}
return ret;
}
}
}

You say you want to rotate in-place, but your rotate method returns a new array. Rotating in-place means you modify the matrix itself, without creating a new one.
But, if you're rotating 90 degrees, you can of course only rotate in-place if the matrix is square.
However, you can always rotate in-place if you're rotating 180 degrees. Let's take a non-square matrix:
{ a, b, c, d, e, f },
{ g, h ,i, j, k, l },
{ m, n, o, p, q, r }
If we rotate it 180 degrees, we end up with:
{ r, q, p, o, n, m },
{ l, k, j, i, h, g },
{ f, e, d, c, b, a }
You can see that an item at [r, c] ends up at [#rows - r - 1, #columns - c - 1]. (0-based of course),
so b at [0, 1] ends up at [3 - 0 - 1, 6 - 1 - 1]
The method you can use is: first swap a and r, then b and q, etc.
This is similar to reversing a 1-dimensional array, just in 2 dimensions.
Just as when reversing a 1-dimensional array, we only go halfway:
the last 2 items we swap are i and j.
I made the method generic, so you can rotate any matrix with it.
static void Rotate180<T>(T[,] matrix) {
int rowCount = matrix.GetLength(0), columnCount = matrix.GetLength(1);
int max = rowCount * columnCount / 2, m = 0;
for (int r = 0; ; ++r) {
for (int c = 0; c < columnCount; ++c) {
Swap(matrix, r, c, rowCount - r - 1, columnCount - c - 1);
if (++m >= max) return;
}
}
}
static void Swap<T>(T[,] matrix, int r1, int c1, int r2, int c2) {
T temp = matrix[r1, c1];
matrix[r1, c1] = matrix[r2, c2];
matrix[r2, c2] = temp;
}

The answer you're looking for is:
ret[i, j] = [n - (i + 1), n - j - 1];
However, this is not in-place as you're creating an entirely different array "ret"

Do it with reversing the columns first, and then the rows.
class Program
{
static void Main(string[] args)
{
var A = new int[,] { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }, { 13, 14, 15, 16 } };
RotateMatrix180(ref A);
// A = {{16,15,14,.. }, .. , { ..3,2,1} }
}
public static void RotateMatrix180<T>(ref T[,] matrix)
{
int n = matrix.GetLength(0), m = matrix.GetLength(1);
if(n!=m) { /* error */ }
for(int i = 0; i<n; i++)
{
for(int j = 0; j<n/2; j++)
{
T temp = matrix[i, j];
matrix[i, j]=matrix[i,n-j-1];
matrix[i, n-j-1]=temp;
}
}
for(int i = 0; i<n/2; i++)
{
for(int j = 0; j<n; j++)
{
T temp = matrix[i, j];
matrix[i, j]=matrix[n-i-1, j];
matrix[n-i-1, j]=temp;
}
}
}
}
PS. I added the ref keyword to make it obvious the function modifies the existing array. The code will work the same without it, because arrays are always reference types.

Related

Is it possible to move around in an array for new location?

I am messing around and making a text based game, I am using an array as my layout for a map and I have a random starting point, and from that point I want to be able to move up down left and right but I am not sure how to proceed
int[,] dungeon = new int[5, 5] { {1,2,3,4,5},
{6,7,8,9,10},
{11,12,13,14,15},
{16,17,18,19,20},
{21,22,23,24,25}};
shuffleArray(dungeon);
int startingPoint;
// i think this has to be in the actual game loop for a new random spot?
for(int i = 0; i<1; i++)
{
for(int j = 0; j < 1; j++)
{
startingPoint = dungeon[i,j];
Console.WriteLine(startingPoint);
}
}
void shuffleArray(int[,] arr)
{
int n = arr.GetLength(0);
int m = arr.GetLength(1);
Random rand = new Random();
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
swap(arr, i + rand.Next(n - i), j + rand.Next(m - j), i, j);
}
}
}
void swap(int[,] arr, int changed, int changedB, int a, int b)
{
int temp = arr[a, b];
arr[a, b] = arr[changed, changedB];
arr[changed, changedB] = temp;
}
Given a starting point (I'm calling it "position"), you can find the value in the shuffled array with this method:
// position is NOT zero-based! In a 5x5 matrix 1 is the first position
// and 25 is the last position
int getValueAtPosition(int position)
{
//assuming non-jagged board!
var w = dungeon.GetLength(0);
int row = position % w == 0 ? (position / w) : (position / w) + 1;
int col = position % w == 0 ? w : position - ((row - 1) * w);
int location = dungeon[row - 1, col - 1];
return location;
}
Now, if you move left you subtract one from the current position and pass it into this method. Likewise, add 1 to move right.
To move up or down subtract or add 5.
Be sure to check bounds so you don't move out of the matrix when adding or subtracting.

How create matrix from array in C#

I have array with data. Array length equals 25 elements. I would like create matrix (5X5). How I can do this in C#? Please help.
Translating a single dimension array into a multi dimension array is straight forward.
public static T getEntry<T>(this T[] array, int column, int row, int width)
{
return array[column+row*width];
}
Add wrapper classes and/or validation as desired.
Usage example:
var array=Enumerable.Range(1,25).ToArray();
for (int row = 0; row < 5; row ++)
{
for (int column = 0; column < 5; column ++)
{
Console.WriteLine("Value in column {0}, row {1} is {2}", column, row, array.getEntry(column,row));
}
}
You can use Buffer.BlockCopy
using System;
class Test
{
static double[,] ConvertMatrix(double[] flat, int m, int n)
{
if (flat.Length != m * n)
{
throw new ArgumentException("Invalid length");
}
double[,] ret = new double[m, n];
// BlockCopy uses byte lengths: a double is 8 bytes
Buffer.BlockCopy(flat, 0, ret, 0, flat.Length * sizeof(double));
return ret;
}
static void Main()
{
double[] d = { 2, 5, 3, 5, 1, 6 };
double[,] matrix = ConvertMatrix(d, 3, 2);
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 2; j++)
{
Console.WriteLine("matrix[{0},{1}] = {2}", i, j, matrix[i, j]);
}
}
}
}
As #Taemyr suggest you can simply use indexing to simulate the structure of the matrix. If you need to access the element at row 2, col 3 in a 5 by 5 matrix simply access index 2*5+3 of your array. (row * # of cols + col)
If you want to split your array into a 2D array you can do so using the following code:
public static T[,] Matrix<T>(T[] arr, int rows) {
var cols = arr.Length / rows;
var m = new T[rows, cols];
for (var i = 0; i < arr.Length; i++)
m[i / cols, i % cols] = arr[i];
return m;
}

How can I delete rows and columns from 2D array in C#?

How to delete a specific row and column from 2D array in C#?
int[,] array= {{1,2,3},{4,5,6},{7,8,9}};
lets say I want to delete row i and column i (skipping them) ... for nXn array not just 3x3 and store the remaining array in a new array...
so the output would be:
{5,6},{8,9}
There's no built-in way to do that, you can do it yourself:
static void Main()
{
int[,] array = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
var trim = TrimArray(0, 2, array);
}
public static int[,] TrimArray(int rowToRemove, int columnToRemove, int[,] originalArray)
{
int[,] result = new int[originalArray.GetLength(0) - 1, originalArray.GetLength(1) - 1];
for (int i = 0, j = 0; i < originalArray.GetLength(0); i++)
{
if (i == rowToRemove)
continue;
for (int k = 0, u = 0; k < originalArray.GetLength(1); k++)
{
if (k == columnToRemove)
continue;
result[j, u] = originalArray[i, k];
u++;
}
j++;
}
return result;
}
No, arrays don't let you do that. You could make your own data structure for that, but it's not going to be exactly simple (unlike if you only wanted to be able to remove rows, for example).
For simple operations, it would be quite enough to build a class on top of an underlying array, and handle the re-indexing to map the virtual 2D array to the physical array underneath. But it's going to get a bit tricky as you combine removals and additions, and deform the array overall.
Very simple logic. Just play with the loop:
int[,] array = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
int[,] arrayskip = new int[array.GetLength(0) - 1, array.GetLength(1) - 1];
for (int i = 1; i < array.GetLength(0); i++)
{
for (int j = 1; j < array.GetLength(1); j++)
{
arrayskip[i - 1, j - 1] = array[i, j];
}
}
I created this method, have a look
public static double[,] fillNewArr(double[,] originalArr, int row, int col)
{
double[,] tempArray = new double[originalArr.GetLength(0) - 1, originalArr.GetLength(1) - 1];
int newRow = 0;
int newCol = 0;
for (int i = 0; i < originalArr.GetLength(0); i++)
{
for (int j = 0; j < originalArr.GetLength(1); j++)
{
if(i != row && j != col)
{
tempArray[newRow, newCol] = originalArr[i, j];
newRow++;
newCol++;
}
}
}
return tempArray;
}
having some out of range, It's obvious why but I'm trying to get there...

How to reshape an Array in c#

I have a 3D array of bytes in c# which I have read from a bitmap:
byte[w, h, 3]
What is the easiest and more performance-friendly way of reshaping this array into 2D (linear) form?
byte[w*h, 3]
In other words I want to keep number of channels (features) but in a linear shape (rather than a square shape)
Let me try to illustrate input and desired output:
input:
|(r1,g1,b1) (r2,g2,b2) (r3,g3,b3)|
|(r4,g4,b4) (r5,g5,b5) (r6,g6,b6)|
|(r7,g7,b7) (r8,g8,b8) (r9,g9,b9)|
note that arr[0, 0, 0] = r1, arr[0, 0, 1] = g1, arr[0, 0, 2] = b1, etc..
and output:
|(r1,g1,b1) (r2,g2,b2) (r3,g3,b3) (r4,g4,b4) (r5,g5,b5) (r6,g6,b6) ...|
This seems to work fine, because the array is already in the right shape in memory:
var a = new byte[2, 2, 2] { { { 1, 2 }, { 3, 4 } }, { { 5, 6 }, { 7, 8 } } };
var b = new byte[2 * 2, 2];
//sizeof(byte) is obviously 1 here, but I put it there for documentation
Buffer.BlockCopy(a, 0, b, 0, a.Length * sizeof(byte));
For those interested: As for what to do if you really want to transpose a 2D array into 1D:
byte[,] a = {
{1, 2},
{3, 4},
{5, 6},
};
var b = new byte[a.GetLength(1) * a.GetLength(0)]; //Transpose
const int R_STRIDE1 = 8; //Tune this for your CPU
const int C_STRIDE1 = 8; //Tune this for your CPU
//You should hoist the calls to GetLength() out of the loop unlike what I do here
for (int r1 = 0; r1 < a.GetLength(0); r1 += R_STRIDE1)
for (int c1 = 0; c1 < a.GetLength(1); c1 += C_STRIDE1)
for (int r2 = 0; r2 < R_STRIDE1; r2++)
for (int c2 = 0; c2 < C_STRIDE1; c2++)
{
var r = r1 + r2;
var c = c1 + c2;
if (r < a.GetLength(0) && c < a.GetLength(1))
b[c * a.GetLength(0) + r] = a[r, c];
}
This should take advantage of caching in the CPU. I have only performed limited testing on this -- it could still be slow. Try tweaking it if it is.
You can (somewhat non-trivially) extend this to a 3D array.
Buffer.BlockCopy will do it. At least, it works in this simple test.
byte[, ,] src = new byte[10, 10, 3];
byte[,] dest = new byte[100, 3];
List<byte> srcList = new List<byte>();
Random rnd = new Random();
for (int i = 0; i < 10; ++i)
{
for (int j = 0; j < 10; ++j)
{
for (int k = 0; k < 3; ++k)
{
byte b = (byte)rnd.Next();
src[i, j, k] = b;
srcList.Add(b);
}
}
}
Buffer.BlockCopy(src, 0, dest, 0, 300);
List<byte> destList = new List<byte>();
for (int i = 0; i < 100; ++i)
{
for (int j = 0; j < 3; ++j)
{
destList.Add(dest[i, j]);
}
}
// See if they're in the same order
for (int i = 0; i < srcList.Count; ++i)
{
Console.WriteLine("{0,3:N0} - {1,3:N0}", srcList[i], destList[i]);
if (srcList[i] != destList[i])
{
Console.WriteLine("ERROR!");
}
}
That said, I wouldn't use Buffer.BlockCopy in this way unless I was absolutely sure that there weren't odd cases with padding issues, etc. And although Buffer.BlockCopy is certainly faster than the equivalent explicit loop, it shouldn't materially affect the runtime of your program. Unless you're doing this conversion inside a piece of code that's called very, very often ... in which case you have bigger problems.
I would suggest writing the explicit loop.
As an alternative you might want to use System.Numerics.Tensors:
It makes reshaping very easy:
using System.Numerics.Tensors;
..
var src = new byte[3, w, h]
var dst = ArrayTensorExtensions
.ToTensor(src)
.Reshape(new[] { 3, w * h });

How can I multiply two matrices in C#?

Like described in the title, is there some library in the Microsoft framework which allows to multiply two matrices or do I have to write my own method to do this? // I've got an answer to this by now
Second question:
I wrote this multi class with a MultiplyMatrix method but it doesn't work like I want to. Can anyone help and tell where I made a mistake?
class multi
{
public void MultiplyMatrix(double[,] _A, double[,] _B, int _n, int _m, int _r)
{
int n, m, r;
double si;
n = _n;
m = _m;
r = _r;
double[,] A = new double[n, m];
double[,] B = new double[m, r];
double[,] C = new double[n, r];
A = _A;
B = _B;
try
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < r; j++)
{
si = 0;
for (int k = 0; k < m; k++)
{
si += A[i, m + k] + B[k, r + j];
}
C[i, r + j] = si;
}
}
for (int i = 0; i < C.Length; i++)
{
for (int j = 0; j < C.Length; j++)
{
Console.Write(C[i, j]+" ");
if (j % 3 == 0)
Console.WriteLine();
}
}
}
catch (IndexOutOfRangeException) { } // I always get this exception
}
}
I forgot to tell: I want to make a webservice to multiply on it.
Thanks:)
Multiplication of 2 matrixes:
public double[,] MultiplyMatrix(double[,] A, double[,] B)
{
int rA = A.GetLength(0);
int cA = A.GetLength(1);
int rB = B.GetLength(0);
int cB = B.GetLength(1);
if (cA != rB)
{
Console.WriteLine("Matrixes can't be multiplied!!");
}
else
{
double temp = 0;
double[,] kHasil = new double[rA, cB];
for (int i = 0; i < rA; i++)
{
for (int j = 0; j < cB; j++)
{
temp = 0;
for (int k = 0; k < cA; k++)
{
temp += A[i, k] * B[k, j];
}
kHasil[i, j] = temp;
}
}
return kHasil;
}
}
Whilst there's no built in Maths framework to do this in .NET (could use XNA's Maths library), there is a Matrix in the System.Windows.Media namespace. The Matrix structure has a Multiply method which takes in another Matrix and outputs a Matrix.
Matrix matrix1 = new Matrix(5, 10, 15, 20, 25, 30);
Matrix matrix2 = new Matrix(2, 4, 6, 8, 10, 12);
// matrixResult is equal to (70,100,150,220,240,352)
Matrix matrixResult = Matrix.Multiply(matrix1, matrix2);
// matrixResult2 is also
// equal to (70,100,150,220,240,352)
Matrix matrixResult2 = matrix1 * matrix2;
This is mainly used for 2D transformation:
Represents a 3x3 affine transformation
matrix used for transformations in 2-D
space.
but if it suits your needs, then there's no need for any third party libraries.
Although you can multiply matrices by an iterative approach (for loops), performing the calculations with linear algebra will clean up your code and will give you performance gains that are several times faster!
There is a free library available in nuget - MathNet.Numerics. It makes it extremely easy to multiply matrices:
Matrix<double> a = DenseMatrix.OfArray(new double[,] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } });
Matrix<double> b = DenseMatrix.OfArray(new double[,] { { 1 }, { 2 }, { 3 } });
Matrix<double> result = a * b;
It has no dependencies and can be used in .net core 2.0, making it an excellent choice to avoid iterative matrix multiplication techniques and take advantage of linear algebra.
There is nothing built into .NET. You will have to write the multiplication yourself or use some third party library. I've blogged about one way to achieve this comparing two different implementations : a standard naive algorithm and one using unsafe code.
CSML - C# Matrix Library - is a compact and lightweight package for numerical linear algebra. Many matrix operations known from Matlab, Scilab and Co. are implemented.
See this!
There are no such built in libraries. Unless you are using XNA - it has a Matrix class, though it is limited and designed for 3D games.
There are many matrix libraries for .NET though.
namespace matrix_multiplication
{
class Program
{
static void Main(string[] args)
{
int i, j;
int[,] a = new int[2, 2];
Console.WriteLine("Enter no for 2*2 matrix");
for (i = 0; i < 2; i++)
{
for (j = 0; j < 2; j++)
{
a[i, j] = int.Parse(Console.ReadLine());
}
}
Console.WriteLine("First matrix is:");
for (i = 0; i < 2; i++)
{
for (j = 0; j < 2; j++)
{
Console.Write(a[i,j]+"\t");
}
Console.WriteLine();
}
int[,] b = new int[2, 2];
Console.WriteLine("Enter no for 2*2 matrix");
for (i = 0; i < 2; i++)
{
for (j = 0; j < 2; j++)
{
b[i, j] = int.Parse(Console.ReadLine());
}
}
Console.WriteLine("second matrix is:");
for (i = 0; i < 2; i++)
{
for (j = 0; j < 2; j++)
{
Console.Write(b[i, j] + "\t");
}
Console.WriteLine();
}
Console.WriteLine("Matrix multiplication is:");
int[,] c = new int[2, 2];
for (i = 0; i < 2; i++)
{
for (j = 0; j < 2; j++)
{
c[i,j]=0;
for (int k = 0; k < 2; k++)
{
c[i, j] += a[i, k] * b[k, j];
}
}
}
for (i = 0; i < 2; i++)
{
for (j = 0; j < 2; j++)
{
Console.Write(c[i, j]+"\t");
}
Console.WriteLine();
}
Console.ReadKey();
}
}
}
output
Enter no for 2*2 matrix
8
7
6
0
First matrix is:
8 7
6 0
Enter no for 2*2 matrix
4
3
2
1
second matrix is:
4 3
2 1
Matrix multiplication is:
46 31
24 18
Below is the method to multiply int[3,4] matrix with int[4,3] matrix, it has time complexity of O(n cube) or Cubic time
class Program
{
static void Main(string[] args)
{
MultiplyMatrix();
}
static void MultiplyMatrix()
{
int[,] metrix1 = new int[3,4] { { 1, 2,3,2 }, { 3, 4,5,6 }, { 5, 6,8,4 } };
int[,] metrix2 = new int[4, 3] { { 2, 5, 3 }, { 4, 5, 1 }, { 8, 7, 9 }, { 3, 7, 2 } };
int[,] metrixMultplied = new int[3, 3];
for (int row = 0; row < 3; row++)
{
for (int col = 0; col < 3; col++)
{
for(int i=0;i<4;i++)
{
metrixMultplied[row, col] = metrixMultplied[row, col] + metrix1[row, i] * metrix2[i, col];
}
Console.Write(metrixMultplied[row, col] + ", ");
}
Console.WriteLine();
}
Console.ReadLine();
}
}
Here is my code : 4*4 matrix
for (int i = 0; i < 4; i++)
{
int column = 0;
while (column < 4)
{
int count = 0;
for (int j = 0; j < 4; j++)
{
matrixResult[i, column] += Convert.ToInt32(matrixR[i, j] * matrixT[count, column]);
count = count + 1;
}
column = column + 1;
}
}
If you have a helper to generate, iterate and populate an int[,] matrix like this one:
public class VisitMatrix{
public static int[,] execute(int rows, int columns, Func<int, int, int> fn)
{
int[,] result = new int[rows, columns];
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
result[i, j] = fn(i, j);
}
}
return result;
}
}
Now matrix multiplication is as trivial as doing (supposing m1.GetLength(1) == m2.GetLength(0)):
public class MultiplyMatrices{
public static int[,] execute(int[,] m1, int[,] m2, int modulus = 10)
{
return VisitMatrix.execute(m1.GetLength(0), m2.GetLength(1), (i, j) =>
Enumerable.Range(0, m1.GetLength(1)-1)
.Select(k => m1[i, k] * m2[k, j])
.Aggregate(0, (a, b) => a + b, e => e % modulus)
}
}

Categories

Resources