I'm trying to create a piece of code that will show this at the end
1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
4 4 4 4 4
5 5 5 5 5
But what I've written shows this instead
1 1 1 1 1
2 0 0 0 0
3 0 0 0 0
4 0 0 0 0
5 0 0 0 0
Here's the code I've written
int col, lig, test;
col = 0;
test = 0;
for (lig = mat.GetLowerBound(0); lig <= mat.GetUpperBound(0); lig++)
{
mat[lig, col] = 1 + test++;
}
for (col = mat.GetLowerBound(0) + 1; col <= mat.GetUpperBound(0); col++)
{
mat[0, col] = mat[0, col] + 1;
}
I've tried multiple things but none of them worked, what can I modify so that it gives the result I'm trying to get?
There are a few things wrong with your code:
You are checking the bounds of the array in dimension 0 for the second loop (for col), but using col in dimension 1 of the array: you should be using GetLowerBound(1) and GetUpperBound(1) instead. This isn't an issue here because you have a square array, but you should be aware.
You need to use a nested loop over the row and column, not two separate j loops. Your code is doing what you tell it to:
In the first loop you're setting mat[lig, col] but col is zero so you only set values in the first column. By declaring lig and col in the loops (see my code below) you can avoid this mistake.
In the second loop you're setting mat[0, col] which will only change values in the first row.
Additionally, you're starting the second loop at mat.GetLowerBound(0) + 1 which will miss the first element out. Presumably you did this on purpose because it set the element at (0,0) to 2.
The code you need is:
int test = 0;
for ( int lig = mat.GetLowerBound(0); lig <= mat.GetUpperBound(0); lig++ )
{
test++;
for ( int col = mat.GetLowerBound(1); col <= mat.GetUpperBound(1); col++ )
mat[lig, col] = test;
}
You can further simplify this by noting that test is always lig + 1 and eliminate test altogether:
for ( int lig = mat.GetLowerBound(0); lig <= mat.GetUpperBound(0); lig++ )
{
for ( int col = mat.GetLowerBound(1); col <= mat.GetUpperBound(1); col++ )
mat[lig, col] = lig + 1;
}
Related
I am new to coding and are trying to make a Connect 4 game in c#. I have a 2D array that is 6 by 6 and initialized as all 0's to begin with. When player 1 inputs their choice, the 0 in the lowest position for that column in the array is replaced with a 1. Likewise with Player 2 - with a 2 replacing the 0's (only) instead.
What I can't seem to make work is for it to check each column for 4 of the same values in a row, each row for 4 of the same values in a row, and then diagonally for 4 of the same values in a row. Below is the code I was trying to make it search along each column for 4 of the same values in a row. Could you please help. Thank you
x = 0;
while (x <= 5)
{
for (row = 5; row >= 0; row--)
{
if (Grid[row, x] == 1)
{
Player1Score = Player1Score + 1;
}
else
{
Player1Score = 0;
}
if (Grid[row, x] == 2)
{
Player2Score = Player2Score + 1;
}
else
{
Player2Score = 0;
}
}
x = x + 1;
if (Player1Score == 4)
{
Console.Clear();
Console.WriteLine("Player1 wins");
}
else if (Player2Score == 4)
{
Console.Clear();
Console.WriteLine("Player2 wins");
}
}
How about:
Have 2 vars, player1Score, player2Score.
For rows:
go through each element in a row,
if it is 0
set player1Score and player2Score to 0
if it is 1
increase player1Score by 1
-- set player2Score to 0
if it is 2
increase player2Score by 1
set player1Score to 0
when you're done with with the row, check if any of the player scores is equal to 4, if it is, game won. Otherways reset scores and go to the another row.
You do the same thing with cols, and diagonals (in diagonals col id is equal to row id).
To my understanding the entries of a datatable are usually row oriented where the columns have a certain meaning and the rows indicate different datasets.
This is also why the actual data is added with DataTable.Rows.Add()
In my case the columns are considered one dataset and I need to extract data from these columns for use in other areas.
I am using a combination of LINQ and Lambda expressions to get the data of one complete column:
int curCol = 4;
int maxRows = 55;
byte[] values = new byte[maxRows];
values = dt.Rows.Cast<DataRow>().Select<DataRow, byte>(row => Convert.ToByte(row[curCol])).ToArray();
But this is where my luck with LINQ and Lambda ends.
I try to implement a copy routine to select columns different from the source but having the same value in a certain row. Then I select a range of rows to be copied to all the other matching columns. Here is an example how this works with for and if statements:
const int numCols = 10;
int curCol = 2;
int searchRow = 1;
int startRow = 3;
int numRows = 25;
byte val = (byte)dt.Rows[searchRow][curCol];
// iterate through all columns
for (int col = 0; col < numCols; col++)
{
// look for "other" columns with the same value in the searchRow of interest
if (col != curCol && val == (byte)dt.Rows[searchRow][col])
{
// iterate through the given row range (startRow and numRows)
for (int row = startRow; row < startRow+numRows; row++)
{
// copy from current column
dt.Rows[row][col] = dt.Rows[row][curCol];
}
}
}
I was wondering if there is a nicer, more efficient way to implement this Using LINQ and Lambda expressions?
Example Data
1 2 3 4 ... // cols 0 .. 3 in row 0
5 5 6 6 ... // cols 0 .. 3 in row 1
0 0 1 0 ... // ...
7 0 8 0 ...
9 0 9 0 ...
. . . .
Expected Result
1 2 3 4 ...
5 5 6 6 ... // value in col 3 is equal to value in col 2
0 0 1 0 ...
7 0 8 8 ... // value from col 2 copied to col 3
9 0 9 9 ... // value from col 2 copied to col 3
. . . .
I hope this makes it easier to understand. Column 2 and 3 are grouped/linked by their value in row 1 and since column 2 is the source other values from a selected row range should be copied over to the linked colums.
Just to make that clear. The If/For implementation above does exactly this. I was just hoping for a LINQ/Lambda shortcut or another more efficient way of execution.
I don't see much:
DataTable dt = new DataTable();
const int numCols = 10;
int curCol = 4;
int searchRow = 1;
int startRow = 3;
int numRows = 25;
int hashVal = dt.Rows[searchRow][curCol].GetHashCode();
var thisValue = dt.Rows[searchRow][curCol];
//iterate cols and rows
for(int c = 0; c < numCols; c++)
{
for(int r = startRow; r < startRow + numRows; r++)
{
int thisHash = dt.Rows[r][c].GetHashCode();
if (thisHash == hashVal)
{
dt.Rows[r][c] = thisValue;
}
}
}
Nothing ground-shaking. What I don't understand, though, is that you seem to be finding matching values in order to copy matching values - by default, if the value is already equal to the source row/col, then why does it need to be copied (because it's already equal)? Perhaps you're simplifying for demonstration purposes, but I'm not seeing a need for this...
For a given number n I have to print the following matrix (n = 3 example):
3 3 3 3 3
3 2 2 2 3
3 2 1 2 3
3 2 2 2 3
3 3 3 3 3
the count of rows and columns should be (2 * n) - 1. I tried to find the pattern but couldn't figured it out. Any help would be helpful. Thanks
Something like this:
private static int[][] Matrix(int n) {
// Create arrays
int[][] result = Enumerable.Range(0, 2 * n - 1)
.Select(_ => new int[2 * n - 1])
.ToArray();
// Feed arrays
for (int i = 1; i <= n; ++i) {
int from = i - 1;
int to = 2 * n - i - 1;
int v = n - i + 1;
for (int j = from; j <= to; ++j) {
result[from][j] = v;
result[to][j] = v;
result[j][from] = v;
result[j][to] = v;
}
}
return result;
}
....
int n = 3;
String report = String.Join(Environment.NewLine, Matrix(n)
.Select(line => String.Join(" ", line)));
Console.Write(report);
Output for n = 3 is
3 3 3 3 3
3 2 2 2 3
3 2 1 2 3
3 2 2 2 3
3 3 3 3 3
And for n = 4:
4 4 4 4 4 4 4
4 3 3 3 3 3 4
4 3 2 2 2 3 4
4 3 2 1 2 3 4
4 3 2 2 2 3 4
4 3 3 3 3 3 4
4 4 4 4 4 4 4
Here's a version that doesn't use any intermediate storage:
static void printMatrix(int n)
{
int x = 2*n - 1;
for (int i = 0, p = n; i < x; ++i, p += (i > x/2) ? 1 : -1)
{
for (int j = 0, q = n; j < x; ++j, q += (j > x/2) ? 1 : -1)
Console.Write(Math.Max(p, q) + " ");
Console.WriteLine();
}
}
This works as follows:
The outer loop (i) and inner loop (j) both go from 0 .. 2*n-1.
However, the values that we want to print (p and q) start at n and decrease until halfway across/down the matrix, at which point they start increasing again.
We can determine whether to increment or decrement these values by checking the loop variable to see if it is halfway across/down the matrix yet. If it is, we decrement, otherwise we increment.
That's what this is doing: p += (i > x/2) ? 1 : -1.
If i > x/2 then the value 1 will be used for the increment, otherwise -1 will be used for the increment (i.e. it will be decremented).
(Similarly for q.)
The final piece of the puzzle is that the value we want to use is actually the maximum of p and q. If you inspect the matrix, you will see that if you consider each row value and each column value, the maximum of each is used for the corresponding cell.
Hence the use of Math.Max(p, q) in the output.
Here a simpler solution less complicated and fastest here so far:
private static void printMatrix(int n)
{
// length of the matrix in one dimension
int length = (2 * n) - 1;
// iterate through y axis of the matrix
for (int i = 0; i < length; i++)
{
int value = n;
// iterate through x axis of the matrix
for (int j = 0; j < length; j++)
{
Console.Write(value);
if (i > j && i + j < length - 1)
{
value--;
}
else if (i <= j && i + j >= length - 1)
{
value++;
}
}
Console.WriteLine();
}
}
Explanation for the if statements
First take a look on the matrix like it would be an array and look at the indexes and values and what changes when iterating through the array in the two for statements whereas the value of i is for the y axis, from up to down and the value of j is for the x axis, from left to right.
// +1 and -1 means the changes of the values
0,0 0,1 0,2 0,3 0,4 // values of i,j (first is i, second is j)
[3] [3] [3] [3] [3] // printed value
1,0 1,1 1,2 1,3 1,4
[3] -1 [2] [2] [2] +1 [3]
2,0 2,1 2,2 2,3 2,4
[3] -1 [2] -1 [1] +1 [2] +1 [3]
3,0 3,1 3,2 3,3 3,4
[3] -1 [2] [2] [2] +1 [3]
4,0 4,1 4,2 4,3 4,4
[3] [3] [3] [3] [3]
As you can see, the value changes only in specific circumstances.
And this happens -1 if i > j and if i + j < length - 1, otherwise after index 3,1 you will have wrong values, after that it shouldn't subtract the value any more.
This two if statements lead us to the first statement in the code:
if (i > j && i + j < length - 1)
{
value--;
}
Now it also happens +1 if i + j >= length - 1 but that not other values like 3,1 also add +1 to the value it only increments it, if i <= j, which leads us to the second if-statement in the code:
else if (i <= j && i + j >= length - 1)
{
value++;
}
If none of these statements are true, the value simply stays the same as it should.
I have table 4 x 4 and wanna get summary of 3 integer values in last columns
public class Table
{
static void Main()
{
int row, column;
int sumrow = 0;
int sumcolumn = 0;
int[,] numbers = new int[4, 4];
for (row = 0; row < 3;row++)
{
for (column = 0; column < 3 ; column++)
{
Console.Write("Give number to place [" + row + "," + column + "]: ");
numbers[row, column] = int.Parse(Console.ReadLine());
}
}
for (row = 0; row < 2; row++) // how to count it?
{
for (column = 0; column < 3; column++)
{
sumrow = numbers[ row ,column] + sumrow;
numbers[0, 3] = sumrow;
}
}
}
}
After you request user input, you have a two-dimensional array with all zeroes in the last row and column, for instance:
1 2 3 0
4 5 6 0
7 8 9 0
0 0 0 0
And you want the last rows and columns to be populated with the sum of the respective row or column:
1 2 3 6
4 5 6 15
7 8 9 24
12 15 18 45
Each non-summary entry in the array contributes to three totals: the row total, the column total, and the grand total (sum of all elements), like so:
0 0 0 0
0 X 0 X
0 0 Y Y
0 X Y X+Y
As one approach, you can enumerate through each data (non-summary) element, and update the three respective summary elements accordingly:
int rowCount = numbers.GetLength(0) - 1; // # rows, exc. total
int columnCount = numbers.GetLength(1) - 1; // # cols, exc. total
for (row = 0; row < rowCount; row++)
{
for (column = 0; column < columnCount; column++)
{
int cell = numbers[row, column];
checked // throw on arithmetic overflow
{
numbers[row, columnCount] += cell;
numbers[rowCount, column] += cell;
numbers[rowCount, columnCount] += cell;
}
}
}
Note that this approach assumes the last row and column are initially all zeroes, which holds in your example. It does not require the original array be square.
You could sum the columns of a 2-d array as follows:
IEnumerable<int> columnSums = Enumerable
.Range(0, numbers.GetLength(0))
.Select(col => Enumerable
.Range(0, numbers.GetLength(1))
.Sum(row => numbers[col, row]))
Untested and possibly with columns and rows the wrong way round...
Sorry for the previous question, but I was so confused and stressed :S.
I have this function in R:
shift <- function(d, k) rbind( tail(d,k), head(d,-k), deparse.level = 0 )
and this data frame:
A B value
1 1 0.123
2 1 0.213
3 1 0.543
1 2 0.313
2 2 0.123
3 2 0.412
this function will transform this data frame to (in case k=1) :
A B value
3 2 0.412
1 1 0.123
2 1 0.213
3 1 0.543
1 2 0.313
2 2 0.123
Code:
string[] data = File.ReadAllLines("test.txt");
decimal[,] numbers = new decimal[data.Length, 3];
for(int x = 0; x < data.Length; x++)
{
string[] temp = data[x].Split(' ');
for(int y = 1; y < temp.Length; y++)
{
numbers[x,y] = Convert.ToDecimal(temp[y]);
}
}
that's the code i'm using to get the values from the text file , but i want to create the function that will rotate this table.
I want to make the same function for a text file in Java or C#.
How this can be done?
I'm storing the data in C# in a 2D array: decimal[,]
UPDATE:
your function will rotate them like the previous example, what i want to do is this:
i have this table:
A B value
1 1 0.123
2 1 0.213
3 1 0.543
1 2 0.313
2 2 0.123
3 2 0.412
i want it to become(in case of shift by 2) :
A B value
3 1 0.543
1 2 0.313
2 2 0.123
3 2 0.412
1 1 0.123
2 1 0.213
I think this will do what you want but I must admit I'm not that familiar with C# so I'd expect there to be a more idiomatic form with less looping:
static decimal[,] Rotate(decimal[,] input, int k)
{
int m = input.GetLength(0);
int n = input.GetLength(1);
decimal[,] result = new decimal[m, n];
for (int i=0; i<m; i++)
{
int p = (i + k) % m;
if (p < 0)
p += m;
for (int j=0; j<n; j++)
result[p, j] = input[i, j];
return result;
}
Regarding your update, that is handled by passing a negative value for k. For your example pass k=-2.