Square with Maximum Sum - c#

I am learning C#, and I am doing Multidimensional Arrays at the moment. I want to write a program that reads a matrix and then finds the biggest sum of 2x2 submatrix and prints it.
int[] dimensions = Console.ReadLine()
.Split(", ", StringSplitOptions.RemoveEmptyEntries)
.Select(int.Parse)
.ToArray();
int rows = dimensions[0];
int columns = dimensions[1];
int[,] matrix = new int[rows,columns];
for (int i = 0; i < rows; i++)
{
int[] numbers = Console.ReadLine()
.Split(", ", StringSplitOptions.RemoveEmptyEntries)
.Select(int.Parse)
.ToArray();
for (int j = 0; j < columns; j++)
{
matrix[i, j] = numbers[j];
}
}
int maxSum = int.MinValue;
int selectedRow = -1;
int selectedCol = -1;
for (int row = 0; row < matrix.GetLength(0) - 1; row++)
{
for (int col = 0; col < matrix.GetLength(1) - 1; col++)
{
int currentSum = matrix[row, col] + matrix[row, col + 1] + matrix[row + 1, col] + matrix[row + 1, col + 1];
if (currentSum > maxSum)
{
maxSum = currentSum;
selectedRow = row;
selectedCol = col;
}
}
}
Console.WriteLine($"{matrix[selectedRow, selectedCol]} {matrix[selectedRow, selectedCol + 1]}");
Console.WriteLine($"{matrix[selectedRow + 1, selectedCol]} {matrix[selectedRow + 1, selectedCol + 1]}");
Console.WriteLine(maxSum);
So, I read the matrix, but I am not sure how to start finding the submatrices and compare their sums. I would be very grateful if you could give me some hints.

You need to check values only current, under positions of your i and current, right positions of your j.
I mean it will check like this:
[7,1] [1,3] [3,3]
[1,3] [3,9] [9,8]
And so on.
After every compare, calculate sum of this 2x2 matrix and save it to dictionary.
For return, you just need to find the max value of key and get value of it key.
public class MatrixTest
{
public static IEnumerable<object[]> TestData =>
new List<object[]>
{
new object[]
{
new int[,]
{
{7, 1, 3, 3, 2, 1},
{1, 3, 9, 8, 5, 6},
{4, 6, 7, 9, 1, 0}
},
new int[,]
{
{9, 8},
{7, 9}
},
33
},
new object[]
{
new int[,]
{
{10, 11, 12, 13},
{14, 15, 16, 17}
},
new int[,]
{
{12, 13},
{16, 17}
},
58
}
};
[Theory]
[MemberData(nameof(TestData))]
public void Test(int[,] input, int[,] expectedArray, int expectedSum)
{
MatrixHandler m = new MatrixHandler();
var resp = m.GetMax2x2Matrix(input);
resp.Item1.Should().Be(expectedSum);
resp.Item2.Should().BeEquivalentTo(expectedArray);
}
}
public class MatrixHandler
{
public (int, int[,]) GetMax2x2Matrix(int[,] source)
{
var sumsPlusTempArrays = new Dictionary<int, int[,]>();
int[,] temp;
int sum = 0;
for (int i = 0, n0 = source.GetLength(0) - 1; i <= n0; i++)
{
for (int j = 0, n1 = source.GetLength(1) - 1; j <= n1; j++)
{
if (i + 1 <= n0 && j + 1 <= n1)
{
temp = new int[2,2];
temp[0, 0] = source[i, j];
temp[0, 1] = source[i, j + 1];
temp[1, 0] = source[i + 1, j];
temp[1, 1] = source[i + 1, j + 1];
sum = CalculateSum(temp);
sumsPlusTempArrays.TryAdd(sum, temp);
}
}
}
var key = sumsPlusTempArrays.Select(x => x.Key).Max();
var value = sumsPlusTempArrays[key];
return (key, value);
}
private int CalculateSum(int[,] source)
{
int sum = 0;
for (int i = 0, n0 = source.GetLength(0); i < n0; i++)
{
for (int j = 0, n1 = source.GetLength(1); j < n1; j++)
{
sum += source[i, j];
}
}
return sum;
}
}

Related

How to join indexes in an 2D array in C#

Is there a efficient way to join blocks in the arrays, as shown here:
original_array = [[1,2], [4,7], [8,10], [15,20], [21,25]]
new_array = [[1,2], [4,10], [15,25]]
Basically I want to join 2 indexes of an array if the distance between them is 1.
I tried something like this but it didin't work.
int[,] new_array = new int[500, 2];
int new_var = 0;
for (int k = 0; k < original_indexes; k++)
{
int dista = original_array [k + 1, 0] - original_array [k, 1];
if (dista < 10)
{
new_array[k, 0] = original_array[k, 0];
new_array[k, 1] = original_array[k + 1, 1];
new_var++;
}
else
{
new_array[k, 0] = original_array[k + new_var, 0];
new_array[k, 1] = original_array[k + new_var, 1];
}
}
Sorry, but I don't know how to be more specific and I don't even know how to search for this.
You can try something like this:
using System.Linq;
...
private static int[,] MyCombine(int[,] source) {
List<int[]> list = new List<int[]>();
int[] last = null;
for (int r = 0; r < source.GetLength(0); ++r)
if (last == null || last[1] + 1 < source[r, 0]) {
if (last != null)
list.Add(last);
last = new int[] { source[r, 0], source[r, 1] };
}
else
last[1] = source[r, 1];
if (last != null)
list.Add(last);
int[,] result = new int[list.Count, 2];
for (int r = 0; r < list.Count; ++r)
for (int c = 0; c < list[r].Length; ++c)
result[r, c] = list[r][c];
return result;
}
Demo:
int[,] original = new int[,] {
{ 1, 2 },
{ 4, 7 },
{ 8, 10 },
{15, 20 },
{21, 25 },
};
int[,] result = MyCombine(original);
string report = "[" + string.Join(", ", Enumerable
.Range(0, result.GetLength(0))
.Select(r => $"[{result[r, 0]}, {result[r, 1]}]")) + "]";
Console.Write(report);
Outcome:
[[1, 2], [4, 10], [15, 25]]

C# Changing values between 2 arrays

I'm trying to change values between two arrays, but im not getting get that right.
This is what I've done so far
I cant show the total of the first array and i cant make any swap at the second array
public static void exe4()
{
int[,] matriz1 = new int[,] { { -2, 3, 4, 11, -8 }, { -1, 0, -12, -6, 9 }, { 23, 4, 6, 8, -3 } };
int[,] matriz2 = new int[,] { { 2, 3, 8 }, { -2, -4, -5 }, { 0, 8, -14 }, { 3, 5, 6 }, { -9, -8, -1 } };
int troca1 = 0;
int troca2 = 0;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
troca1 = matriz1[i, j];
matriz1[1, 0] = matriz2[0, 2];
matriz1[1, 1] = matriz2[1, 2];
matriz1[1, 4] = matriz2[4, 1];
}
Console.WriteLine();
}
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
troca2 = matriz2[i, j];
matriz2[0, 2] = matriz1[1, 0];
matriz2[1, 2] = matriz1[1, 1];
matriz2[4, 2] = matriz1[1, 4];
}
Console.WriteLine();
}
Console.WriteLine("\nApĆ³s a troca dos valores:\n");
Console.WriteLine("Matriz1:\n");
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
Console.Write("{0}\t", matriz1[i, j]);
}
Console.WriteLine();
}
Console.WriteLine("\nMatriz2:\n");
Console.WriteLine();
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
Console.Write("{0}\t", matriz2[i, j]);
}
Console.WriteLine();
}
That's how it's supposed to be:
Analyzing your solution
It sounds like you're only interested in swapping very few and specific values in those matrices, so for-loops seem unnecessary as you already know the positions in the matrices you want to swap.
Apart from that I noticed that your for-loops only goes from 0 to 2 (for (int i = 0; i < 3; i++)) but your matrices have a length of 4 in one dimension, so the loops never reach the ends.
An alternative solution
If you just want to swap those specific values, you could do it like this:
int[,] matriz1 = new int[,]
{
{ -2, 3, 4, 11, -8 },
{ -1, 0, -12, -6, 9 },
{ 23, 4, 6, 8, -3 }
};
int[,] matriz2 = new int[,]
{
{ 2, 3, 8 },
{ -2, -4, -5 },
{ 0, 8, -14 },
{ 3, 5, 6 },
{ -9, -8, -1 }
};
int temporary;
// Swap A[1,0] with B[0,2]
temporary = matriz1[1,0];
matriz1[1,0] = matriz2[0,2];
matriz2[0,2] = temporary;
// Swap A[1,1] with B[1,2]
temporary = matriz1[1,0];
matriz1[1,1] = matriz2[1,2];
matriz2[1,2] = temporary;
// Swap A[1,4] with B[4,2]
temporary = matriz1[1,0];
matriz1[1,4] = matriz2[4,2];
matriz2[4,2] = temporary;
... or with a little helper function:
void Swap(int[,] matrixA, int row1, int col1, int[,] matrixB, int row2, int col2)
{
var temp = matrixA[row1, col1];
matrixA[row1, col1] = matrixB[row2, col2];
matrixB[row2, col2] = temp;
}
// ...
Swap(matriz1, 1, 0, matriz2, 0, 2);
Swap(matriz1, 1, 1, matriz2, 1, 2);
Swap(matriz1, 1, 4, matriz2, 4, 2);

Int Array left rotation from given index in c#

The Array example is {4, 5, 3, 6, 1}
The user will input the index number and the array will be rotated left from the given index number.
Example: If the user input(index number) is 2, the result is: 3 6 1 4 5.
Any better approach?
public static void Main(string[] args)
{
int[] a = { 4, 2, 8, 3, 1 };
int l = a.Length;
int[] b = new int[l];
int x = 0;
x = Convert.ToInt32(Console.ReadLine());
int i = 0;
for (int j = x; j < l; j++)
{
b[i] = a[j];
i++;
}
for (int k = 0; k < x; k++)
{
int v = a[k];
b[i] = a[k];
i++;
}
for (int m = 0; m < b.Length; m++)
{
Console.Write("{0}, ", b[m]);
}
Console.ReadKey();
}
I will use this method
public static int[] CircularShiftLeft(int[] arr, int shifts)
{
var dest = new int[arr.Length];
Array.Copy(arr, shifts, dest, 0, arr.Length - shifts);
Array.Copy(arr, 0, dest, arr.Length - shifts, shifts);
return dest;
}
Usage in your code, i didnt changed the naming
public static void Main(string[] args)
{
int[] a = { 4, 2, 8, 3, 1 };
int x = 0;
x = Convert.ToInt32(Console.ReadLine());
var b = ShiftLeft(a, x);
for (int m = 0; m < b.Length; m++)
{
Console.Write("{0}, ", b[m]);
}
Console.ReadKey();
}

Write a program, which finds the maximal sequence of consecutive equal elements in an array. c#

The prompt is to find the maximal sequence of consecutive equal elements in an array. I don't know what I'm doing wrong but I can't get the right result to show up. :/ Maybe the problem is in the way I iterate with the second loop?
class Class2
{
static void Main(string[] args)
{
int pos=0, bestpos=0, bestlen = 0;
int len = 1;
int[] vargu = { 2, 2, 3, 4, 5, 5, 5, 6, 9, 9, 9, 9 };
for(int i = 0; i < vargu.Length-1; i++)
{
if (vargu[i] == vargu[i++])
{
len++;
if (len > bestlen)
{
bestlen = len;
bestpos = pos;
}
}
else
{
len = 1;
pos = i++;
}
}
for(int k = bestpos; k <= bestlen; k++)
{
Console.Write("{0}", vargu[k]);
}
Console.ReadLine();
}
}
3 problems.
if (vargu[i] == vargu[i++])
dont use ++ with i, it means increment the actual value of i, and you are looping i. Use "i+1" instead.
pos = i++;
same problem here. the array wont get traversed by each index due to this line.
for(int k = bestpos; k <= bestlen; k++)
k < bestlen + bestpos, because bestpos = 8, and bestlen = 4, so loop run condition fails.
int pos = 0, bestpos = 0, bestlen = 0;
int len = 1;
int[] vargu = { 2, 2, 3, 4, 5, 5, 5, 6, 9, 9, 9, 9 };
for (int i = 0; i < vargu.Length - 1; i++)
{
if (vargu[i] == vargu[i+1])
{
len++;
if (len > bestlen)
{
bestlen = len;
bestpos = pos;
}
}
else
{
len = 1;
pos = i+1;
}
}
for (int k = bestpos; k < bestlen + bestpos; k++)
{
Console.Write("{0} ", vargu[k]);
}
Console.ReadLine();
You're using i++ in the loop body when you mean i + 1.
Note that i++ has the side effect of increasing i by 1. Leave the incrementation of i solely in for (int i = 0; i < vargu.Length - 1; i++).
Your problem is 2-fold.
First i++ increments the variable i which shifts the index forward. Something that you don't want. You need to use i+1 if you want to access the consecutive element
Second, when you print in the second loop your array the end-index is wrong. You start at bestpos but you want to end at bestpos + bestlen! Since you measure the length of the sequence and don't save the final index.
This should give you the expected result:
int pos = 0, bestpos = 0, bestlen = 0;
int len = 1;
int[] vargu = { 2, 2, 3, 4, 5, 5, 5, 6, 9, 9, 9, 9 };
for (int i = 0; i < vargu.Length - 1; i++)
{
if (vargu[i] == vargu[i+1])
{
len++;
if (len > bestlen)
{
bestlen = len;
bestpos = pos;
}
}
else
{
len = 1;
pos = i+1;
}
}
for (int k = bestpos; k <= bestpos+bestlen; k++)
{
Console.Write("{0}", vargu[k]);
}
Console.ReadLine();
I would suggest making a structure to hold results :
struct ResultItem
{
public int start;
public int end;
public int value;
}
And then just iterate and compare when signs are changing :
int[] vargu = { 2, 2, 3, 4, 5, 5, 5, 6, 9, 9, 9, 9 };
List<ResultItem> _result = new List<ResultItem>();
ResultItem current = new ResultItem{ value = vargu[0], start = 0, end = 1 };
for (int i = 1; i < vargu.Length; i++)
{
if (vargu [i] != current.value)
{
current.end = i;
_result.Add( current );
current = new ResultItem { value = vargu[i], start = i, end = i };
}
Console.WriteLine(current.value + " " + current.start + " " + current.end);
}
current.end = vargu.Length;
_result.Add(current);
Then you can dump the result as such :
foreach(ResultItem value in _result)
{
Console.WriteLine("integer {0} was placed {1} times in a row", value.value, value.end - value.start);
}
which should result in something like :
integer 2 was placed 2 times in a row
integer 3 was placed 1 times in a row
integer 4 was placed 1 times in a row
integer 5 was placed 3 times in a row
integer 6 was placed 1 times in a row
integer 9 was placed 4 times in a row
Then to find the longest sequence you can use Linq : _result.Max(r => r.end - r.start);
I've been working on the same problem myself. I tried using Mong Zhu's code above and it almost worked so I tweaked two things and it seemed to work.
Change (vargu[i] == vargu[i+1]) to (vargu[i] + 1 == vargu[i+1])
And pos = i + 1; to pos = i; and it seemed to work. My first post. I hope it's okay.
int[] arr = { 1, 2, 3, 5, 4, 3, 3, 4, 5, 6, 5, 4, 5, 6, 7, 8, 7, 5, 6, 9, 8, 7, 0 };
int pos = 0, bestPos = 0, bestLen = 0;
int len = 1;
for(int i = 0; i < arr.Length -1; i++)
{
if(arr[i] + 1 == arr[i + 1])
{
len++;
if(len > bestLen)
{
bestLen = len;
bestPos = pos;
}
}
else
{
len = 1;
pos = i ;
}
}
for( int k = bestPos; k <= bestLen + bestPos; k++)
{
Console.Write("{0}", arr[k]);
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int finalbestsum = 0;
int bestsum = 0;
int bestcount = 0;
int count = 0;
int consval = 0;
int? consval1 = null;
string bestvalue = null;
string bestvalue1 = null;
Console.WriteLine("Enter number of columns for the array");
int col = int.Parse(Console.ReadLine());
Console.WriteLine("Enter number of rows for the array");
int row = int.Parse(Console.ReadLine());
int[,] twodimen = new int[row, col];
for (int index = 0; index < twodimen.GetLength(0); index++ )
{
for (int index1 = 0; index1 < twodimen.GetLength(1); index1++)
{
Console.WriteLine("Enter twodimen {0} {1} value",index, index1);
twodimen[index, index1] = int.Parse(Console.ReadLine());
}
}
for (int index = 0; index < twodimen.GetLength(0); index++ )
{
for (int index1 = 0; index1 < twodimen.GetLength(1)-1; index1++)
{
consval = twodimen[index,index1];
if (consval == twodimen[index, index1 + 1])
{
consval1 = twodimen[index,index1+1];
//Console.Write("{0}" + " ", consval);
bestvalue = bestvalue + Convert.ToString(" " + consval + " ");
count++;
bestsum = bestsum + consval;
}
else if (consval1 != null)
{
//Console.Write(consval1);
count++;
bestvalue = bestvalue + Convert.ToString(" " + consval1 + " ");
bestsum = bestsum + Convert.ToInt16(consval1);
Console.WriteLine();
if (bestcount < count)
{
bestvalue1 = bestvalue;
bestcount = count;
finalbestsum = bestsum;
}
else if (bestcount == count && finalbestsum < bestsum)
{
bestvalue1 = bestvalue;
bestcount = count;
finalbestsum = bestsum;
}
bestvalue = null;
count = 0;
bestsum = 0;
consval1 = null;
}
if (consval == twodimen[index, index1 + 1] && index1 == (twodimen.GetLength(1)-2))
{
bestvalue = bestvalue + Convert.ToString(" " + consval1 + " ");
//Console.Write(consval1);
bestsum = bestsum + Convert.ToInt16(consval1);
count++;
consval1 = null;
if (bestcount < count)
{
bestcount = count;
bestvalue1 = bestvalue;
finalbestsum = bestsum;
}
else if (bestcount == count && finalbestsum < bestsum)
{
bestvalue1 = bestvalue;
bestcount = count;
finalbestsum = bestsum;
}
}
}
bestvalue = null;
count = 0;
bestsum = 0;
Console.WriteLine();
//Console.WriteLine(bestcount);
}
Console.WriteLine(bestvalue1);
Console.ReadLine();
}
}
}

Array Out of Bound Exception in C#

I am just sorting an array and my code seem to be fine but I am unable to resolve the Array Out of Bound Exception. Any ideas.
static void Main(string[] args)
{
int temp = 0; // For temporary holding array values for swapping
int [] num = new int[] {1, 4, 7, 6, 9, 3, 0, 8, 5, 2 };
for (int i = 0; i <= 9; i++) //Outer loop
{
for (int j = 0; j < 9; j++) // Inner loop
{
if (num[j] > num[j + 1])
{
temp = num[j + 1];
num[j + 1] = num[j];
num[j] = temp;
}
}
}
//Displaying the array
for (int i = 0; i < 9; i++)
Console.WriteLine(num[i]);
Console.ReadKey();
}
Modifying the second loop to "j < loopSize - i" (instead of j < loopSize) will double the efficiency of your bubble sort. :)
int[] num = new int[] { 1, 4, 7, 6, 9, 3, 0, 8, 5, 2 };
//int comparisons = 0;
int loopSize = num.Length - 1;
for (int i = 0; i <= loopSize; i++) //Outer loop
{
for (int j = 0; j < loopSize - i; j++) // Inner loop
{
//comparisons++;
if (num[j] > num[j + 1])
{
temp = num[j + 1];
num[j + 1] = num[j];
num[j] = temp;
}
}
}
//Displaying the array
for (int i = 0; i < num.Length; i++)
Console.WriteLine(num[i]);
//Console.WriteLine("comp: {0}", comparisons);
//Console.ReadKey();
}

Categories