The shortest way to initialize a point array? - c#

I am looking for the shortest way in terms of writing to declare an array of points.
My problem is that I have humongous point data that I want to hardcode as an initialization.
These initializations repeat the 'new Point' multiple times:
Point[] points1 = new[] { new Point { X = 0, Y = 0 }, new Point { X = 20, Y = 120 }, new Point { X = 40, Y = 60 }, }; // kinda long typing
Point[] points2 = { new Point(0, 0), new Point(20, 120), new Point(40, 60) }; // better
Alternatively I could declare the array like so:
int[,] arr = new int[,] { { 0, 0 }, { 20, 120 }, { 40, 60 } }; // so far shortest typing
But how can I cast int[,] to Point[] ?
Are there other alternatives (like using lists) ?

You can change new[] to new Point[]. This way, you can use target-typed new in the array elements:
Point[] points1 = new Point[] {
new() { X = 0, Y = 0 },
new() { X = 20, Y = 120 },
new() { X = 40, Y = 60 },
};
If Point has a 2-parameter constructor, this can be even shorter:
Point[] points1 = new Point[] {
new(0, 0),
new(20, 120),
new(40, 160)
};
If points1 is a local variable, you can make it even shorter by making the variable implicitly typed:
var points1 = new Point[] {
new(0, 0),
new(20, 120),
new(40, 160)
};
If you want to make this really short in the long run, you can make a (int, int)[], then convert to Point[]:
Point[] points1 = new[] {
(0, 0),
(20, 120),
(40, 160)
}.Select(x => new Point(x.Item1, x.Item2)).ToArray();

Definitely not the shortest way, But this approach has its own advantages. and it's only a one-time effort.
Making it configuration-driven will help in modifying the points. if in future you want to add/delete/modify points. It will help you in testing and also provide different02 points.
second, you can manage different points based on the environment as well.
public class Point
{
public int X { get; set; }
public int Y { get; set; }
}
public class Root
{
public Point[] Points { get; set; }
}
string json = File.ReadAllText("inut.json");
Root obj = JsonConvert.DeserializeObject<Root>(json); //Use NewtonSoft.json library to deserialize the JSON to object.
Sample JSON:
{
"Points": [{
"X": 0,
"Y": 0
},
{
"X": 10,
"Y": 20
}
]
}

Related

How to use struct to cover all integers in 2d array?

this is my first post.
I'm taking a programming course right now and my current assignment is to create an integer (we will call it the ant) which will move around to all integers in a 2d array (randomized path). Here is my code thus far:
namespace Ant
{
class Program
{
static void Main(string[] args)
{
int ant;
int i = 0;
int[,] numberGrid =
{
{1, 2},
{3, 4},
{5, 6},
{7, 8},
{9, 10},
{10, 11},
{11, 12},
{13, 14},
{15, 16},
{17, 18},
{19, 20},
};
do
{
Random rand = new Random();
ant= rand.Next(numberGrid[10, 1]);
Console.WriteLine(ant);
i++;
} while (i !=110);
Console.WriteLine("It took {0} steps for the ant to cover all spaces!", i);
}
}
}
I have the 2d array and I have temporarily set the ant up for a randomized path which will go on for 110 times before it stops. I'm supposed to integrate struct into this so that the ant will only go until it has visited all the integers of the 2d array instead of a set amount of times, but I'm absolutely clueless as to how I'm supposed to do this. If anyone could help me understand that would be great, thank you!
Without more detail of how your expected to do this it sounds like you need to make the Ant a struct and record where the Ant has been (or not been). Here's a way you could do it, though I'm sure performance-wise there's a better way:
static void Main(string[] args)
{
var unvisitedSpaces = new List<Coordinates>
{
//I've used your numbers but should this be a full matrix i.e. [1,1], [1,2], [1,3] etc.?
new Coordinates(1, 2),
new Coordinates(3, 4),
new Coordinates(5, 6),
new Coordinates(7, 8),
new Coordinates(9, 10),
new Coordinates(11, 12),
new Coordinates(13, 14),
new Coordinates(15, 16),
new Coordinates(17, 18),
new Coordinates(19, 20)
};
var ant = new Ant();
int counter = 0;
var r = new Random();
var min = Math.Min(unvisitedSpaces.Min(x => x.X), unvisitedSpaces.Min(y => y.Y));
var max = Math.Max(unvisitedSpaces.Max(x => x.X), unvisitedSpaces.Max(y => y.Y)) + 1;
do
{
ant.X = r.Next(min, max);
ant.Y = r.Next(min, max);
counter++;
//check if the ant hasn't visited this space by checking the unvisitedSpaces list.
if (unvisitedSpaces.Any(c => c.X == ant.X && c.Y == ant.Y))
{
//if it hasn't visited (the list contains that set of coordinates) then remove it from the list as it's now visited it.
var coord = unvisitedSpaces.FirstOrDefault(c => c.X == ant.X && c.Y == ant.Y);
unvisitedSpaces.Remove(coord);
}
} while (unvisitedSpaces.Count() > 0);
Console.WriteLine("It took {0} steps for the ant to cover all spaces!", counter);
Console.ReadLine();
}
public struct Coordinates
{
public int X { get; }
public int Y { get; }
public Coordinates(int x, int y)
{
X = x;
Y = y;
}
}
public struct Ant
{
public int X { get; set; }
public int Y { get; set; }
}
Result:
UPDATE
Added in the ability for it to automatically adjust the max and min values to be used by the 'random' by getting them from the coordinates matrix. Any adjustments to the matrix should therefore be included in the spaces the 'Ant' visits.

How to generate a Accord.Math.Sparse<double> element in C#?

I am trying to implement in C# the dot product, to do so, I am using Accord.Math and its method Dot as follows:
using Accord.Math;
namespace VectorOperations
{
class DotProduct
{
private static double CalculateDotProduct(Sparse<double> Vector1, Sparse<double> Vector2)
{
double DotProduct = Vector.Dot(Vector1, Vector2);
return DotProduct;
}
}
}
However I am not able to create an example where I can test if it is working correctly fine because I don't know how to create a variable of type Sparse<double>. How could I create one as an example? Ideally, I would like to have:
Sparse<double> Vector1 = new Sparse<double>();
Sparse<double> Vector2 = new Sparse<double>();
// Vector1 = [1, 2, 3];
// Vector2 = [1, 2, 3];
So I can call this.CalculateDotProduct(Vector1, Vector2) and check if it works correctly.
If you know any other method to compute the dotproduct with vectors of type List<double> are welcome too.
The unit tests show a couple of ways to create and fill an instance:
var s = new Sparse<double>();
s[0] = 1;
s[99] = 99;
s[10] = 42;
v = new double[] { 1, 2, 3, 0, 0, 6 };
d = Sparse.FromDense(v);
Another way is using the Sparse(int[] indices, T[] values) constructor:
Sparse<double> Vector1 = new Sparse<double>(new[] { 0, 1, 2 }, new[] { 1, 2, 3 });

Group items of array by three using Linq

I have an Array of bytes, representing the RGB values of an image.
How could I group each offset of 3 values (RGB) of this array to apply my tweaks (like removing the repeated colors), maybe using Linq?
["120", "100", "10", "120", "100", "10", "10", "60", "110"]
to
["120", "100", "10", "10", "60", "110"]
You can use Select to add index to your enumeration and later group by index / 3. A bit of post-processing on each of the groups and you should be able to get what you want:
var grouped = source.Select((x,i) => new { x, i })
.GroupBy(x -> x.i / 3)
.Select(g => g.ToList())
.Select(g => new { R = g[0], G = g[1], B = g[2] })
.Distinct();
But that feels quite ugly. If I were you I'd probably write a simple custom LINQ method (an extension method on IEnumerable<int>) to do this more efficiently.
Shorter version that gets the distinct RGB values and their indexes:
string[] a = { "120", "100", "10", "120", "100", "10", "10", "60", "110" };
var l = Enumerable.Range(0, a.Length / 3)
.ToLookup(i => new { R = a[i * 3], G = a[i * 3 + 1], B = a[i * 3 + 2] });
If you don't mind using a loop instead of Linq:
class Program
{
static void Main(string[] args)
{
byte[] array = new byte[] { 120, 100, 10, 120, 100, 10, 10, 60, 110 };
List<byte[]> grouped = new List<byte[]>();
// This loop will populate the list grouped with arrays of 3 bytes each, each representing an value for RGB
for(int i = 0; i + 2 < array.Length; i += 3)
{
byte[] currentColor = new byte[]
{
array[i],
array[i + 1],
array[i + 2]
};
grouped.Add(currentColor);
}
// Here you will remove repeated elements for RGB
// Notice you will have to create the ByteArrayComparer class, you will find the code right under this one
var noRepeatedElements = grouped.Distinct<byte[]>(new ByteArrayComparer());
// Print the non repeated elements for testing purposes
foreach(var rgb in noRepeatedElements)
{
foreach(var value in rgb)
{
Console.Write($"\"{value}\"");
}
}
Console.ReadKey();
}
}
Where ByteArrayComparer is the following class
// This class will compare two distinct byte arrays and check if their elements are the same
public class ByteArrayComparer : IEqualityComparer<byte[]>
{
public bool Equals(byte[] x, byte[] y)
{
int smallerArrayLength = Math.Min(x.Length, y.Length);
bool elementsWithSameValue = true;
for(int i = 0; i < smallerArrayLength; i++)
{
// If there is a single element which is different, we know the arrays are different and can break the loop.
if(x[i] != y[i])
{
elementsWithSameValue = false;
break;
}
}
return elementsWithSameValue;
}
public int GetHashCode(byte[] obj)
{
int hash = 0;
for(int i = 0; i < obj.Length; i++)
{
hash += obj[i].GetHashCode();
}
return hash;
}
}
Note that grouped now is a List of arrays of bytes. Each element in grouped has three elements, representing a single RGB value.
Now you can work with the rgb values as you please.
Using Microsoft's Reactive Framework Team's Interactive Extensions (NuGet "Ix-Main") you can do this:
byte[] array = new byte[]
{
120, 100, 10, 120, 100, 10, 10, 60, 110
};
byte[] results =
array
.Buffer(3)
.Distinct(xs => String.Join(",", xs))
.SelectMany(x => x)
.ToArray();
That will give you { 120, 100, 10, 10, 60, 110 }.

Linear Algebra MatrixMultiply method

EDIT:
After fixing the syntax error and working with this algorithm I found the MKL provider is not the matrix multiplication needed. This algorithm simply multiplies element by element and does not compute the dot(row_n,column_n) as I had originally thought.
other source
End Edit
I can't get this passed the compiler. I have looked all over for a good example but have come up short. The documentation I'm referencing is MklLinearAlgebraProvider
MathNet.Numerics.Algorithms.LinearAlgebra.Mkl.MklLinearAlgebraProvider
I'm trying to write a simple method to compute the rotation matrix R = rz*ry*rx from Euler angles. The problem is the compiler won't take ryXrx or resultMat arrays I'm trying to pass it. I've tried out keyword as well.
inputMat is a 1-D array of the form {x,y,z,rx,ry,rz} where x,y and z are translations and rx,ry and rz are rotation angles in degrees.
private float[,] EulerToHMat(float[] inputMat)
{
var linalg = new MathNet.Numerics.Algorithms.LinearAlgebra.Mkl.MklLinearAlgebraProvider();
double rzRad = ((double)inputMat[5])*Math.PI/180;
double cosZ = Math.Cos(rzRad);
double sinZ = Math.Sin(rzRad);
double ryRad = ((double)inputMat[4])*Math.PI/180;
double cosY= Math.Cos(ryRad);
double sinY = Math.Sin(ryRad);
double rxRad = ((double)inputMat[3])*Math.PI/180;
double cosX= Math.Cos(rxRad);
double sinX = Math.Sin(rxRad);
var rz = new float[,] { { (float)cosZ, -(float)sinZ, 0 }, { (float)sinZ, (float)cosZ , 0 }, {0,0,1 } };
var ry = new float[,] { { (float)cosY , 0 , (float)sinY }, { 0, 1 , 0 }, { -(float)sinY, 0, (float)cosY } };
var rx = new float[,] { {1,0,0 }, {0,(float)cosX,-(float)sinX }, {0,(float)sinX,(float)cosX } };
var ryXrx = new float[3,3];
var resultMat = new float[3, 3];
// won't take the matrix --ryXrx-- here
linalg.MatrixMultiply(ry, 3, 3, rx, 3, 3,ryXrx);
// won't take the matrix --resultMat-- here
linalg.MatrixMultiply(rz, 3, 3, ryXrx, 3, 3,resultMat);
return resultMat;
}
This seems like it should be simple.... Please ignore the casting mess.
According to the reference you linked, the method works on matrices that are stored in a SINGLE-dimensional array, you are trying to pass two-dimensionals.
Try this:
var rz = new float[] { (float)cosZ, -(float)sinZ, 0, (float)sinZ, (float)cosZ, 0, 0, 0, 1 };
var ry = new float[] { (float)cosY, 0, (float)sinY, 0, 1, 0, -(float)sinY, 0, (float)cosY };
var rx = new float[] { 1, 0, 0, 0, (float)cosX, -(float)sinX, 0, (float)sinX, (float)cosX };
int size = 3;
var ryXrx = new float[size * size];
var resultMat = new float[size * size];
// won't take the matrix --ryXrx-- here
linalg.MatrixMultiply(ry, size, size, rx, size, size,ryXrx);

How to initialize an array of Point? [duplicate]

This question already has answers here:
How to populate/instantiate a C# array with a single value?
(26 answers)
All possible array initialization syntaxes
(19 answers)
Closed 9 years ago.
I need to initialize an array of three points.
I want to write it like below, but only once for three elements.
Point P = new Point { X = 0, Y = 1 };
Point[] P = new Point[3];// <---- ?
How to write correctly?
Here is the code for creating the array of 3 different points:
Point[] points = new Point[] { new Point { X = 0, Y = 1 }, new Point { X = 2, Y = 1 }, new Point { X = 0, Y = 3 } };
There’s not really a shorthand for that. For three, just write it three times:
Point initial = new Point { X = 0, Y = 1 };
Point[] P = new Point[3] { initial, initial, initial };
Example below you can create 10 Point using Enumerable.Range
var points = Enumerable.Range(0, 10)
.Select(x => new Point {X = 0, Y = 1})
.ToArray();
Because you question deals about a static fixed length array of point with static coordinates, no needs to bother with LINQ and loops in this context when array initialization is that simple.
So you can initialize an array this way:
Point[] P = new Point[]
{
new Point { X = 0, Y = 1 },
new Point { X = 0, Y = 1 },
new Point { X = 0, Y = 1 },
...
};
or use duck typing type inference (thanks minitech):
var P = new []
{
new Point { X = 0, Y = 1 },
new Point { X = 0, Y = 1 },
new Point { X = 0, Y = 1 },
...
};
Here is the shortest solution:
Point[] points = Enumerable.Repeat<Point>(new Point(0, 1), 3).ToArray();

Categories

Resources