I'm relatively new to programming, and I'm currently trying to get to grips with C#. I've reached a point where I'm learning about 'for' loops. The problem I'm stuck on is to create the shape below using only 'for' loops and the character '*' only once.
*
***
*****
*******
*********
The code I've written is below:
for (int row = 0; row < 5; row++)
{
for (int column = 0; column + row < 4; column++)
{
Console.Write(" ");
}
for (int column = 0; column + row >= 4; column++)
{
if (column - row >= 5)
break;
Console.Write("*");
}
Console.WriteLine();
}
From what I can see, the second nested 'for' loop is being skipped until the first loop is complete.
Replacing the spaces with "O", this displays the following:
OOOO
OOO
OO
O
*********
**********
***********
************
*************
**************
Can anyone see where I'm going wrong?
The problem is in the loop condition for the second nested loop, column + row >= 4. Since column starts at zero, the first execution is basically the same as row >= 4 so for any row < 5 it won't print, which is exactly the conditions of the first loop. This means all the spaces are printed, and then a bunch of stars.
You also don't need the if-statement since that is basically a second loop condition. Something like for (int column = 0; column <= row * 2; column++) would make the most sense.
You also should probably re-evaluate the outer loop, since you only want 5 lines, and you will go through 10 lines as-is.
for (int row = 0; row < 5; row++)
{
for (int column = 0; column + row < 4; column++)
{
Console.Write(" ");
}
for (int column = 0; column <= row * 2; column++)
{
Console.Write("*");
}
Console.WriteLine();
}
for (int row = 0; row < 10; row++)
{
// This code will only get run for the first 3 rows
for (int column = 0; column + row < 4; column++)
{
Console.Write(" ");
}
// This code will only get run for rows 4 and greater
for (int column = 0; column + row >= 4; column++)
{
if (column - row >= 5)
break;
Console.Write("*");
}
Console.WriteLine();
}
What you need to do is ensure your are putting the correct number of spaces followed by the correct number of * for each line.
Hint: You probably only want 5 rows not 10
This works:
for (int row = 0; row < 5; row++)
{
for (int column = 0; column < 5 + row + 1; column++)
Console.Write(column < 5 - row ? " " : "*");
Console.WriteLine();
}
*
***
*****
*******
*********
Worked out a solution:
for (int row = 0; row < 5; row++)
{
for (int column = 0; column + row < 4; column++)
{
Console.Write(" ");
}
for (int column = 0; column + row >= 0; column++)
{
if (column == (row * 2) + 1)
break;
Console.Write("*");
}
Console.WriteLine();
}
x...'s solution is probably more appropriate, being clearer and without the need for an if statement and any breaks, but you all helped me reach the answer without too much hand holding, and I appreciate that.
Thanks :D
A simple logic can be like this.
for(i=0 to 4) //since five rows
for(j=0 to 2*i-1) // is in multiple of 1, 3, 5
print(*)
Related
I am trying to calculate the Neighbour near my cells, but the code works for only the middle cells and not for the corner ones, for which I can use many if loops but I wanna know how it works with for and if loops.
I tried creating extra if loops or writing like if row ==0 etc. but everything seems to give me wrong answer. btw bool[,] grid has the values of false and true. and we need to calculate how many trues and false are their in give row/ col.
public static int CountNeighbours(bool[,] grid, int row, int col)
{
int total = 0;
for (int i = row - 1; i < row + 2; i++)
{
for (int j = col - 1; j < col + 2; j++)
{
if (grid[i, j] == grid[row, col])
{
total += 1;
}
}
}
Console.WriteLine("total neighbours for row {0} and column {1}: {2}",row,col,total-1);
return total-1;
}
The result should give perfect answer for corners and rows.
Your problem is that you count the cell itself as its own neighbour and that you don't check the boundaries of your grid.
Change your loop conditions like that:
for (int i = Math.Max(0, row - 1); i < row + 2 && i < grid.GetLength(0); i++)
{
for (int j = Math.Max(0, col - 1); j < col + 2 && j < grid.GetLength(1); j++)
{
if (i == row && j == col) continue; // skip current cell
So with Math.Max() you ensure that you don't use a negative i or j, because that would lead to an IndexOutOfRangeException.
With grid.GetLength() you get the array size in the respective dimension, because using a i or j greater or equal to that length would again raise an IndexOutOfRangeException.
And finally the last line checks that you don't count the cell in question itself.
I'm currently messing around with 2D arrays. I want to Fill a 2D array with a count. I've managed to do this using 2 nested for loops. (That's probably the easiest way of doing it right?)
//create count
int count = 1;
for (int row = 0; row < matrix.GetLength(0); row++)
{
for (int col = 0; col < matrix.GetLength(0); col++)
{
matrix[row, col] = count++;
}
}
I was just curious, is it also possible to fill this 2D array using only a single for loop?
I thought of making a loop that counts the rows. When the rows reaches the end of the array the column wil be increased by 1. This could probably be done by using some if, if else and else statements right?
Does someone here have any idea how to make this work?
Here you go
int[,] matrix = new int[5, 10];
int row = matrix.GetLength(0);
int col = matrix.GetLength(1);
for (int i = 0; i < row * col; i++)
{
matrix[i / col , i % col] = i + 1;
}
https://dotnetfiddle.net/Lv9DvT
Yes, of course you can.
for(int i = 0; i < matrix.GetLength(0) * matrix.GetLength(1); i++)
{
int row = i / matrix.GetLength(1);
int column = i % matrix.GetLength(1);
matrix[row, column] = i;
}
Works with NxN arrays.
I have an array and i want to extract specific column from it, let's say the 3rd column only.
Example:
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
What is want is to extract 3rd column and display only:
3
3
3
3
This is my code where i am able to create a dynamic array specified by the user:
int r;
int c;
Console.Write("Enter number of rows: ");
r = (int)Convert.ToInt32(Console.ReadLine());
Console.Write("Enter number of columns: ");
c = (int)Convert.ToInt32(Console.ReadLine());
int[,] matrix = new int[r, c];
/*Insert Values into Main Matrix
--------------------------------------------------------------------------------*/
for (int row = 0; row < r; row++)
{
for (int col = 0; col < c; col++)
{
Console.Write("Enter value for matrix[{0},{1}] = ",row, col);
matrix[row, col] = (int)Convert.ToInt32(Console.ReadLine());
}
}
/*Print and show initial Matrix
--------------------------------------------------------------------------------*/
Console.WriteLine("Your matrix is,");
for (int row = 0; row < r; row++)
{
for (int col = 0; col < c; col++)
{
Console.Write(matrix[row, col] + " ");
}
Console.WriteLine();
}
/*Fixing first 2 columns
--------------------------------------------------------------------------------*/
int startingMatrixCols = 2;
Console.WriteLine("Fixed first 2 columns:");
for (int row = 0; row < r; row++)
{
for (int col = 0; col < startingMatrixCols; col++)
{
Console.Write(matrix[row, col] + " ");
}
Console.WriteLine();
}
var column = 2; // your expected column
//if it needs to be dynamic, you can read it from user entry
// Console.Write("Enter expected column: ");
// column = int.Parse(Console.ReadLine()); //enhance with error checks
for (int row = 0; row < r; row++)
{
Console.Write(matrix[row, column] + " ");
}
Console.Write("Enter the column number to display ");
int displayColNo = (int)Convert.ToInt32(Console.ReadLine());
/*If displayColNo=3 it displays only 3rd column numbers*/
for (int row = 0; row < r; row++)
{
Console.Write(matrix[row, displayColNo]);
Console.WriteLine();
}
I have 48 columns in my datagrid, I want to label data grid columns header in such a way that every alternate column represent one hour while following column represent half hour i.e
if my first column is 00 then my next column should be 00:30 in this way 01 should be followed 01:30 and so on. I have tried this, but I think I am messing up my nested loops.
for (int i = 0; i < 24; i += 2)
{
dataGridView1.Columns[i].Name = Convert.ToString(i);
for (int j = 0; j <= i; j += 1) {
dataGridView1.Columns[i].Name = Convert.ToString(j) + ":30";
}
}
You only need one loop:
for (int i = 0; i < dataGridView1.Columns.Count; i++) {
dataGridView1.Columns[i].HeaderText = (i/2).ToString("00") + (i% 2 == 0? ":00" : ":30");
}
In C# Winforms, I'd like to use a DataGridView as a simple widget to store information to display to the user. To this end, I'd like to create a table of say, 5x10 cells.
After some research, solutions tend to allow adding just one row or column at a time. I'd like the whole grid created initially and straight away, so I can start populating it with data, like you would with a standard C# 2D array.
What's the simplest way of going about this? A function header could look like this:
createCells(DataGridView dgv, int cols, int rows) {}
It should be quick and amenable to changing the cols and rows to a larger or smaller number later on if need be.
By the way, there might an error like:
Sum Of The Columns' FillWeight Values Cannot Exceed 65535
To avoid it, set AutoGenerateColumns property to false, and set FillWeight to 1 for each column generated:
dgv.AutoGenerateColumns = false;
for (int i = 1; i <= columns; i++)
{
dgv.Columns.Add("col" + i, "column " + i);
dgv.Columns[i - 1].FillWeight = 1;
}
for (int j = 0; j < rows; j++)
dgv.Rows.Add();
You can do by using for loops in this way:
private DataGridView DGV_Creation(DataGridView dgv, int columns, int rows)
{
for (int i = 1; i <= columns; i++)
{
dgv.Columns.Add("col" + i, "column " + i);
}
for (int j = 0; j < rows; j++)
{
dgv.Rows.Add();
}
return dgv;
}
Call it with:
this.dataGridView1 = DGV_Creation(dataGridView1, 5, 10); // 5 columns, 10 rows (empty rows)
or:
private void DGV_Creation(ref DataGridView dgv, int columns, int rows)
{
for (int i = 1; i <= columns; i++)
dgv.Columns.Add("col" + i, "column " + i);
for (int j = 0; j < rows; j++)
dgv.Rows.Add();
}
call it with:
DGV_Creation(ref this.dataGridView1, 5, 10); //5 columns, 10 rows (empty rows)