I need to write a program that asks the user for a number from 2 to 12, and then displays a multiplication table with answers in the format below:
User enters: 6
Output:
2 3 4 5 6
2 4 6 8 10 12
3 6 9 12 15 18
4 8 12 16 20 24
5 10 15 20 25 30
6 12 18 24 30 36
I cannot get, neither the top horizontal row (2, 3, 4, 5, 6), nor the left column (2, 3, 4, 5, 6) to display on the WPF application screen, and I also need to get the vertical tab right, so all the numbers are equally spaced horizontally and vertically. My current code looks like this:
int inputNumber;
public MainWindow()
{
InitializeComponent();
btnYes.IsEnabled = false;
}
private void calculateTable_Click(object sender, RoutedEventArgs e)
{
inputNumber = int.Parse(number.Text);
if (inputNumber < 2 || inputNumber > 12)
{
MessageBox.Show("Please enter values between 2 and 12");
number.Clear();
return;
}
for (int i = 2; i <= inputNumber; i++)
{
for (int j = 2; j <= inputNumber; j++)
{
displayValues.Text += (i * j).ToString() + '\t';
}
displayValues.Text += '\n';
}
calculateTable.IsEnabled = false;
btnYes.IsEnabled = true;
}
private void btnYes_Click(object sender, RoutedEventArgs e)
{
number.Clear();
number.Focus();
displayValues.Text = String.Empty;
btnYes.IsEnabled = false;
calculateTable.IsEnabled = true;
}
private void btnNo_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
Simplest and meaningful approach :
Use UniformGrid as <UniformGrid x:Name="UG" Columns="10"/>, code :
int from = 2, to = 15;
for (int i = from; i <= to; ++i)
{
for (int j = 1; j <= 10; ++j)
{
TextBlock tb = new TextBlock() { Text = (i * j).ToString() };
UG.Children.Add(tb);
}
}
There are other approaches :
Create a StackPanel with Orientation = Horizontal for every table. Use TextBlock for every digit.
Create a Grid with 10 columns. Your Columns are fixed, but Rows vary. So, you can create needed Rows, and show every digit in relevant Column. Use RowDefinition, Grid.SetRow() and Grid.SetColumn() .
Use a DataGrid and make it ReadOnly. Create your list, and simple assign it as DataGrid.ItemsSource. You can format the DataGrid to hide various lines etc.
The answer I need to get from my program should be in the following format:
Multiplication Tables from 2 to 12
I'm getting the left most column (2 to 8) and the results, but not the the top row (2 to 8) and the vertical spacing between the numbers. All numbers have to be evenly spaced/distributed in the grid.
One of your problems is that you forgot to print out the first number of the ì -loop iteration. For the linebreak you can also use Environment.NewLine
I used here a TextBox for the display.
Try this:
int inputNumber = 6;
for (int i = 2; i <= inputNumber; i++)
{
textBox.Text += i.ToString() + '\t';
for (int j = 2; j <= inputNumber; j++)
{
textBox.Text += (i * j).ToString() + '\t';
}
textBox.Text += Environment.NewLine;
}
The result looks the following:
And for inputNumber = 12 like this:
hope this helps.
EDIT:
Ok after you edit I understand you a little better.
To get the first line you need only to include an enumeration from 2 to the inputNumber with a leading whitespace " ". For the vertical alignment you could cheat a little and take 3 NewLines, that would be spacially the same as a tab.
here is an example code:
int inputNumber = 6;
textBox.Text += " \t" + String.Join("\t", Enumerable.Range(2, inputNumber-1)) + new string('\n', 3);
for (int i = 2; i <= inputNumber; i++)
{
textBox.Text += i.ToString() + '\t';
for (int j = 2; j <= inputNumber; j++)
{
textBox.Text += (i * j).ToString() + '\t';
}
textBox.Text += new string('\n', 3);
}
The result should look now like this:
Related
Hello my currenct code is doing sum on numbers after + including 10 I need it only after, now is doing like 10 + 10 = 20 then 20 +11 = 31 and etc which is wrong, when I change my i with 11 it adds 1 more interaction to the correct and makes the number more than 1000.
`` `
int i = 10;
int a = 10;
while (a < 1000)
{
a += i++;
}
Console.WriteLine(a);
Console.WriteLine(i);
Tried to change the numbers to 11 which is correct but gives me 1 more interaction which I want to remove!
sorry, do you mean to increment only by 10 ?, you can change a += i++; to a += i;
Solution:
int i = 11;
int a = 10;
while (a < 1000)
{
a += i++;
}
i -= 1;
a -= i;
Console.WriteLine(a);
Console.WriteLine(i);
So you want to termionate the loop before a gets > 1000.
The easiest way is to calculate the new value but not yet assign it to a:
int i = 10;
int a = 10;
while (a < 1000)
{
int newValue = a + i;
if (newValue > 1000) break;
i++;
a = newValue;
}
Console.WriteLine(a);
Console.WriteLine(i);
Alternative: you could also modify the while condition. As you know you are going to add i, check if the result would be still <= 1000:
while (a + i <= 1000)
{
a += i++;
}
Alternative 2: Another strategy proposed in #Slepcho's comment is to undo the last addition after the loop:
while (a <= 1000)
{
a += i++;
}
a -= --i;
I'm working on a math game in the Unity game engine using C#, specifically a reusable component to teach the grid method for multiplication. For example, when given the numbers 34 and 13, it should generate a 3X3 grid (a header column and row for the multiplier and multiplicand place values and 2X2 for the number of places in the multiplier and multiplicand). Something that looks like this:
My issue is that I don't know the best way to extract the place values of the numbers (eg 34 -> 30 and 4). I was thinking of just converting it to a string, adding 0s to the higher place values based on its index, and converting it back to an int, but this seems like a bad solution. Is there a better way of doing this?
Note: I'll pretty much only be dealing with positive whole numbers, but the number of place values might vary.
Thanks to all who answered! Thought it might be helpful to post my Unity-specific solution that I constructed with all the replies:
List<int> GetPlaceValues(int num) {
List<int> placeValues = new List<int>();
while (num > 0) {
placeValues.Add(num % 10);
num /= 10;
}
for(int i = 0;i<placeValues.Count;i++) {
placeValues[i] *= (int)Mathf.Pow(10, i);
}
placeValues.Reverse();
return placeValues;
}
Take advantage of the way our number system works. Here's a basic example:
string test = "12034";
for (int i = 0; i < test.Length; ++i) {
int digit = test[test.Length - i - 1] - '0';
digit *= (int)Math.Pow(10, i);
Console.WriteLine("digit = " + digit);
}
Basically, it reads from the rightmost digit (assuming the input is an integer), and uses the convenient place value of the way our system works to calculate the meaning of the digit.
test.Length - i - 1 treats the rightmost as 0, and indexes positive to the left of there.
- '0' converts from the encoding value for '0' to an actual digit.
Play with the code
Perhaps you want something like this (ideone):
int n = 76302;
int mul = 1;
int cnt = 0;
int res[10];
while(n) {
res[cnt++] = (n % 10) * mul;
mul*=10;
cout << res[cnt-1] << " ";
n = n / 10;
}
output
2 0 300 6000 70000
My answer is incredibly crude, and could likely be improved by someone with better maths skills:
void Main()
{
GetMulGrid(34, 13).Dump();
}
int[,] GetMulGrid(int x, int y)
{
int[] GetPlaceValues(int num)
{
var numDigits = (int)Math.Floor(Math.Log10(num) + 1);
var digits = num.ToString().ToCharArray().Select(ch => Convert.ToInt32(ch.ToString())).ToArray();
var multiplied =
digits
.Select((d, i) =>
{
if (i != (numDigits - 1) && d == 0) d = 1;
return d * (int)Math.Pow(10, (numDigits - i) - 1);
})
.ToArray();
return multiplied;
}
var xComponents = GetPlaceValues(x);
var yComponents = GetPlaceValues(y);
var arr = new int[xComponents.Length + 1, yComponents.Length + 1];
for(var row = 0; row < yComponents.Length; row++)
{
for(var col = 0; col < xComponents.Length; col++)
{
arr[row + 1,col + 1] = xComponents[col] * yComponents[row];
if (row == 0)
{
arr[0, col + 1] = xComponents[col];
}
if (col == 0)
{
arr[row + 1, 0] = yComponents[row];
}
}
}
return arr;
}
For your example of 34 x 13 it produces:
And for 304 x 132 it produces:
It spits this out as an array, so how you consume and display the results will be up to you.
For two-digit numbers you can use modulo
int n = 34;
int x = n % 10; // 4
int y = n - x; // 30
for (int i = 0; i <50 ; i++)
{
cb.Items.Add(i);
}
Here it shows all values until 49 in vertical format but I want in range
1-5 ,6-10,11-15
and next
you'll want to change the increment for the loop:
for (int i = 1; i < 50; i += 5)
{
cb.Items.Add($"{i}-{i + 4}");
}
I am currently breaking my head over this simple assignment for loops that I have to do.
Basically what I want to achieve is:
1) User gives imput how long the star pyramid should be
2) Make a pyramid with a for loop.
It needs to look something like this:
(If it needs to be 5 stories high; first row is 5 spaces 1 star; second row 4 spaces 2 stars and so on.
*
**
***
****
(Hard to format but you get my intention.)
I currently have this
public void Pyramid()
{
Console.WriteLine("Give the hight of the pyramid");
_aantal = Convert.ToInt32(Console.ReadLine());
for (int i = 1; i <= _aantal; i++) // loop for hight
{
for (int d = _aantal; d > 0; d--) // loop for spaces
{
Console.Write(_spatie);
}
for (int e = 0; e < i; e++) // loop for stars
{
Console.Write(_ster);
}
Console.WriteLine();
}
}
The output is always the inserted number amount of spaces and it is not decremented correctly.
Although if I debug it it counts down correctly.
Thank you for responding.
You could use the constructor of the string class to create the repetition for you, and then print both values at once, then you don't need the extra for loops
static void Main(string[] args)
{
int rowHeight = 5;
for (int row = 1; row <= rowHeight; row++)
{
string spaces = new string(' ', rowHeight - row);
string stars = new string('*', row);
Console.WriteLine("{0}{1}", spaces, stars);
}
Console.ReadLine();
}
UPDATE
for the semantics, i will then also show it with 2 for loops
static void Main(string[] args)
{
int rowHeight = 5;
for (int row = 1; row <= rowHeight; row++)
{
int totalSpaces = rowHeight - row;
for (int j = 0; j < totalSpaces; j++)
{
Console.Write(" ");
}
for (int j = 0; j < row; j++)
{
Console.Write("*");
}
Console.WriteLine();
}
Console.ReadLine();
}
well, your problem is
for (int d = _aantal; d > 0; d--) // loop for spaces
you really want
for (int d = _aantal - i ; d > 0; d--) // loop for spaces
but it really just mirrors what you currently have, and still doesn't create the pyramid look you seem to want.
I think the closest you'll get in a console app is by subtracting a space every other row:
for (int d = _aantal-i; d > 0; d-=2) // loop for spaces
which will give output:
Give the hight of the pyramid:
10
*
**
***
****
*****
******
*******
********
*********
**********
Got it !
static void Main(string[] args)
{
Console.WriteLine("Give the hight of the pyramid");
string _spatie = " ";
string _ster = "*";
int _aantal = Convert.ToInt32(Console.ReadLine());
for (int i = 1; i <= _aantal; i++) // loop for height
{
for (int d = i; d < _aantal; d++) // loop for spaces
{
Console.Write(_spatie);
}
for (int e = 1; e <= i; e++) // loop for stars
{
Console.Write(_ster);
}
Console.WriteLine();
}
Console.ReadKey();
}
Check this out..!! You were missing out the iterator 'i' of the height loop inside the spaces loop.
You will get the triangle :-
*
**
***
****
You will need odd number of stars always for a symmetrical pyramid.
I know you wanted to do this as a console app but if you adapt this code it should work fine
Replace textbox1/2 with Consle.Readline/Write
int pyramidstories = int.Parse(TextBox2.Text);
int I = 1;
while (I <= pyramidstories)
{
for (int spacecount = 0; spacecount < (pyramidstories - I); spacecount++)
{
TextBox1.Text += " ";
}
for (int starcount = 1; starcount < I + 1; starcount++)
{
TextBox1.Text += "*";
}
TextBox1.Text += Environment.NewLine;
I++;
}
As your question states you need:
4 spaces 1 star
3 spaces 2 stars
2 spaces 3 stars
etc..
so your pyramid should look something like
*
**
***
****
*****
The code sample above displays a pyramid as illustrated above
To get a pyramid (with proper spacing) like this:
You can use:
static void Main(string[] args)
{
// The length of the pyramid
int lengte = 18;
// Loop through the length as given by the user
for (int i = 0; i <= lengte; i++)
{
// If its an even number (we don't want 1-2-3.. but 1-3-5.. stars)
if (i % 2 == 0)
{
// Calculate the length of the spaces we need to set
int spatieLengte = (lengte / 2) - (i / 2);
// Display spaces
for (int spaties = 0; spaties <= spatieLengte; spaties++)
{
Console.Write(" ");
}
// Display stars
for (int sterren = 0; sterren <= i; sterren++)
{
Console.Write("*");
}
// Newline
Console.WriteLine();
}
}
Console.ReadLine();
}
Obviously the if block and spaceLengte variable aren't really needed. But I thought it would make it somewhat easier for OP to read.
Good luck / Succes ermee ;)
I am attempting to make Conway's Game of Life in C# with XAML. The window allows the user to specify the number of rows and columns of my 2D array of cells using a slider. When my Uniform Grid is a perfect square (10x10, 20x20, or even 16x16), the simulations work without a problem. However, when the user attempts to specify a rectangular uniform grid (13x14, 15x26, 24x14), the cells are thrown of by the difference (i.e. in a 33x27 grid, difference = 6, so the cell goes appropriately up, but is thrown off (left/right) by the difference). I have narrowed down that this only happens on the x-axis; the cells are never thrown off on the y-axis.
THE QUESTION: Why is my array throwing off my x axis? Is there something wrong with it?
As far as I can tell, everything should work fine. I set up a log to check the dimensions of my 2D arrays and my uniform grid. I'm not sure what is wrong, and I have been staring and debugging for literally DAYS. I'm at my wits end. Please help, I hope there is something that I am simply not catching.
Code Legend:
unigridOfCells is a Uniform Grid in XAML.
slideWidth/slideHeight are sliders.
Also, I am using a converter from my resource which converts my isAlive property to a SolidColorBrush.
private Cell[,] cells;
private Cell[,] nextGenCells;
private int codeColumn, codeRow, difference, secondDiff;
public MainWindow()
{
InitializeComponent();
unigridOfCells.Height = 500;
unigridOfCells.Width = 500;
setCellsOnGrid(10, 10);
}
//Sets all the cells on the grid, as well as setting the number of columns and rows to be reset for all arrays in the application
public void setCellsOnGrid(int column, int row)
{
unigridOfCells.Rows = row;
unigridOfCells.Columns = column;
codeColumn = column;
codeRow = row;
time = new Timer(3000);
cells = new Cell[codeColumn, codeRow];
nextGenCells = new Cell[codeColumn, codeRow];
for (int i = 0; i < codeColumn; i++)
{
for (int j = 0; j < codeRow; j++)
{
cells[i, j] = new Cell();
Rectangle block = new Rectangle();
block.Height = 10;
block.Width = 10;
block.DataContext = cells[i, j];
block.MouseLeftButtonDown += cells[i, j].ParentClicked;
//block.MouseLeftButtonDown += blockSpace;
Binding b = new Binding();
b.Source = cells[i, j];
b.Path = new PropertyPath("isAlive");
b.Converter = (BoolColorConverter)Application.Current.FindResource("cellLifeSwitch");
block.SetBinding(Rectangle.FillProperty, b);
unigridOfCells.Children.Add(block);
}
}
}
public void blockSpace(object sender, MouseButtonEventArgs e)
{
int spot = 0;
int pick = 0;
for (int i = 0; i < codeColumn; i++)
{
for (int j = 0; j < codeRow; j++)
{
spot = unigridOfCells.Children.IndexOf((Rectangle)sender);
}
}
MessageBox.Show("" + spot + " : " + pick);
}
//Updates the cells. This is where the rules are applied and the isAlive property is changed (if it is).
public void updateCells()
{
for (int n = 0; n < codeColumn; n++)
{
for (int m = 0; m < codeRow; m++)
{
nextGenCells[n, m] = new Cell();
bool living = cells[n, m].isAlive;
int count = GetLivingNeighbors(n, m);
bool result = false;
if (living && count < 2)
{
result = false;
}
if (living && (count == 2 || count == 3))
{
result = true;
}
if (living && count > 3)
{
result = false;
}
if (!living && count == 3)
{
result = true;
}
nextGenCells[n, m].isAlive = result;
}
}
setNextGenCells();
}
//Resets all the cells in a time step
public void setNextGenCells()
{
for (int f = 0; f < codeColumn; f++)
{
for (int k = 0; k < codeRow; k++)
{
cells[f, k].isAlive = nextGenCells[f, k].isAlive;
}
}
}
//Checks adjacent cells to the cell in the position that was passed in
public int GetLivingNeighbors(int x, int y)
{
int count = 0;
// Check cell on the right.
if (x != codeColumn - 1)
if (cells[x + 1, y].isAlive)
count++;
// Check cell on the bottom right.
if (x != codeColumn - 1 && y != codeRow - 1)
if (cells[x + 1, y + 1].isAlive)
count++;
// Check cell on the bottom.
if (y != codeRow - 1)
if (cells[x, y + 1].isAlive)
count++;
// Check cell on the bottom left.
if (x != 0 && y != codeRow - 1)
if (cells[x - 1, y + 1].isAlive)
count++;
// Check cell on the left.
if (x != 0)
if (cells[x - 1, y].isAlive)
count++;
// Check cell on the top left.
if (x != 0 && y != 0)
if (cells[x - 1, y - 1].isAlive)
count++;
// Check cell on the top.
if (y != 0)
if (cells[x, y - 1].isAlive)
count++;
// Check cell on the top right.
if (x != codeColumn - 1 && y != 0)
if (cells[x + 1, y - 1].isAlive)
count++;
return count;
}
//Fires when the next generation button is clicked. Simply makes the board go through the algorithm
private void nextGenerationClick(object sender, RoutedEventArgs e)
{
updateCells();
}
//Fired when the "Reset Grid" button is pressed, resets EVERYTHING with the new values from the sliders
private void resetGrid(object sender, RoutedEventArgs e)
{
MessageBox.Show("First Slide (width) value: " + slideWidth.Value + "\nSecond Slide (length) value: " + slideHeight.Value + "\nDifference: " + (codeColumn - codeRow) + "\nColumns: " + unigridOfCells.Columns + " \nRows: " + unigridOfCells.Rows + "\nChildren count: " + unigridOfCells.Children.Count + " \nLengths: "
+ "\n\tOf 1D of cells: " + cells.GetLength(0) + "\n\tOf 1D of nextGenCells: " + nextGenCells.GetLength(0) + "\n\tUniform Grid Columns: " + unigridOfCells.Columns + " \nWidths: "
+ "\n\tOf 2D of cells: " + cells.GetLength(1) + "\n\tOf 2D of nextGenCells: " + nextGenCells.GetLength(1) + "\n\tUniform Grid Rows: " + unigridOfCells.Rows);
unigridOfCells.Children.Clear();
setCellsOnGrid((int)slideWidth.Value, (int)slideHeight.Value);
}
The problem is that the order in which you create cells differs from the order in which the UniformGrid arranges its children.
In your setCellsOnGrid method, you create cells top-to-bottom, then left-to-right, whereas the UniformGrid arranges its children in the order left-to-right then top-to-bottom.
For a square grid, the cells in the first column of your grid are drawn in the first row of the UniformGrid, and similarly for other columns and rows. You end up with the grid being reflected in the line x = y. However, for a non-square grid, the length of a row does not equal the length of a column and so the grid is completely out of place.
For example, with a 3 × 3 grid, your loop runs in the following order:
1 4 7
2 5 8
3 6 9
However, the controls are added to the UniformGrid in the following order (assuming you haven't set FlowDirection="Right"):
1 2 3
4 5 6
7 8 9
For, for a 3 × 4 grid, your loop runs in the order
1 5 9
2 6 10
3 7 11
4 8 12
but the controls are added to the UniformGrid in the order
1 2 3
4 5 6
7 8 9
10 11 12
This means that cells that adjacent in your cells array might not be drawn as adjacent in the UniformGrid, and vice versa.
Fortunately, the fix is simple: switch the order of the i and j loops in setCellsOnGrid. Make the j loop the outer loop and the i loop the inner loop.
Incidentally, your blockSpace method doesn't appear to use the i and j loop variables - it just calls the same method codeColumn * codeRow times. Is this intentional?