There is a square matrix nxn. The task is to determine the maximum among the sums of elements of diagonals which are parallel to the main diagonal of the matrix. I have managed already to loop throught matrix in proper way and output these elements. So how can I find the sum of every diagonal separately? Or at least how to extract every diagonal separately while looping throught matrix? Thanks in advance!
//Reverse rows of matrix
static int[,] Reverse2DimArray(int[,] theArray)
{
for (int rowIndex = 0; rowIndex <= (theArray.GetUpperBound(0)); rowIndex++)
{
for (int colIndex = 0; colIndex <= (theArray.GetUpperBound(1) / 2); colIndex++)
{
int tempHolder = theArray[rowIndex, colIndex];
theArray[rowIndex, colIndex] = theArray[rowIndex, theArray.GetUpperBound(1) - colIndex];
theArray[rowIndex, theArray.GetUpperBound(1) - colIndex] = tempHolder;
}
}
return theArray;
}
static void Main(string[] args)
{
int[,] reversed = Reverse2DimArray(matrix);
MatrixOutput(reversed, size);
for (int y = 0; y < 2 * size; y++)
{
for (int x = 0; x < size; x++)
{
if (0 <= y - x && y - x < size)
Console.WriteLine(reversed[y - x, x]);
}
}
}
What I have now:
3 6 2 9 5 1 8 4 7
What I need is:
1 2 3
4 5 6
7 8 9
Diadonals: 3; 6,2; 9,5,1; 8,4; 7
Sums: 3; 8; 15; 19
Output: 19
Related
So, I am trying to wrap my head around understanding how you can use a variable to denote how many times a loop is nested.
Here is an example I write up to simulate the output of dimensions = 4:
static void Main(string[] args)
{
int dimensions = 4; // e.g. for (1, 2, 3, 4), dimensions = 4
Console.WriteLine($"{addNumbers(dimensions)}");
Console.ReadKey();
}
static long addNumbers(int dimensions)
{
long number = 0;
// hard coded to be dimensions = 4
for (int h = 0; h <= dimensions; h++)
for (int i = 0; i <= dimensions; i++)
for (int j = 0; j <= dimensions; j++)
for (int k = 0; k <= dimensions; k++)
number += h + i + j + k; // just some random math
return number;
}
This will present the expected output of:
5000
So to readdress the problem, how can I code to allow this for n dimensions? Thanks for your help!
For arbitrary n dimensions you can loop with a help of array int[] address which represents n dimensions:
static long addNumbers(int dimensions) {
int[] address = new int[dimensions];
// size of each dimension; not necessary equals to dimensions
// + 1 : in your code, int the loops you have i <= dimensions, j <= dimensions etc.
int size = dimensions + 1;
long number = 0;
do {
//TODO: some math here
// i == address[0]; j = address[1]; ... etc.
number += address.Sum();
// next address: adding 1 to array
for (int i = 0; i < address.Length; ++i) {
if (address[i] >= size - 1)
address[i] = 0;
else {
address[i] += 1;
break;
}
}
}
while (!address.All(index => index == 0)); // all 0 address - items're exhausted
return number;
}
Finally, let's add some Linq to look at the results:
int upTo = 5;
string report = string.Join(Environment.NewLine, Enumerable
.Range(1, upTo)
.Select(i => $"{i} -> {addNumbers(i),6}"));
Console.Write(report);
Outcome:
1 -> 1
2 -> 18
3 -> 288
4 -> 5000 // <- We've got it: 5000 for 4 dimensions
5 -> 97200
I want to fill my array with struct in a way that it will look like this
I have this code so far :
`for (int i = 1; i <= n; i++)
{
for (int j = 0; j <=(n - i); j++)
//i should fill m[,] here
for (int j = 1; j <= i; j++)
//i should fill m[,] here
for (int k = 1; k < i; k++)
//i should fill m[,] here
}
for (int i = n - 1; i >= 1; i--)
{
for (int j = 0; j < (n - i); j++)
//i should fill m[,] here
for (int j = 1; j <= i; j++)
//i should fill m[,] here
for (int k = 1; k < i; k++)
//i should fill m[,] here
}`
but I 'm a little bit confused with the index .
how can I adopt this code?
As it's unclear wether the array always has the size 5 I'll assume it has the size n with n being odd and n > 0 (The size is the x and the y size, as I assume that your matrix is quadratic). Then there are several ways to reach the goal your trying to reach, I'll try to present you one I thought of.
First of all we have to think about the array - as it's the easiest way, I'll assume it consists of boolean values (even though you said "I want to fill my array with struct", but as I'm not quite sure what you wanted to say with that and wether you really meant a struct, I'll let this up to you, as this shouldn't be the most difficult part):
var matrix = new bool[n,n];
Then we have to evalueate which fields have to be filled. Therefore we must realize a few things:
The filled fields are always central in their line
The first and last line always have one filled item
The following line always has two more/less filled items, so that the offset is one more than in the previous line
The center line has most items and is the turning point in the amount of filled items
As a first step in developing the algorithm, I'd write a function to fill lines of the array with specific amounts of fields:
private static void FillLine(int line, int count, bool[,] matrix)
{
//Firstly we have to evaluate the offset:
var offset = (matrix.GetLength(0) - count) / 2;
//Then we have to fill the line
for (var x = offset; x < offset + count; x++)
matrix[x, line] = true;
}
Now we simply have to fill the lines for the whole array:
public static void FillDiamond(bool[,] matrix)
{
var count = 1;
for (var line = 0; line < matrix.GetLength(1) / 2; line++)
{
FillLine(line, count, matrix);
count += 2;
}
FillLine(matrix.GetLength(1) / 2, count, matrix);
count = 1;
for (var line = matrix.GetLength(1) - 1; line > matrix.GetLength(1) / 2; line--)
{
FillLine(line, count, matrix);
count += 2;
}
}
Now in a console application you could use this like that:
using System;
namespace SO_c
{
internal static class Program
{
private static void Main()
{
while (true)
{
var n = int.Parse(Console.ReadLine());
if (n < 1 || n % 2 == 0)
continue;
var matrix = new bool[n, n];
FillDiamond(matrix);
for (var y = 0; y < matrix.GetLength(1); y++)
{
for (var x = 0; x < matrix.GetLength(0); x++)
Console.Write(matrix[x, y] ? "█" : " ");
Console.WriteLine();
}
}
}
private static void FillLine(int line, int count, bool[,] matrix)
{
//Firstly we have to evaluate the offset:
var offset = (matrix.GetLength(0) - count) / 2;
//Then we have to fill the line
for (var x = offset; x < offset + count; x++)
matrix[x, line] = true;
}
public static void FillDiamond(bool[,] matrix)
{
var count = 1;
for (var line = 0; line < matrix.GetLength(1) / 2; line++)
{
FillLine(line, count, matrix);
count += 2;
}
FillLine(matrix.GetLength(1) / 2, count, matrix);
count = 1;
for (var line = matrix.GetLength(1) - 1; line > matrix.GetLength(1) / 2; line--)
{
FillLine(line, count, matrix);
count += 2;
}
}
}
}
This can result in output like that:
That's it! Now you should get your diamond for every matrix that fits the rules :)
One way to do it is to calculate the center of the grid and fill in each row, from the center column. In each successive row, we increment the number of blocks we fill in on each side of the center column until we get to the center row, and then we decrement the number of blocks we fill in until we get to the end.
To determine how many blocks to put on each side of the center column for any given row, we can use the row index for the calculation.
Working our way from the top down to the center, the row index represents the number of blocks to add. So, for row index 0, we add 0 blocks on either side of the center column, row index 1 we add 1 block on each side, until we get to the center.
After we get to the center, we want to decrement the number of blocks each time, which can be done by subtracting the row index from the total number of rows.
The code says it better, I think:
private static void Main()
{
while (true)
{
// Get grid size from user and keep it between 1 and the window width
var gridSize = GetIntFromUser("Enter the size of the grid: ");
gridSize = Math.Min(Console.WindowWidth - 1, Math.Max(1, gridSize));
var grid = new bool[gridSize, gridSize];
var center = (gridSize - 1) / 2;
// Populate our grid with a diamond pattern
for (int rowIndex = 0; rowIndex < grid.GetLength(0); rowIndex++)
{
// Determine number of blocks to fill based on current row
var fillAmount = (rowIndex <= center)
? rowIndex : grid.GetUpperBound(0) - rowIndex;
for (int colIndex = 0; colIndex <= fillAmount; colIndex++)
{
grid[rowIndex, center - colIndex] = true;
grid[rowIndex, center + colIndex] = true;
}
}
// Display the final grid to the console
for (int row = 0; row < grid.GetLength(0); row++)
{
for (int col = 0; col < grid.GetLength(1); col++)
{
Console.Write(grid[row, col] ? "█" : " ");
}
Console.WriteLine();
}
}
}
Oh, and this is the helper function I used to get an integer from the user. It's pretty helpful to keep around because you don't have to do any validation in your main code:
private static int GetIntFromUser(string prompt)
{
int value;
// Write the prompt text and get input from user
Console.Write(prompt);
string input = Console.ReadLine();
// If input can't be converted to a double, keep trying
while (!int.TryParse(input, out value))
{
Console.Write($"'{input}' is not a valid number. Please try again: ");
input = Console.ReadLine();
}
// Input was successfully converted!
return value;
}
OUTPUT
This question already has answers here:
How to multiply a matrix in C#?
(2 answers)
Closed 6 years ago.
I want to know how to multiply 2D arrays (matrices) and show them as a matrix.
The current output is
1 1 1
1 1 1
1 1 1
which is not the correct result.
The code is below:
static void Main(string[] args)
{
int[,] metrix1 = new int[3, 3] { { 2, 0, 2 }, { 0, 1, 2 }, { 1, 2, 1 } };
int[,] metrix2 = new int[3, 3] { { 1, 1, 1 }, { 0, 1, 0 }, { 0, 0, 1 } };
int[,] result = new int[3, 3];
int m1 =0;
int m2 =0;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
m1 = metrix1[i, j];
}
}
// metrix 2
for (int y = 0; y < 3; y++)
{
for (int z = 0; z < 3; z++)
{
m2 = metrix2[y, z];
}
}
//m
for (int a = 0; a < 3; a++)
{
for (int b = 0; b < 3; b++)
{
result[a, b] = m1 *m2;
Console.Write(result[a, b] );
}Console.WriteLine();
}Console.ReadLine();
}
}
}
You're approaching this incorrectly.
for (int y = 0; y < 3; y++)
{
for (int z = 0; z < 3; z++)
{
m2 = metrix2[y, z];
}
}
After this, m2 will contain the lower right-hand value of the array (matrix[2, 2]). You're literally multiplying the same value over and over again for your multiplication. You need to put all of this in one for loop.
Also, that's not the correct way to do matrix multiplication. To begin with, your code will only work for a 3x3 matrix; not only can you have other sizes of matrices (4x4, 5x5, etc.), matrices don't even have to be square to be able to multiply them (as long as the number of columns of one equals the number of rows of the other). Even if they are both 3x3 matrices, the calculation would still be wrong. Wikipedia has some good examples of the proper way to do this.
2 0 2 1 1 1 (2*1)+(0*0)+(2*0) (2*1)+(0*1)+(2*0) ...
0 1 2 x 0 1 0 = (0*1)+(1*0)+(2*0) (0*1)(1*1)(2*0) ...
1 2 1 0 0 1 ..
This is more of a discussion than a question per se since I could solve this with code but I think there should be better ways of doing this.
I need to distribute elements in a matrix so that each quadrant of the matrix (which dimensions aren't necessarily divisible by 4) contains an equal (or as close to equal as possible) number of said elements but is located randomly within that quadrant.
The rest of the matrix needs to contain random elements of a different type.
For instance, distributing 10 elements (A) in a 9x6 matrix could look like this:
Which reveals the problem of what to do with the middle lines when a dimension is odd. It could be included on one quadrant or the other randomly (the fact that there are no As in the 3 middle columns is just chance)
I first thought of dealing with this with a recursive function that divides into quadrants and randomly places each element.
I'm halfway through coding this in C#, the idea being something like this (it doesn't work as of yet and some things are inefficient to try to make the code more readable):
private void PopulateQuadrants(ref Test5Target[,] matrix,
int xBeginQuadrant, int xEndQuadrant, int yBeginQuadrant, int yEndQuadrant, int targets)
{
if (targets == 0)
{
return;
}
else if (targets == 1)
{
Random rand = new Random();
matrix[rand.Next(xBeginQuadrant, xEndQuadrant), rand.Next(yBeginQuadrant, yEndQuadrant)]
= new Test5Target(ChosenTarget, UseAdvancedTargets);
for (int x = xBeginQuadrant; x < xEndQuadrant; x++)
{
for (int y = xBeginQuadrant; y < xEndQuadrant; y++)
{
if (matrix[x, y] == null)
{
int type = rand.Next(TargetCount);
while(type == ChosenTarget){
type = rand.Next(TargetCount);
}
matrix[x, y] = new Test5Target(rand.Next(TargetCount), UseAdvancedTargets);
}
}
}
return;
}
else
{
int[] TargetsPerQuadrant = { targets / 4, targets / 4, targets / 4, targets / 4 };
int RemaindingTargets = targets % 4;
Random rand = new Random();
while (RemaindingTargets > 0)
{ // Randomly select quadrants to allocate the Remainding targets (one may end up with 3 extra as it is now)
TargetsPerQuadrant[rand.Next(4)]++;
RemaindingTargets--;
}
PopulateQuadrants(ref matrix, xBeginQuadrant, xEndQuadrant / 2, yBeginQuadrant, yEndQuadrant / 2, TargetsPerQuadrant[0]);
PopulateQuadrants(ref matrix, xEndQuadrant / 2, xEndQuadrant, yBeginQuadrant, yEndQuadrant / 2, TargetsPerQuadrant[1]);
PopulateQuadrants(ref matrix, xBeginQuadrant, xEndQuadrant / 2, yBeginQuadrant, yEndQuadrant / 2, TargetsPerQuadrant[2]);
PopulateQuadrants(ref matrix, xEndQuadrant / 2, xEndQuadrant, yBeginQuadrant / 2, yEndQuadrant, TargetsPerQuadrant[3]);
}
}
Is there any mathematically correct or simple or something way of achieving this or should I keep going in this way.
I finally decided to just place a minimum of a fourth of all elements in each corner randomly and the remainder also randomly ignoring odd lengths or just letting it skew toward one side or the other.
private Element[,] GetCancellationTestMatrix(int rows, int columns, int targets, int types)
{
// Supposing the different types of elements are just ints and we want a concrete type
// for our targets which is contained in the variable "TargetType"
Element[,] Matrix = new int[rows, columns];
Random rand = new Random();
int currQuadRowBegin = 0;
int currQuadRowEnd = rows / 2;
int currQuadColBegin;
int currQuadColEnd;
int rowIndex;
int colIndex;
for (int i = 0; i < 2; i++)
{
currQuadColBegin = 0;
currQuadColEnd = columns / 2;
for (int j = 0; j < 2; j++)
{
for (int t = 0; t < targets / 4; t++)
{
rowIndex = rand.Next(currQuadRowBegin, currQuadRowEnd);
colIndex = rand.Next(currQuadColBegin, currQuadColEnd);
while (Matrix[rowIndex, colIndex] != null)
{
rowIndex = rand.Next(currQuadRowBegin, currQuadRowEnd);
colIndex = rand.Next(currQuadColBegin, currQuadColEnd);
}
Matrix[rowIndex, colIndex] = new Element(TargetType);
}
currQuadColBegin = currQuadColEnd++;
currQuadColEnd = columns - 1;
}
currQuadRowBegin = currQuadRowEnd++;
currQuadRowEnd = rows - 1;
}
// Some targets may be unarranged yet (up to three)
int remainding = targets % 4;
while (remainding > 0)
{
rowIndex = rand.Next(0, rows);
colIndex = rand.Next(0, columns);
while (Matrix[rowIndex, colIndex] != null)
{
rowIndex = rand.Next(0, rows);
colIndex = rand.Next(0, columns);
}
Matrix[rowIndex, colIndex] = new Element(TargetType);
remainding--;
}
// Fill the remainding elements of the target matrix with other targets
List<int> fakeTargets = new List<int>(rows * columns - targets);
// If we are placing 10 targets in a 9x6 matrix then we need to place an extra
// 9 * 6 - 10 = 34 targets and if we have, say, 4 types then we can divide that
// between 4-1 (for the target type)
int targetsOfEachType = (rows * columns - targets) / types-1;
for (int i = 0; i < types; i++)
{
if (i == TargetType) continue;
for (int j = 0; j < targetsOfEachType; j++)
{
fakeTargets.Add(i);
}
}
int tmp;
while (fakeTargets.Count < rows * columns - targets)
{
tmp = rand.Next(types);
while (tmp == TargetType)
{
tmp = rand.Next(types);
}
fakeTargets.Add(tmp);
}
Shuffle(fakeTargets); // Assume this method shuffles the list of fakeTargets
tmp = 0;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < columns; j++)
{
if (Matrix[i, j] != null) continue;
Matrix[i, j] = new Element(fakeTargets[tmp++]);
}
}
return Matrix;
}
Of course, I'm not claiming this is a good solution, just one that works for me at least for now. I'll leave some time so that someone can post a better answer or some corrections over mine before I check this as the answer.
I have this code to read a 1x3 matrix (1 5 9) from a text file and make a 3x3 matrix out of it.
The output matrix should be:
1 0 0
0 5 0
0 0 9
using a loop (and conditions - if needed). The closest I got is:
1 0 0
5 0 0
9 0 0.
Here's my code:
for (int x = 0; x <= 2; x++)
{
for (int y = 0; y <= 2; y++)
{
sw.Write("{0} ", matrix[x, y]);
sw.WriteLine();
}
}
sw.WriteLine();
sw.Close();
Here is how I think you can do it.
Let's consider matrixA the original matrix and matrixB the final matrix.
Here is the logic
//Convert 1x3 into 3x3
for (int x = 0; x <= 2; x++)
{
matrixB[x,x]=matrixA[x];
}
//Display Matrix
for (int x = 0; x <= 2; x++)
{
for (int y = 0; y <= 2; y++)
{
sw.Write("{0} ", matrix[x, y]);
sw.WriteLine();
}
}
sw.WriteLine();
sw.Close();
Here is a solution using Linq. Make sure you add System.Linq to your using clause. I did see that you want to use loops. I'll leave this here anyway for reference as a more idiomatic way of expressing the solution.
var matrix1 = new int[] {1,5,9};
var matrix3 = matrix1.Select ((v, i) => {
var n = new int[matrix1.Length];
n [i] = v;
return n;
});
foreach (var v in matrix3)
Console.WriteLine ("{0} {1} {2}", v[0],v[1],v[2]);