Fill 1D array from matrix - c#

I have a matrix, my mission is to fill 1D array from my matrix.
Example:
1 2 3
1 2 3
1 2 3
I need to sum the columns and fill the sum of every column in a 1D array
Here is my code (that doesn't work), (int[,] mat) is the matrix that the function gets.
public static int sumcolumn(int[,] mat)
{
int sum = 0;
int[] sumcol = new int[mat.GetLength(0)];
for (int y = 0; y < mat.GetLength(0); y++)
{
for (int i = 0; i < mat.GetLength(0); i++)
{
for (int j = 0; j < mat.GetLength(1); j++)
{
sum = sum + mat[j, i];
}
sumcol[i] = sum;
return sum;
sum = 0;
}
return sum;
}
return sumcol;
}
How should I do this mission?
Thanks in advance.

You need only 2 for loops. For each column run through all rows and sum up the content. Write the sum at the proper col index. Then after each column reset the sum. You also need to return the array with the sums. So I changed the return value:
Also it helps if you call the index variables with meaningful names.
public static int[] sumcolumn(int[,] mat)
{
int[] sumcol = new int[mat.GetLength(1)];
for (int col = 0; col < mat.GetLength(1); col++)
{
for (int row = 0; row < mat.GetLength(0); row++)
{
// since sumcol is initially filled with zeros you can just
// sum up the values from mat onto the zeros in each cell
sumcol[col] += mat[row, col];
}
}
return sumcol;
}
In the main you can test it like this:
void Main()
{
int[,] array = {
{ 1, 2, 3 },
{ 1, 2, 3 },
{ 1, 2, 3 },};
// this is just for test display
Console.WriteLine(String.Join(" ", sumcolumn(array)));
// normally you would call it like this and catch the return value in a new array
int[] result = sumcolumn(array);
}

So you need to evaluate a 2D matrix to get the column wise sum to a 1D array. So first thing you have to do is change the return type of the method to int[] instead for int.
Let me quote Few things that you have to notice before moving to a fix:
If you execute a return during iteration of the loop rest of iterations will not be executed.
A function can return only one value in a single call.
Let i and j be two positive unequal integers then a[i,j] and a[j,i] will points to two different elements in the matrix a.
As a whole you have to modify the method signature like the following:
public static int[] sumcolumn(int[,] mat)
{
int sum = 0;
int[] sumcol = new int[mat.GetLength(1)];
for (int i= 0; i< mat.GetLength(1); i++)
{
sum = 0; // reset sum for next colomn
for (int j= 0; j< mat.GetLength(0); j++)
{
sum += mat[i, j];
}
// iteration of column completed
sumcol[i] = sum;
}
return sumcol;
}

Linq approach
int[,] array = new int[3, 3] { { 1, 2, 3 },
{ 1, 2, 3 },
{ 1, 2, 3 } };
int[] result = Enumerable.Range(0, array.GetUpperBound(1) + 1)
.Select(y => Enumerable.Range(0, array.GetUpperBound(0) + 1)
.Select(x => array[x, y]).Sum()).ToArray(); // [3,6,9]

public static int[] sumColumn(int[,] mat)
{
//int sum = 0;
int colCount = mat.GetLength(0);
int[] sumCol = new int[colCount];
for (int y = 0; y < colCount; y++)
{
int rowCount = mat.GetLength(1);
sumCol[y] = 0;
for (int x = 0; x < rowCount; x++)
{
sumCol[y] += mat[y, x];
}
//sum += sumCol[y];
}
//return sum;
return sumCol;
}

Related

How to find 3x3 square matrix with maximum sum in bigger rectangular matrix in C#?

I have matrix with size N x M and I want to find smaller matrix inside which has maximum sum and is of size 3 x 3. I can manually sum all the elements but wthis is imposible in bigger matrices, can you point me a better approach.
Look for Kadane 2D algorithm.
I think it is one of the best solution for this problem
If I understand the problem ¯\_(ツ)_/¯
Given
public static int FindStuff(int[,] array)
{
var largest = 0;
for (var i = 0; i < array.GetLength(0) - 2; i++)
for (var j = 0; j < array.GetLength(1) - 2; j++)
{
var sum = 0;
for (var x = i; x < i+3; x++)
for (var y = j; y < j+3; y++)
sum += array[x, y];
if (sum > largest)
largest = sum;
}
return largest;
}
Usage
var array = new[,]
{
{1, 1, 1, 1},
{1, 2, 3, 4},
{1, 1, 1, 1},
{5, 1, 1, 1},
};
Console.WriteLine(FindStuff(array));
Result
16
In pure C# you must calculate all inner matricies, you can speed up algorithms with paraller task, you can also use CUDA, and a naive solution with checking inner matrices should looks like this:
public void TestMethod(int[][] matrix)
{
int largestSum = 0;
int columnLargestIdx = 0;
int rowLargestIdx = 0;
for (int column = 0; column < matrix.Length; column++)
for (int row = 0; row < matrix[column].Length; row++)
{
if (IsBuild3x3Possible(matrix, column, row))
{
int sum = CalculateSum(matrix, column, row);
if (sum > largestSum)
{
largestSum = sum;
columnLargestIdx = column;
rowLargestIdx = row;
}
}
}
}
public bool IsBuild3x3Possible(int[][] matrix, int column, int row)
{
var columns = (matrix.Length - column) >= 3;
var rows = (matrix[column].Length - row) >= 3;
return columns && rows;
}
public int CalculateSum(int[][] matrix, int column, int row)
{
int sum = 0;
for (int i = column; i < column + 3; i++)
for (int j = row; j < row + 3; j++)
sum += matrix[i][j];
return sum;
}

Check for line on bingo program with arrays

I have this problem of bingo, where I have to check for bingo, line, or nothing, for a given input, where I get the 3 X 3 bingo card, and next 15 numbers extracted. I've wrote some code and I pass the tests for bingo and nothing, but not for line and I don't know why because I think my logic is good.
Here is the input:
1 2 3
4 5 6
7 8 9
1
2
3
4
5
6
7
8
10
11
12
13
14
15
16
I should have the result "line" but I get "nothing" instead. I think that my problem is on CheckLine method and I think this happens because somehow I don't pass correct parameters or maybe I have/or don't have to use ref keyword on some parameters. Can someone tell me what's wrong?
Here is my code:
static void Main()
{
const int numberOfRows = 3;
const int numberOfColumnns = 3;
const int numbersExtracted = 15;
int[,] bingoCard = ReadBingoCard(numberOfRows, numberOfColumnns);
int[] numbers = ReadNumbersExtracted(numbersExtracted);
PrintResult(bingoCard, numbers);
}
static int[,] ReadBingoCard(int rowsNumber, int columnNumber)
{
int[,] card = new int[rowsNumber, columnNumber];
for (int i = 0; i < rowsNumber; i++)
{
string[] array = Console.ReadLine().Split(' ');
for (int j = 0; j < columnNumber; j++)
{
card[i, j] = Convert.ToInt32(array[j]);
}
}
return card;
}
static int[] ReadNumbersExtracted(int numbersExtracted)
{
int[] numbers = new int[numbersExtracted];
for (int i = 0; i < numbersExtracted; i++)
{
numbers[i] = Convert.ToInt32(Console.ReadLine());
}
return numbers;
}
static void CheckLine(int[,] bingoCard, int nr, int nr2, int[] numbersExtracted,
ref int counter, int nr3, ref bool isTrue)
{
const int rowEnd = 2;
bool isLine = counter == nr3 && nr2 == rowEnd;
for (int k = 0; k < numbersExtracted.Length; k++)
{
if (bingoCard[nr, nr2] == numbersExtracted[k])
{
counter++;
if (isLine)
{
isTrue = true;
break;
}
}
}
}
static void CheckBingo(int[,] bingoCard, int nr, int nr2, int[] numbersExtracted,
ref int counter, int nr3, ref bool isTrue)
{
for (int k = 0; k < numbersExtracted.Length; k++)
{
if (bingoCard[nr, nr2] == numbersExtracted[k])
{
counter++;
if (counter == nr3)
{
isTrue = true;
}
}
}
}
static bool CheckForLine(int[,] bingoCard, int[] numbersExtracted)
{
const int length = 3;
int count = 0;
bool isLine = false;
for (int i = 0; i < bingoCard.GetLength(0); i++)
{
for (int j = 0; j < bingoCard.GetLength(0); j++)
{
CheckLine(bingoCard, i, j, numbersExtracted, ref count, length, ref isLine);
}
}
return isLine;
}
static bool CheckForBingo(int[,] bingoCard, int[] numbersExtracted)
{
const int length = 9;
int count = 0;
bool isBingo = false;
for (int i = 0; i < bingoCard.GetLength(0); i++)
{
for (int j = 0; j < bingoCard.GetLength(1); j++)
{
CheckBingo(bingoCard, i, j, numbersExtracted, ref count, length, ref isBingo);
}
}
return isBingo;
}
static void PrintResult(int[,] bingoCard, int[] numbersExtracted)
{
if (CheckForBingo(bingoCard, numbersExtracted))
{
Console.WriteLine("bingo");
}
else if (CheckForLine(bingoCard, numbersExtracted))
{
Console.WriteLine("linie");
}
else
{
Console.WriteLine("nimic");
}
}
I think part of the problem here is that you're passing program state around to the methods using ref arguments. This can lead to problems because the state is now shared between methods and can easily get out of sync if we're not careful.
Instead we should define methods that take in some information, do some calculation, and return a result. It makes tracking down problems much easier this way.
For example, to determine if there is a "Bingo", we need to check if all items in the bingoCard array are also in the numbers array. This can be done fairly easily with a nested loop, where we:
Loop over each row in the bingoCard array
For each row we look at each column value.
Then we loop over the numbers array to see if there's a match for the value.
If there's a match, then we can increment a counter.
If, when we're done, the counter equals the number of items in the bingoCard array, then we return true
Otherwise return false
For example:
static bool CheckForBingo(int[,] bingoCard, int[] numbers)
{
int numMatchesFound = 0;
for (int row = 0; row < bingoCard.GetLength(0); row++)
{
for (int col = 0; col < bingoCard.GetLength(1); col++)
{
for (int numIndex = 0; numIndex < numbers.Length; numIndex++)
{
if (bingoCard[row, col] == numbers[numIndex])
{
// Match found! Increment our counter and break from this loop
numMatchesFound++;
break;
}
}
}
}
// If the number of matches equals the number of items in the card, return 'true'
return numMatchesFound == bingoCard.Length;
}
Similarly, to check for a "line" we examine each row, and for each row we look at the column value. Then we loop through the numbers array to see if there's a match. If there is, then we increment a counter. If, at the end of the columns loop, our counter matches the total number of columns, then we have a "line" and return true. Otherwise, if we get to the end of the loops, then we return false:
static bool CheckForLine(int[,] bingoCard, int[] numbers)
{
for (int row = 0; row < bingoCard.GetLength(0); row++)
{
// For a 'line', we only need to match all columns in a row,
// so create a counter to track that here
int colMatchesInRow = 0;
for (int col = 0; col < bingoCard.GetLength(1); col++)
{
for (int numIndex = 0; numIndex < numbers.Length; numIndex++)
{
if (bingoCard[row, col] == numbers[numIndex])
{
// Match found! Increment our counter and break from this loop
colMatchesInRow++;
break;
}
}
}
// If our counter equals the number of columns, return 'true'
if (colMatchesInRow == bingoCard.GetLength(1)) return true;
}
// If we get this far, we never found a 'line', so return 'false'
return false;
}
Hopefully this helps.

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;
}

Digit difference sort

So I am trying to solve this task "Digit Difference Sort" on Codefights
Given an array of integers, sort its elements by the difference of their largest and smallest digits.
In the case of a tie, that with the larger index in the array should come first.
Example
For a = [152, 23, 7, 887, 243], the output should be digitDifferenceSort(a) = [7, 887, 23, 243, 152].
Here are the differences of all the numbers:
152: difference = 5 - 1 = 4;
23: difference = 3 - 2 = 1;
7: difference = 7 - 7 = 0;
887: difference = 8 - 7 = 1;
243: difference = 4 - 2 = 2.
23 and 887 have the same difference, but 887 goes after 23 in a, so in the sorted array it comes first.
I have an issue with two numbers having the same difference. Here's what I wrote so far:
int[] digitDifferenceSort(int[] a) {
return a.OrderBy(x => difference(x)).ToArray();
}
int difference(int x)
{
int min = 9, max = 0;
do
{
int tmp = x % 10;
min = Math.Min(min, tmp);
max = Math.Max(max, tmp);
} while ((x /= 10) > 0);
return max - min;
}
Didn't do much (for example the output is still [7, 23, 887, 243, 152] rather than [7, 887, 23, 243, 152])
How do I make element with larger index come first in result? What should I use instead of OrderBy?
I don't consider your difference method, i assume it works fine.
To your question: you have to keep revered order of the array (that the items with the same difference arrive will be sorted reverse). To do it, you could just reverse you input array: all items with not identical difference will be ordered correctly, and with the same differece will be ordered reversed:
int[] digitDifferenceSort(int[] a)
{
return a.Reverse().OrderBy(x => difference(x)).ToArray();
}
Following is my code for the above question digit difference sort. I am also getting output when running in Eclipse but when I paste the code on code signal it gives me a null pointer exception.
package NormalPrograms;
import java.util.ArrayList;
import java.util.Collections;
public class DigitDifferenceSort {
// For index wise sorting in descending order
public static int[] sortingnumberindexwise(int[] a, ArrayList<Integer> index) {
int k = 0;
int[] res = new int[index.size()];
int[] finalres = new int[index.size()];
for (int i = a.length - 1; i >= 0; i--) {
for (int j = 0; j < index.size(); j++) {
if (a[i] == (int) index.get(j)) {
res[k] = i;
index.remove(j);
k++;
break;
}
}
}
int g = 0;
k = 0;
for (int i = 0; i < res.length; i++) {
finalres[g] = a[res[k]];
g++;
k++;
}
return finalres;
}
public static int[] finddigitDifferenceandSort(int[] p) {
int[] finres = new int[p.length];
for (int i = 0; i < finres.length; i++) {
finres[i] = p[i];
}
// This finres array act as an temp array and reused to make final result array
int digit = 0;
ArrayList<Integer> A = new ArrayList<Integer>();
ArrayList<ArrayList<Integer>> B = new ArrayList<ArrayList<Integer>>();
for (int i = 0; i < 10; i++) {
B.add(new ArrayList<Integer>());
}
for (int i = 0; i < p.length; i++) {
int temp = 0;
temp = p[i];
while (p[i] > 0) {
digit = p[i] % 10;
p[i] /= 10;
A.add(digit);
}
int b = Collections.max(A);
int c = Collections.min(A);
int diff = b - c;
B.get(diff).add(temp);
A.clear();
}
for (int i = 0; i < B.size(); i++) {
if (B.get(i).size() > 1) {
ArrayList<Integer> C = new ArrayList<Integer>();
for (int k = 0; k < B.get(i).size(); k++) {
C.add(B.get(i).get(k));
}
B.get(i).clear();
for (int j : sortingnumberindexwise(finres, C)) {
B.get(i).add(j);
}
} else {
continue;
}
}
int k = 0;
for (int i = 0; i < B.size(); i++) {
for (int j = 0; j < B.get(i).size(); j++) {
if (B.get(i).size() == 0)
continue;
else {
finres[k] = B.get(i).get(j);
k++;
}
}
}
return finres;
}
public static void main(String[] args) {
int[] a = { 12, 21, 1, 1, 1, 2, 2, 3 };
for (int i : finddigitDifferenceandSort(a)) {
System.out.print(i + " ");
}
}
}

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...

Categories

Resources