Concatenate a 2D array - c#

I have two arrays mat1 & Mat2.
I want to have new_mat=[ma1,mat2];
I have written a function which works. I wonder if there is an efficient function for very large matrix or How can I do it with Array.CopyTo method.
public static double[,] Concatenate_matrix_byCol(double[,] Mat1, double[,] Mat2)
{
int col1=Mat1.GetLength(1);
int col2 = Mat2.GetLength(1);
int row1=Mat1.GetLength(0);
int row2 = Mat2.GetLength(0);
int i, j, y;
double[,] newMat = new double[row1, col1 + col2];
for (i = 0; i < row1; i++)
{
for (j = 0; j < col1; j++)
{
newMat[i, j] = Mat1[i, j];
}
}
for (i = 0; i < row1; i++)
{
for (y = 0; y < col2; y++)
{
newMat[i, y+col1] = Mat2[i, y];
}
}
return newMat;
}

You could combine your loops into:
for (i = 0; i < row1; i++)
{
for (j = 0; j < col1; j++)
newMat[i, j] = Mat1[i, j];
for (y = 0; y < col2; y++)
newMat[i, y+col1] = Mat2[i, y];
}
And maybe use pointers instead (test performance first!) but a library would properly be the best solution. That way you don't have to do micro-optimizations yourself.
There is a lot of libraries for .Net mentioned in this thread: Matrix Library for .NET
Depending on your performance requirement you could also look into parallel algorithms and you may be inspired by http://innovatian.com/2010/03/parallel-matrix-multiplication-with-the-task-parallel-library-tpl/. Again, a well-build library probably already have parallel algorithms.

When moving Arrays, you should look into Array.CopyTo instead of moving the cells one by one.
Also you could create a class that accepts the 2 matrices, and provides a level of abstraction that makes them look like 1 matrix but just keeps them seperate underneath.
For instance M1 = 20x 30 and M2 = 25 x 30 so you have a class M3 that 'looks like' M1 + M2, a 55 x 30 matrix.
When someone asks for M3[28, 23] this class will know that it should redirect to M2[8, 23] because M1 was only 20 positions wide (28-20=8). That way you don't have to copy the memory, that's expensive. Figuring out how to reroute a request to the right matrix is much cheaper. Depends on how much the matrix accessed afterwards obviously.
edit
This is what I mean:
class Program {
static void Main(string[] args) {
int[,] x = { { 1, 2, 3 }, { 4, 5, 6 } };
int[,] y = { { 7, 8, 9 }, { 10, 11, 12 } };
var xy = new StitchMatrix<int>(x, y);
Console.WriteLine("0,0=" + xy[0, 0]); // 1
Console.WriteLine("1,1=" + xy[1, 1]); // 5
Console.WriteLine("1,2=" + xy[1, 2]); // 6
Console.WriteLine("2,2=" + xy[2, 2]); // 9
Console.WriteLine("3,2=" + xy[3, 2]); // 12
}
}
class StitchMatrix<T> {
private T[][,] _matrices;
private int[] _lengths;
public StitchMatrix(params T[][,] matrices) {
// TODO: check they're all same size
_matrices = matrices;
// call uperbound once for speed
_lengths = _matrices.Select(m => m.GetUpperBound(0)).ToArray();
}
public T this[int x, int y] {
get {
// find the right matrix
int iMatrix = 0;
while (_lengths[iMatrix] < x) {
x -= (_lengths[iMatrix] + 1);
iMatrix++;
}
// return value at cell
return _matrices[iMatrix][x, y];
}
}
}
Regards Gert-Jan

Related

moving an element in 2d array with arrow keys and having border restricting movement

I dont know if this has been answered before but how would I move an element in 2d array with arrow keys? say something like this and having it not move if it is not possible as in the image displayed 0 can swap and go up, down, left and right but the next move you are restricted to just three options as up,down and left only
New to c# so if there are helpful examples online about my problem just post them down the comment
using System;
namespace moveElement
{
public class move
{
static void Main(string[] args)
{
int[,] arr = { { 9, 1, 4 }, { 5, 0, 3 }, { 6, 8, 2 } };
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
Console.Write(arr[i, j] + " ");
}
Console.WriteLine();
}
}
}
}
Took what was suggested and made it work somehow like this
ConsoleKeyInfo info = Console.ReadKey();
if (info.Key == ConsoleKey.RightArrow)
{
int temp = arr[1, 1];
arr[1, 1] = arr[1, 2];
arr[1, 2] = temp;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
Console.Write(arr[i, j] + " ");
}
Console.WriteLine();
}
}
After working on the code for sometime I get error "use of unassigned local variable x and y" on line 41(y) and 47(x) I have completed most of the problem but stuck on this error
using System;
namespace moveElement
{
public class move
{
static void Main(string[] args)
{
int x, y;
int[,] arr = { { 0, 1, 4 }, { 3, 9, 5 }, { 6, 8, 2 } };
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
Console.Write(arr[i, j] + " ");
Solved the problem by giving x and y a value of 0.
You could try something similar to the answer of this post where you take the variable of position 1, put it in a temp variable, then set position 1 to the value of position 2 and finally set the value of position 2 to what is in the temp variable:
var t = a;
a = b;
b = t;
To actually figure out if you can move in a specific direction, you will need to check if you are at a boundary, for example, the boundaries would be (where i is any valid position):
arr[0, i]
arr[arr.getLength(0)-1, i]
arr[i, 0]
arr[i, arr.getLength(1)-1]
if your current position is the same as one of those, you will need to add some conditions so that you cant move in a specific direction, for example, if you have arr[0, i], you cannot move up one as it will then go to arr[-1, i] which does not exist.
I would suggest reading up on the Array.getLength(Int32 dimension) method for finding the boundaries (it essentially gets the length of the array at a specified dimension)

Limit the array size 2D (C# UNITY)

Hello guys is it possible to limit the array size just like this example
Now i want only to show 6 of them.
What i have done so far is this
CustomClass
const int MAX = 104; // = 8 decks * 52 cards / 4cardsoneround
const int Y = 6;
int[,] arrayRoad = new int[Y, X];
public int[,] GetRoad(int x) {
arrayRoad = new int[x, 6];
return arrayRoad;
}
Now I'm displaying it on my MainClass like this
ScoreBoard bsb = new ScoreBoard();
private void Road()
{
bsb.makeRoad(history); // Road
int[,] arrayRoad = bsb.GetRoad(6); //<--- sample value 6
string s = "";
for (int y = 0; y < arrayRoad.GetLength(0); y++)
{
//just 27 for now
for (int x = 0; x < 28; x++)
{
s += string.Format("{0:D2}",arrayRoad[y, x]);
s += ".";
}
s += "\n";
}
Debug.Log(s);
}
The problem with this code is that it's giving me an Array out of index
Is this possible??
Updated
public int[,] GetRoad(int x = MAX,int y = Y) {
arrayRoad = new int[y, x];
return arrayRoad;
}
Where in my Max = 104 and Y = 6
int[,] arrayRoad = bsb.GetRoad(12,6); //12 rows and 6 in height
string s = "";
for (int y = 0; y < arrayRoad.GetLength(0); y++)
{
for (int x = 0; x < arrayRoad.GetLength(1); x++)
{
s += string.Format("{0:D2}",arrayRoad[y, x]);
s += ".";
}
s += "\n";
}
Debug.Log(s);
}
I have all this value earlier before i perform the update code
Now when i perform the updated code here's what I got
The expected result must be this
Inside of that black marker those twelve columns only must be shown because i declared on my
int[,] arrayRoad = bsb.GetRoad(12,6);
Note this:
public int[,] GetBigEyeRoad(int x) {
arrayRoad = new int[x, 6]; // <-------------
return arrayBigEyeRoad;
There you are fixing the length of the second dimension of the array to 6.
for (int x = 0; x < 28; x++)
{
s += string.Format("{0:D2}",arrayBigEyeRoad[y, x]); // <------------
There, you are trying to access indices up to 28 on the second dimension of the array. The Out of Range error comes from that.
What I did here was copy my old array to the new one just like this code below
int[,] arrayBigRoadResult = new int[6, x];
//copy manually the element references inside array
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < x; j++)
{
arrayBigRoadResult[i, j] = arrayBigRoad[i, j];
}
}
return arrayBigRoadResult;
then by calling it just like this
int[,] arrayRoad = bsb.GetRoad(12);
It would only display 12 columns and 6 rows :)

Find Small Number in Matrix

I have a matrix like this
13 7 22
101 50 3
I Want to Print The smallest Number from the same.
Below is my Code:
using System;
class Class1
{ int min(int[,] arr)
{
int small = arr[0, 0];
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (small > arr[i, j])
{
small = arr[i, j];
}
}
}
return small;
}
public static void Main()
{
int[,] x;
x = new int[,] { { 13, 7, 22 }, { 101, 50, 3 } };
Class1 obj = new Class1();
Console.WriteLine("Smallest Element : {0}", obj.min(x));
Console.ReadLine();
}
}
Throws Error as
{"Index was outside the bounds of the array."}
Expected output is 3
Why am getting this error? Please give me solution.
Note that you can use foreach to iterate over all the elements of a multidimensional array without having to worry about indices.
So it is simpler to write your min() method like so (note that I'm also using Math.Min() to find the lower of two values rather than writing my own if to do it):
static int min(int[,] arr)
{
int small = int.MaxValue;
foreach (int n in arr)
small = Math.Min(n, small);
return small;
}
Also note how I initialised small to be the largest possible int, in order to avoid having to access the first value of the array to initialise it.
If you wanted to use Linq to do the same thing you can just do this:
int min = array.Cast<int>().Min();
The reason that Cast<int> is needed is because a multidimensional array only implements the non-generic IEnumerable rather than the generic IEnumerable<T>. See this question for more details.
However using Linq an advanced topic if you are currently learning C#, in which case don't worry about that for now!
Try the following code, it will resolve X x X matrix
List<List<int>> matrix = new List<System.Collections.Generic.List<int>>()
{
new List<int>() {5,10,6}, new List<int>() {6,11,7}, new List<int>() {7,12,8}, new List<int>() {8,13,9}
};
To find MIN Value:
matrix.SelectMany(m => m.Select(n => n)).OrderBy(m => m).FirstOrDefault().Dump();
To find MAX Value
matrix.SelectMany(m => m.Select(n => n)).OrderByDescending(m => m).FirstOrDefault().Dump();
If you are using multi dimensional array
int[,] matrix = { { 1, 2, 3 }, { 3, 4, 5 } };
IEnumerable<int> query = matrix.OfType<int>();
query.SelectMany(m => m.Select(n => n)).OrderBy(m => m).FirstOrDefault().Dump();
Your array is 2X3 so you have specify condition for first loop is i<2
Like this
int min(int[,] arr)
{
int small = arr[0, 0];
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
if (small > arr[i, j])
{
small = arr[i, j];
}
}
}
return small;
}

Optimizing my image search routine

My routine is as follows (the SpeedyBitmap class just locks each bitmap for faster pixel data access):
private static bool TestRange(int number, int lower, int upper) {
return number >= lower && number <= upper;
}
public static List<Point> Search(Bitmap toSearch, Bitmap toFind, double percentMatch = 0.85, byte rTol = 2, byte gTol = 2, byte bTol = 2) {
List<Point> points = new List<Point>();
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
int findArea = toFind.Width * toFind.Height;
int allowedMismatches = findArea - (int)(findArea * percentMatch);
int mismatches = 0;
using (SpeedyBitmap speedySearch = new SpeedyBitmap(toSearch)) {
using (SpeedyBitmap speedyFind = new SpeedyBitmap(toFind)) {
for (int i = 0; i < speedySearch.Height - speedyFind.Height + 1; i++) {
for (int j = 0; j < speedySearch.Width - speedyFind.Width + 1; j++) {
for (int k = 0; k < speedyFind.Height; k++) {
for (int l = 0; l < speedyFind.Width; l++) {
Color searchColor = speedySearch[j + l, i + k];
Color findColor = speedyFind[l, k];
if (!TestRange(searchColor.R, findColor.R - rTol, findColor.R + rTol) ||
!TestRange(searchColor.G, findColor.G - gTol, findColor.G + gTol) ||
!TestRange(searchColor.B, findColor.B - bTol, findColor.B + bTol)) {
mismatches++;
if (mismatches > allowedMismatches) {
mismatches = 0;
goto notFound;
}
}
}
}
points.Add(new Point(j, i));
continue;
notFound:
;
}
}
}
}
Console.WriteLine(stopwatch.ElapsedMilliseconds);
return points;
}
Searching a moderately sized image (1000x1000) takes over 20 seconds. Removing the percent match takes it down to a few hundred milliseconds, so I think I've established where the major bottleneck is.
How can I make this run faster? Perhaps I could flatten the two-dimensional arrays down to one-dimensional arrays and then apply some sort of sequence check on the two to possibly match up the longest sequence of where the toFind bitmap data appears with the respective tolerances and match percent. If this would be a good solution, how would I begin to implement it?

keeping array in an array

i want to save kingarray[x1+1,y1-1],king array[x1+1,y1],etc in an array(ways that king in chess game can go).how can i do it?or if its not possible what do you suggest me to keep the ways that king can go?thanks
int[,] kingarray = new int[8, 8];
for (i = 0; i < 1; i++)
{
return kingarray[x1 + 1, y1];
}
for (i = 1; i > 0; i--)
{
return kingarray[x1 - 1, y1];
}
for (j = 0; j < 1; j++)
{
return kingarray[x1, y1 + 1];
}
for (j = 1; j > 0; j--)
{
return kingarray[x1, y1 - 1];
}
for (i = 0; i < 1; i++)
for (j = 1; j > 0; j--)
{
return kingarray[x1 + 1, y1 - 1];
}
for (i = 1; i > 0; i--)
for (j = 0; j < 1; j++)
{
return kingarray[x1 - 1, y1 + 1];
}
for (i = 0; i < 1; i++)
for (j = 0; j < 1; j++)
{
return kingarray[x1 + 1, y1 + 1];
}
for (i = 1; i > 0; i--)
for (j = 1; j > 0; j--)
{
return kingarray[x1 - 1, y1 - 1];
}
what do you suggest me to keep the ways that king can go?
This may not answer your question directly, and that you have already marked the correct answer. But just to answer the above.
Rather than keeping the all the positions a king can go, I would keep the positions it is allowed to go and calculate the possible routes during run-time.
For any piece(King, Pawn, etc), there are 8 places that it can move. Left, right, up, down, top-left, top-right, bottom-left, bottom-right. Based upon the type of piece, you can control the movement.
For You can create a ChessPiece class. Declare 8 positional flags, bool flags probably, that would define the possible positions that a piece can move.
Declare the number of blocks a piece can skip, for instance directions(; and drive the types from the ChessPiece and allow.
--EDIT--
For instance, following:
//Class that contains the position of the Piece over the Tile
class PiecePosition
{
//Set the bounds an image/vector can move.
public int X, Y;
public PiecePosition(int x, int y) { this.X = x; this.Y = y; }
public PiecePosition(int x, int y, int width, int height) { this.X = x; this.Y = y; }
}
//Base ChessPeice class that shall be used to drive all types of chess pieces.
//Sixteen pieces: one king, one queen, two rooks, two knights, two bishops, and eight pawns
//http://en.wikipedia.org/wiki/Chess
abstract class ChessPiece
{
public object Image;//This is an "optional" object that contains the Picture of the Peice,
//alternatively, it may contain vector of the image that you want
//to draw. Right now this is object is here just for the sake of
//understanding that you can use this object here to Draw() it
//based upon its position.
//Possible movements of the unhindered piece=8
protected const int MaxDirectionsCount = 8;
public enum PieceType { King, Pawn, SomeOtherType }//Types of chess peice.
public enum Moves { Up, Down, Left, Right, TopLeft, Etc }//Possible positions a piece can move
protected PieceType Type; //Contains type of piece
protected Moves MoveableDirections;//Shall contain the allowable directions
public List<PiecePosition> listPositions;//List of possible positions to be calculated during runtime
//Defines a piece can skip
protected int SkippableBlocks;
public abstract void PossiblePositions(PiecePosition CurrentPosition);//Calculates possible positions
public abstract void Draw();//Draws the piece
}
//The King Chess piece
//http://en.wikipedia.org/wiki/King_%28chess%29
class King : ChessPiece
{
//Constructor that sets the type of piece
public King()
{
//Set the directions a King can move.
base.MoveableDirections = Moves.Down | Moves.Left | Moves.Right;
base.Type = PieceType.King;
SkippableBlocks = 1; //Max a king can move is one block in the base.Directions set above.
}
//Calculates possible available positions to move to, during runtime; based upon current position.
public override void PossiblePositions(PiecePosition CurrentPosition)
{
//Calculate position
//Since you know this is king piece, you can calculate the possible positions
//And add that the list of possible positions.
//For instance, a King can move
int X = 0; int Y = 0;
for (int i = 0; i < MaxDirectionsCount; i++)
{
//Calculate directions.
if (base.MoveableDirections == Moves.Down) { X = CurrentPosition.X - 1; Y = CurrentPosition.Y; }
if (base.MoveableDirections == Moves.Up) { X = CurrentPosition.X + 1; Y = CurrentPosition.Y; }
//Rest of the directions go here...
//...Btw, what would you do for cross directions?
//One way could be to pass a Rectangle in the ChessTile(x,y,width,height) constructor
//Add to list of possible directions.
listPositions.Add(new PiecePosition(X, Y));
}
}
public override void Draw()
{
//You can actually draw/redraw using the Image object
//based upon the current/moved position.
}
}
Btw, if you just started writing the code, I would suggest you stop. Look around for Chess class designs first, and see if you want make sense out of Chess Objects. For instance, ChessBoard, Game, Players, Piece, Movements, AllowablePositions, etc.
Take a look at questions related to Chess/Google abit, and see if the questions/answers and your logic is already inline.
Array?
It is rather easy to determine a King's possible movement.
class position { public int x, y }
...
public ArrayList<position> KingPossibleMove(position current)
{
var list = new ArrayList();
if (current.x>0) {
list.add(new position() { x= current.x - 1, y = current.y });
if (current.x<8) {
list.add(new position() { x= current.x + 1, y = current.y });
// The rest follows, try to determine if the move is within bound
// you can also look for if the move will cause immediate checkmate.
return list;
}
int[,][] declares a 1D array containing a 2D array of int. Is that what you want?
And the kingmoves can simply be calculated as:
IEnumerable<Position> ValidKingTargets(Position p)
{
int top=Math.Max(0,y-1);
int left=Math.Max(0,x-1);
int bottom=Math.Min(8,y+2);
int right=Math.Min(8,x+2);
for(int y=top;y<bottom;y++)
for(int x=left;x<right;x++)
if(x!=p.X || y!=p.Y)
yield return new Position(x,y);
}

Categories