How to get all possible pairs from an 4x4 Array in C#? - c#

Let's say I have an 2x2 Array.
[1, 2]
[3, 4]
And I want to get all pairs possible.
[1, 2] [1, 3] [1, 4] [2, 3] [2, 4] [3, 4]
And I do not want reversed pairs like [2, 1].
Has anyone a good solution for this problem?

You will actually need three nested loops, or to convert your 2d list to 1d list and then to get your Permutations:
List<List<int>> My2DList = new List<List<int>>() { new List<int>(){ 1, 2 }, new List<int>(){ 3, 4 } }; // your initial 2d list
List<int> My1DList = My2DList.Cast<int>().ToList(); // convert to 1d list
List<List<int>> Permutations = new List<List<int>>(); // prepare a container
for (int i = 0; i < My1DList.Count; i++)
for(int j = i; j < My1DList.Count; j++)
Permutations.Add(new List<int>() { My1DList[i], My1DList[j] }); // add your permutations

Related

How to reshape matrix in MathNet?

I have 1x4 Matrix
[1, 2, 3, 4]
And I want to get 2x2 Matrix
[[1, 2], [3, 4]]. How can achieve this in Math.Net?
I found Resize method, which does not what I need.
Vector<double> vector = Vector<double>.Build.DenseOfArray(new double[] { 1, 2, 3, 4 });
var matrix1x4 = vector1x4.ToRowMatrix();
var matrix2x2 = matrix1x4.Resize(2, 2);
Resize method does not reshape, it copies part "common" part for those two matrices and discards the rest
[[1, 0], [2, 0]]

I can't filter elements in a collection with Enumerable.Where()

I found a strange behavior when I was using Linq.
The situation is that I want to make a collection which contains integers like [1, 2, 3, 4, 5], and I will remove the first element in the collection in each iteration of a for-loop.
But when I executed my code, I found that the count of elements in the collection didn't really reduce as what I expected. Instead, it kept remaining 4 elements after the first iteration.
Here is my source code:
var collection = Enumerable.Range(1, 5);
int currentNumber;
for (int i = 0; i < 10; i++)
{
currentNumber = collection.FirstOrDefault();
Console.WriteLine(currentNumber); //It prints endless 1 2 1 2 1 2...
collection = collection.Where(number => currentNumber != number);
}
I inspected the process with debugger and found the elements after executing collection.Where() were like:
Iteration 1: [2, 3, 4, 5]
Iteration 2: [1, 3, 4, 5]
Iteration 3: [2, 3, 4, 5]
Iteration 4: [1, 3, 4, 5]
...
This confused me because it seemed to always take [1, 2, 3, 4, 5] as the source to execute Where() in each iteration.
But when I moved the declaration of currentNumber into the for-loop, everything worked as what I expected.
var collection = Enumerable.Range(1, 5);
for (int i = 0; i < 10; i++)
{
int currentNumber; //Move the declaration to this line
currentNumber = collection.FirstOrDefault();
Console.WriteLine(currentNumber); //It correctly prints 1 2 3 4 5 0 0 0 0 0
collection = collection.Where(number => currentNumber != number);
}
Please tell me why it worked correctly after I moved the declaration into the for-loop.

Stretch or resample 1D array

This question might be something really simple and I might be missing something really basic, but how do you interpolate a 1D array in C#?
Lets say I have this array of n elements
int[] array1 = new int[] { 1, 3, 5, 7, 1 };
How to stretch or compress the array so that it has n values and interpolates the values, just like when you resize an image, thats it, not chopping or adding zeros or empty values to the array.
For example if I want to convert the array so it has n = 4 elements, get this
array1
>>[2, 4, 6, 4]
what I'm trying to do is the same as the resample function from matlab does
https://mathworks.com/help/signal/ref/resample.html
I suggest this solution for the case that the new array is shorter than the old one:
int[] array1 = new int[] { 1, 3, 5, 7, 9 };
int[] array2 = new int[4];
for (var i = 0; i < array2.Length; i++)
{
var doubleIndex1 = (double)i * array1.Length / array2.Length;
var index1 = (int)Math.Floor(doubleIndex1);
var rel = doubleIndex1 - index1;
array2[i] = (int)Math.Round((1.0 - rel) * array1[index1] + rel * array1[index1 + 1]);
}

How to save an entire array in a slot of a multidimensional array?

Is there any way to do the following?
int[,] multiArray = new int[5,5];
multiArray[0] = {0, 1, 3, 4, 5};
No, with multidimensional arrays, this is not possible. The array has a fixed size, and the compiler does not now what size you are allowed to assign to the array.
Also, how would the compiler know if you meant to do this:
multiArray[0, 0..4] = { 1, 2, 3, 4, 5 };
or this:
multiArray[0..4, 0] = { 1, 2, 3, 4, 5 };
However, you can use jagged arrays:
int[][] multiArray = new int[5][];
multiArray[0] = new[] { 1, 2, 3, 4, 5 };
I think what you want to do is save each element of the array into the same row but DIFFERENT columns of the multiArray.
multiArray[0][0] = 0;
multiArray[0][1] = 1;
multiArray[0][2] = 2;
multiArray[0][3] = 3;
multiArray[0][4] = 4;
multiArray[0][5] = 5;
I believe that is what you're trying to do. You can simplify this with a for loop as well.
Since .NET multidimensional arrays are stored in row-major order, you can use Buffer.BlockCopy for this operation (filling a full row at a time). Note the use of sizeof(int) since this method operates on bytes, not elements (unlike methods such as Array.Copy).
int[,] multiArray = new int[5, 5];
int rowIndex = 0;
int[] rowData = { 0, 1, 3, 4, 5 };
int destOffset = rowIndex * sizeof(int) * multiArray.GetLength(0);
Buffer.BlockCopy(rowData, 0, multiArray, destOffset, rowData.Length * sizeof(int));

Add distinct items from a list to another list

I would like to accomplish what the title states but I don't know how to go about doing so.
I have 2 lists:
public List<int[,]> LongList = new List<int[,]>();
public List<int[,]> UniqueList = new List<int[,]>();
To further explain, here's a scenario:
Puzzles:
public int[,] puzzle1 = new int [3,3] { {1,2,3},
{8,4,0},
{7,6,5} }; //[1,2,3;8,4,0;7,6,5]
public int[,] puzzle2 = new int [3,3] { {8,7,6},
{1,0,5},
{2,3,4} }; //[8,7,6;1,0,5;2,3,4]
public int[,] puzzle3 = new int [3,3] { {7,6,3},
{1,0,2},
{8,4,5} }; //[7,6,3;1,0,2;8,4,5]
LongList contains:
LongList.Add(puzzle1);
LongList.Add(puzzle1);
LongList.Add(puzzle1);
LongList.Add(puzzle1);
LongList.Add(puzzle2);
LongList.Add(puzzle2);
LongList.Add(puzzle3);
LongList.Add(puzzle3);
LongList.Add(puzzle3);
I would like Unique list to hold the UNIQUE values from LongList.
AS IF this happened:
UniqueList.Add(puzzle1);
UniqueList.Add(puzzle2);
UniqueList.Add(puzzle3);
As an equation: UniqueList = Distinct values from LongList
List is full of multiple reoccurring values & I would like to take only the unique ones and put them into UniqueList.
I'm trying to complete a puzzle and the LongList will contain multiple references of the same same puzzle and more. To make it simple for case of discussion:
LongList values: 1,1,1,1,2,2,3,4,4,4,4,5,5
I would like UniqueList to contain the puzzles: 1,2,3,4,5
OP's comments are vague.
Option 1: Unique numbers from across all multidimensional arrays
List<int> UniqueList = new List<int>();
UniqueList = LongList.Select(i => Flatten(i))
.SelectMany(i => i)
.Distinct()
.ToList();
This would turn { [[0, 1], [2, 3]], [[2, 2], [4, 5]] } to { 0, 1, 2, 3, 4, 5 }
See below for Flatten
Option 2: Unique multidimensional arrays by values
NB: Assumes size and number of dimensions of each multidimensional array match.
List<int[,]> UniqueList = new List<int[,]>();
foreach (var e in LongList)
{
IEnumerable<int> flat = Flatten(e);
if (!UniqueList.Any(i => Flatten(i).SequenceEqual(flat)))
{
UniqueList.Add(e);
}
}
This would turn { [[0, 1], [2, 3]], [[0, 1], [2, 3]], [[2, 2], [4, 5]] } to { [[0, 1], [2, 3]], [[2, 2], [4, 5]] }
See below for Flatten
Option 3: Unique references only
UniqueList = aList.Distinct().ToList();
NB: This was the original answer, for context on the comments.
Flatten Method
In all cases Flatten is taken from Guffa's SO Answer
public static IEnumerable<T> Flatten<T>(T[,] items) {
for (int i = 0; i < items.GetLength(0); i++)
for (int j = 0; j < items.GetLength(1); j++)
yield return items[i, j];
}
Other options
If OP would like something else (e.g. flattenting List<int[,]> to List<int[]> or support for different sized multidimensional arrays) they will have to comment back.
Based on OP's update, we just need to remove duplicate references. So we do not need to compare on a per-value basis. Distinct should do:
UniqueList = LongList.Distinct().ToList();

Categories

Resources