How do I construct a pyramid using a loop program, given a number of rows by a user's input? Such as
*
***
*****
*******
I've tried watching several videos and reading articles about the logic of this, but instructors were either not understandable or they skipped lines of reasoning.
I know every row increases by 2 stars, and I know that because every row has an odd number of stars I can define the number of stars in a row as 2n+1 where n is an integer. I noticed a 2 row triangle has a base of 3 stars, a 3 row triangle has a base of 5 stars, and so on. So for an nth row, the triangles base is n+(n-1), which is 2n-1. For example, r_5: base = 9 stars. The next thing I know my program needs to consider is spacing. I noticed, from the base, spacing increases by 2 every row until we have n-1 spaces on the first half and another n-1 spaces on the second half, in other words, spacing increases from the base until it is greater than or equal to 2b-2.
I think all that covers the gist a java program would need to know: the number of stars per row, the size of the base, and spacing.
But how do I translate all this in terms of a for while loop?
Method 1
Note that, if we denote current line number as "line" starting from 0, and total number of lines as "n",
Number of stars in each line = 2*line + 1
Number of leading (or trailing) spaces in each line = n - line - 1
We can simply generate the pyramid using this rule:
int n = 4;
for (int line = 0; line < n; line++) {
StringBuilder sb = new StringBuilder();
int starsToAppend = 2 * line + 1;
int spaceToAppend = n - line - 1;
while (spaceToAppend-- > 0) sb.append(" ");
while (starsToAppend-- > 0) sb.append("*");
System.out.println(sb.toString());
}
Method 2
You can also approach from the middle and expand. Note that there is a constant column of a star (*) in the middle, and on each side, only one star gets added in each line each time. And the rest are spaces.
int n = 4;
for(int line=0; line <n ; line++){
StringBuilder sb = new StringBuilder("*");
int spacesToAppendOnBothSides = n-line-1;
int starsToAppendOnBothSides = line;
for(int idx=0; idx<starsToAppendOnBothSides; idx++){
sb.insert(0, "*"); //appends to the beginning
sb.append("*"); //appends to the end
}
for(int idx=0; idx<spacesToAppendOnBothSides; idx++){
sb.insert(0, " ");
sb.append(" "); //NOTE: You may exclude this line to avoid adding trailing spaces
}
System.out.println(sb.toString());
}
Explanation:
On first iteration (line == 0) we take a single star,
*
and add zero extra stars (as our line# is zero) on both sides, which gives us (same string):
*
And then add n-line-1 (we substract 1 because we already added 1 character - the first star) = 3 spaces on each side of that star, which gives us:
...*...
On 2nd iteration (line == 1) if we apply same logic:
1.
*
***
^ This middle one is the first star
..***..
Pretty simple once you understand the logic.
There are multiple ways to do this, but these are among the simplest ones :)
Say you need to print a pyramid of n rows. You can see that row i (where i is between 1 and n) will start with n-i spaces and have (i-1)*2+1 asterisks:
for (int i = 1; i <= n; ++i) {
int spaces = n-i;
int stars = (i-1)*2+1;
for (int j = 1; j <= spaces; ++j) {
System.out.print(' ');
}
for (int j = 1; j <= stars; ++j) {
System.out.print('*');
}
System.out.println();
}
Here's my implementation -
public static String repeat(String str, int times) {
return new String(new char[times]).replace("\0", str);
}
public void createPyramid(int size) {
for (int i = 1; i <= size; i += 2) {
int numSpaces = (size - i) / 2;
System.out.println(repeat(" ", numSpaces) + repeat("*", i) + repeat(" ", numSpaces));
}
}
Call the method as - createPyramid(7); should give you the desired output. You can increase the size for bigger pyramid.
The variable i iterate for the size of the pyramid. And the number of stars on each row is increasing by 2 starting from 0. There i is incrementing by 2. The blank spaces will be equal to size - number of *'s but they have to be repeated before and after the *'s symmetrically, we divide it by 2. This will give the number of spaces before and after the *'s and in the middle we just need to print the *'s whose number is given by i.
So, we finally print them.
The repeat function creates a String formed from the str parameter repeated times times. eg - if we call repeat("abc", 3), it will return "abcabcabc".
Related
I have this task to display a pyramid as follows:
I wrote the code but unfortunately, the digits are displayed with spaces and order.
public class DisplayPyramid {
//main method declaration. Program entry point which begins its execution
public static void main(String[] args) {
//Create a Scanner object
Scanner input = new Scanner(System.in);
//Prompt the user to enter an integer (number of lines)
System.out.print("Enter the number of lines: ");
int numbers = input.nextInt(); //Read value from keyboard and assign it to numberOfLines
String padding = " ";
//Display pyramid
//for loop to produce each row
for (int rows = 0; rows < numbers ; rows++) {
for (int k = numbers - rows; k >= 1; k--){
System.out.print(k + " ");
}
for (int l = 2; l <= numbers - rows; l++){
System.out.print(" " + l);
}
//Advance to the next line at the end of each rows
System.out.print("\n");
}
} }
And this is my output:
Can you help me figure out what is wrong with code ?
Anyone's help will be much appreciated.
Consider the 1st pass of the outer loop which produces
If we color hint your code, which the first inner loop in red, the second inner loop in green
This will be their corresponding output for each pass
The last pass of the red loop print "1 " and the first pass of green loop print " 2". They combine and become "1 2", which has 2 spaces in between.
The solution as Osama A.R point out, just reverse the printing order of number and space for the green loop and make if follow the red loop pattern. That will make the sequence neat.
Your second for loop prints the spaces first and then the number, however, the spaces have already been added by the first for loop, so just update the second for loop to print the spaces after printing the number.
E.g. your second loop should be like this:
for (int l = 2; l <= numbers - rows; l++){
System.out.print(l + " ");
}
I am new to programming and I have an exercise that's killing me. How can you print a grid (5-by-6) which consists of asterisks alone? [Later on, these asterisks will have to be replaced by letters which are read in with StdIn.readInt() and a switch statement, but for now I at least need to understand how to print the grid]. I would appreciate any help so much!
More specifically, the grid should look like this:
//THIS ISN'T THE CODE; JUST AN ILLUSTRATION OF WHAT SHOULD BE PRINTED
0 1 2 3 4 5
0 * * * * * *
1 * * * * * *
2 * * * * * *
3 * * * * * *
4 * * * * * *
//I AM SUPPOSED TO START WITH SOMETHING LIKE THIS:
public class Grid {
static int X = 6;
static int Y = 7;
public static void main(String[]args) {
int [][] grid = new int [X][Y];
This could have been done in many ways, but this is my way of doing it:
When you want to print a grid, you have to use 2 nested for loops.
Let's see what happens when you use 2 nested for loops:
for(int i = 0; i < 6; i++){
for(int j = 0; j < 7; j++){
}
}
We start with the first loop:
for i = 0, we will enter the second loop and iterate from 0 to 6.
for i = 1, we will enter the second loop and iterate from 0 to 6.
...
for i = 5, we will enter the second loop and iterate from 0 to 6.
What you should notice is that j will iterate and take values from 0 to 6 with each value of i.
Going back to your question, and comparing it by what i just showed, you should notice that for each line, you are printing 7 values (of a column).
Let's assume i is the number of lines, and j is the index of each value in that line (column).
public static void printGrid() {
for (int i = 0; i < 6; i++) {
System.out.println();
for (int j = 0; j < 7; j++) {
System.out.print("*");
}
}
}
This code prints on each line (i), 7 asterixes (j).
And each time i is incrementing, we are going back to the next line System.out.println(). That's why we put it inside the for loop with i.
In your situation, we have to tweak this code a little bit to be able to print the numbers on the sides, and that space at the top left corner.
The explanation is in the comments in my code.
public class Question_55386466{
static int X = 6;
static int Y = 7;
public static void printGrid() {
System.out.print(" "); // Printing the space on the top left corner
for (int i = 0; i < X; i++) {
if (i > 0) { // Printing the numbers column on the left, taking i>0 to start from the second line (i == 1)
System.out.println(); // Going to the next line after printing the whole line
System.out.print(i - 1);//Printing the numbers of the column. Taking i-1 because we start the count for i == 1 not 0
}
for (int j = 0; j < Y; j++) {
if (i == 0)
System.out.print(j + " ");//Print the first line numbers.
else
System.out.print(" * "); //if the line isn't the first line(i == 0), print the asterixes.
}
}
}
You can always edit the values of X and Y and get the desired result.
And later you can give this method your array as a parameter and print each element instead of the asterixes.
Okay, I'm making a program that'll make vertical lines, horizontal lines, diagonals lines too! I'm kinda confused on one of my outputs that doesn't make any sense.
So my psudocode was like this:
//enter a char
//enter a number that will determine how long the line is
//define with easyreader what type of line it will be (hori, vert, diag)
//the idea of making the diag lines was this...
#
(two spaces) #
(four spaces) #
(six spaces) #
//we could use the sum spaces = spaces + 2; to keep on calculating what
//the previous spaces was
Code was:
class starter {
public static void main(String args[])
{
System.out.print("What char would you like? ");
EasyReader sym = new EasyReader();
String chars = sym.readWord();
System.out.print("How long would you like it to be? ");
int nums = sym.readInt();
System.out.print("Diag, Vert, or Hori? ");
//you want to read the __ varible, not the sym.readX()
String line = sym.readWord();
System.out.println("");
System.out.println("");
if(line.equals("Hori")){
for(int x = 0; x < nums; x++){
System.out.print(chars + " ");
}
}
else if(line.equals("Vert")){
for(int y = 0; y < nums; y++){
System.out.println(chars + " ");
}
}
else{
for(int xy = 0; xy < nums; xy++){
for(int spaces = 0; spaces < nums; spaces++){
spaces = spaces + 2;
System.out.print(spaces + " ");
System.out.println(chars);
}
}
}
}
}
At the bottom you will see a for loop called xy that will read how long the lines would be. Under that for loop would control the spaces. However, for some reason, the sum isn't updating correctly. The output is always:
2 (char)
5 (char)
8 (char)
2 (char)
5 (char)
8 (char)
...
The output should be:
2 (char)
4 (char)
8 (char)
...
EDIT **********
Since I need help now changing incriements here is an example (So I don't have to explain it a lot in comments)
Example: If user puts he wants the line as much as 5 units. With two for loops, one controlling how many spaces he wants, one controlling how many chars will print out, the output would be then 2, 4, 6, 8, 10.
In for loop statement, you say 'increase spaces by one after each iteration' (spaces++):
for(int spaces = 0; spaces < nums; spaces++){
In the body of your loop, you additionally ask to increase it by 2:
spaces = spaces + 2;
So each iteration it gets increased by 3.
By the way, there seems to be something wrong with your nested loops (if I understand the intention correctly). If the outer loop (looping over xy) draws a line on each iteration, then the inner loop, which is supposed to output an indent for the current line, must be bounded by xy (multiplied by 2) rather than nums. I'd write it like this:
for (int xy = 0; xy < nums; xy++) {
for (int spaces = 0; spaces < xy*2; spaces += 2) {
System.out.print(" ");
}
System.out.println(chars);
}
Because you are adding 3 to the spaces each time
for(int spaces = 0; spaces < nums; spaces++){
spaces = spaces + 2;
spaces++ spaces += 1
spaces = spaces + 2; spaces += 2
actually the problem is in this part :
for(int spaces = 0; spaces < nums; spaces++){
spaces = spaces + 2;
System.out.print(spaces + " ");
System.out.println(chars);
}
when the program starts we have spaces = 0
then this part is going to run spaces =spaces + 2
now spaces is equal to 2, so we have spaces = 2
the program prints 2, after that spaces increments by 1 using spaces++ part
now spaces is equal to 3, which means spaces=3
after that this line is going to be run spaces = spaces + 2
so the value of spaces becomes 5
and if we do this for ever and ever we will have this sequence of numbers :
2 5 8 11 14 ....
in fact this is because we are incrementing spaces by 3 in each iteration
if you modify your code in this form, the problem is going to be solved :
for (int xy = 0; xy < nums; xy++) {
for(int spaces = 0; spaces < xy*2; spaces += 2)
System.out.print(spaces + " ");
System.out.println(chars);
}
I need to produce a triangle as shown:
1
22
333
4444
55555
and my code is:
int i, j;
for(i = 1; i <= 5; i++)
{
for(j = 1; j <= i; j++)
{
System.out.print(i);
}
System.out.print("\n");
}
Producing a triangle the opposite way
1
22
333
4444
55555
What do i need to do to my code to make it face the right way?
You need 3 for loops:
Upper-level loop for the actual number to be repeated and printed
first inner level for printing the spaces
second inner level for to print the number repeatedly
at the end of the Upper-level loop print new line
Code:
public void printReversedTriangle(int num)
{
for(int i=0; i<=num; i++)
{
for(int j=num-i; j>0; j--)
{
System.out.print(" ");
}
for(int z=0; z<i; z++)
{
System.out.print(i);
}
System.out.println();
}
}
Output:
1
22
333
4444
55555
666666
I came across this problem in my AP CS class. I think you may be starting to learn how to program so heres what I'd do without giving you the answer.
Use a loop which removes the number of spaces each iteration. The first time through you would want to print four spaces then print 1 one time(probably done in a separate loop).
Next time through one less space, but print i one more time.
You need to print some spaces. There is a relation between the number of spaces you need and the number (i) you're printing. You can print X number of spaces using :
for (int k = 0; k < numSpaces; k++)
{
System.out.print(" ");
}
So in your code:
int i, j;
for(i = 1; i <= 5; i++)
{
// Determine number of spaces needed
// print spaces
for(j = 1; j <= i; j++)
{
System.out.print(i);
}
System.out.print("\n");
}
use this code ,
int i, j,z;
boolean repeat = false;
for (i = 1; i <= 5; i++) {
repeat = true;
for (j = 1; j <= i; j++) {
if(repeat){
z = i;
repeat = false;
while(z<5){
System.out.print(" ");
z++;
}
}
System.out.print(i);
}
{
System.out.print("\n");
}
}
You can use this:
int i, j;
int size = 5;
for (i = 1; i <= size; i++) {
if (i < size) System.out.printf("%"+(size-i)+"s", " ");
for (j = 1; j <= i; j++) {
System.out.print(i);
}
System.out.print("\n");
}
This line:
if (i < size) System.out.printf("%"+(size-i)+"s", " ");
Is going to print the left spaces.
It uses the old printf with a fixed sized string like 5 characters: %5s
Try it here: http://ideone.com/jAQk67
i'm having trouble sometimes as well when it's about formatting on console...
...i usually extract that problem into a separate method...
all about how to create the numbers and spacing has been posted already, so this might be overkill ^^
/**
* creates a String of the inputted number with leading spaces
* #param number the number to be formatted
* #param length the length of the returned string
* #return a String of the number with the size length
*/
static String formatNumber(int number, int length){
String numberFormatted = ""+number; //start with the number
do{
numberFormatted = " "+numberFormatted; //add spaces in front of
}while(numberFormatted.length()<length); //until it reaches desired length
return formattedNumber;
}
that example can be easily modified to be used even for Strings or whatever ^^
Use three loops and it will produce your required output:
for (int i=1;i<6 ;i++ )
{
for(int j=5;j>i;j--)
{
System.out.print(" ");
}
for(int k=0;k<i;k++)
{
System.out.print(i);
}
System.out.print("\n");
}
Your code does not produce the opposite, because the opposite would mean that you have spaces but on the right side. The right side of your output is simply empty, making you think you have the opposite. You need to include spaces in order to form the shape you want.
Try this:
public class Test{
public static void main (String [] args){
for(int line = 1; line <= 5; line++){
//i decreases with every loop since number of spaces
//is decreasing
for(int i =-1*line +5; i>=1; i--){
System.out.print(" ");
}
//j increases with every loop since number of numbers
//is decreasing
for(int j = 1; j <= line; j++){
System.out.print(line);
}
//End of loop, start a new line
System.out.println();
}
}
}
You approached the problem correctly, by starting with the number of lines. Next you have to make a relation between the number of lines (the first for loop) and the for loops inside. When you want to do that remember this formula:
Rate of change*line + X = number of elements on line
You calculate rate of change by seeing how the number of elements change after each line. For example on the first line you have 4 spaces, on the second line you have 3 spaces. You do 3 - 4 = -1, in other words with each line you move to, the number of spaces is decreasing by 1. Now pick a line, let's say second line. By using the formula you will have
-1(rate of change) * 2(line) + X = 3(how many spaces you have on the line you picked).
You get X = 5, and there you go you have your formula which you can use in your code as you can see on line 4 in the for loop.
for(int i = -1 * line +5; i >= 1; i--)
You do the same for the amount of numbers on each line, but since rate of change is 1 i.e with every line the amount of numbers is increasing by 1, X will be 0 since the number of elements is equal to the line number.
for(int j = 1; j <= line; j++){
I have to write a java program where the solution will include the printing of the arrow tip figure depending on the number of rows. Below are example of how the result should look. However, I cannot do this until I understand for loops. I know I have to work with the rows and columns and possibly nested loops. I just dont know how to connect the row with the columns using for loops. Please help me in understanding these loops. Thanks!
Example #1 (odd number of rows)
>
>>>
>>>>>
>>>>>>>
>>>>>
>>>
>
Example #2 (even number of rows)
>
>>>
>>>>>
>>>>>>>
>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>
>>>>>>>
>>>>>
>>>
>
a for loop will loop through a collection of data, such as an array. The classic for loop looks like this:
for(counter=0;counter <= iterations;counter++){ }
the first param is a counter variable. the second param expresses how long the loop should last, and the 3rd param expresses how much the counter should be incremented by after each pass.
if we want to loop from 1 - 10, we do the following:
for(counter=1;counter<=10;counter++){ System.out.println(counter); }
if we want to loop from 10 - 1, we do the following:
for(counter=10;counter>=1;counter--){ System.out.println(counter); }
if we want to loop through a 2 dimensional collection, like...
1 2 3
4 5 6
7 8 9
int[][] grid = new int[][] {{1,2,3},{4,5,6},{7,8,9}};
we need 2 loops. The outer loop will run through all the rows, and the inner loop will run through all the columns.
you are going to need 2 loops, one to iterate through the rows, one to iterate through the columns.
for(i=0;i<grid.length;i++){
//this will loop through all rows...
for(j=0;j<grid[i].length;j++){
//will go through all the columns in the first row, then all the cols in the 2nd row,etc
System.out.println('row ' + i + '-' + 'column' + j + ':' + grid[i][j]);
}
}
In the outer loop, we set a counter to 0 for the first parameter. for the second, to calculate how many times we will loop, we use the length of the array, which will be 3, and for the third param, we increment by one. we can use the counter, i, to reference where we are inside the loop.
We then determine the length of the specific row by using grid[i].length. This will calculate the length of each row as they are being looped through.
Please feel free to ask any questions you may have regarding for loops!
EDIT: understanding the question.....
You are going to have to do several things with your code. Here we will store the number of lines in a variable, speak up if you need to pass in this value to a method.
int lines = 10; //the number of lines
String carat = ">";
for(i=1;i<=lines;i++){
System.out.println(carat + "\n"); // last part for a newline
carat = carat + ">>";
}
The above will print out carats going all the way up. We print out the carat variable then we make the carat variable 2 carats longer.
.... the next thing to do is to implement something that will decide when to decrease the carats, or we can go up half of them and down the other half.
Edit 3:
Class Test {
public static void main(String[] args) {
int lines = 7;
int half = lines/2;
boolean even = false;
String carat = ">";
int i;
if(lines%2==0){even = true;} //if it is an even number, remainder will be 0
for(i=1;i<=lines;i++){
System.out.println(carat + "\n");
if(i==half && even){System.out.println(carat+"\n");} // print the line again if this is the middle number and the number of lines is even
if(((i>=half && even) || (i>=half+1)) && i!=lines){ // in english : if the number is even and equal to or over halfway, or if it is one more than halfway (for odd lined output), and this is not the last time through the loop, then lop 2 characters off the end of the string
carat = carat.substring(0,carat.length()-2);
}else{
carat = carat + ">>"; //otherwise, going up
}
}
}
}
Explanation and commentary along shortly. Apologies if this is over complicated (i'm pretty sure this is not even close to the best way to solve this problem).
Thinking about the problem, we have a hump that appears halfway for even numbers, and halfway rounded up for the odd numbers.
At the hump, if it is even, we have to repeat the string.
We have to then start taking off "<<" each time, since we are going down.
Please ask if you have questions.
I had the same question for a homework assignment and eventually came to a correct answer using a lot of nested if loops through a single for loop.
There is a lot of commenting throughout the code that you can follow along to explain the logic.
class ArrowTip {
public void printFigure(int n) { //The user will be asked to pass an integer that will determine the length of the ArrowTip
int half = n/2; //This integer will determine when the loop will "decrement" or "increment" the carats to String str to create the ArrowTip
String str = ">"; //The String to be printed that will ultimately create the ArrowTip
int endInd; //This integer will be used to create the new String str by creating an Ending Index(endInd) that will be subtracted by 2, deleting the 2 carats we will being adding in the top half of the ArrowTip
for(int i = 1; i <= n; i++) { //Print this length (rows)
System.out.print(str + "\n"); //The first carat to be printed, then any following carats.
if (n%2==0) { //If n is even, then these loops will continue to loop as long as i is less than n.
if(i <= half) { //This is for the top half of the ArrowTip. It will continue to add carats to the first carat
str = str + ">>"; //It will continue to add two carats to the string until i is greater than n.
}
endInd = str.length()-2; //To keep track of the End Index to create the substring that we want to create. Ultimately will determine how long the bottom of the ArrowTip to decrement and whether the next if statement will be called.
if((endInd >= 0) && (i >= half)){ //Now, decrement the str while j is greater than half
str = str.substring(0, endInd); //A new string will be created once i is greater than half. this method creates the bottom half of the ArrowTip
}
}
else { //If integer n is odd, this else statement will be called.
if(i < half+1) { //Since half is a double and the integer type takes the assumption of the one value, ignoring the decimal values, we need to make sure that the ArrowTip will stick to the figure we want by adding one. 3.5 -> 3 and we want 4 -> 3+1 = 4
str = str + ">>"; //So long as we are still in the top half of the ArrowTip, we will continue to add two carats to the String str that will later be printed.
}
endInd = str.length()-2; //Serves the same purpose as the above if-loop when n is even.
if((endInd >= 0) && (i > half)) { //This will create the bottom half of the ArrowTip by decrementing the carats.
str = str.substring(0, endInd); //This will be the new string that will be printed for the bottom half of the ArrowTip, which is being decremented by two carats each time.
}
}
}
}
}
Again, this was for a homework assignment. Happy coding.
Here is a simple answer for you hope it helps! Cheers Logan.
public class Loop {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
int count = i;
int j = 0;
while (j != count) {
System.out.print(">");
j++;
}
System.out.println();
}
for (int i = 10; i > 0; i--) {
int count = i;
int j = 0;
while (j != count) {
System.out.print(">");
j++;
}
System.out.println();
}
}
}
For making a 'for' loop:
public class Int {
public static void main(String[] args) {
for (Long num = 1000000L; num >= 9; num++) {
System.out.print("Number: " + num + " ");
}
}
}
Output:
Number: 1008304 Number: 1008305 Number: 1008306 Number: 1008307 ...