John Cena John Cena - 11 days ago 6
Java Question

Java Triangular kind of histogram

I need a bit of help with a project, I want to create a java program that creates a kind of histogram in the shape of triangles, its hard to explain so look at the following example

input : 3 1 12 0 7
output:

_
/|\
/ | \
/ | \
/ | \
/ | \ _
/ | \ /|\
/ | \ / | \
/ | \ / | \
_ / | \ / | \
/|\ / | \ / | \
/ | \ _ / | \ / | \
/ | \ /|\ / | \ _ / | \
<=======><===><=========================><=><===============>
| | | | | | | | |


in my code I've managed to create the input part, and the generator of the base, but the triangles/piramides generator doesnt make the correct spaces, anyone can help me?
here is my code to make the triangles (assuming the input is what is in the array numbers and numbers2):

public class Spires{
public static void main(String[] args){
int[] numbers = {3,1,12,0,7};
int counter = 6, max = 12;
int[] numbers2 = {3,1,12,0,7};

for(int row = max+1; row >= 0; --row) {
System.out.println();
for(int col = 0; col < counter-1; ++col) {
if(numbers2[col] >= row){
for(int spacesleft = 1; spacesleft < (numbers2[col] + col)+row-1; ++spacesleft){
System.out.print(" ");
}
if(numbers2[col] != row){
System.out.print("/");
for(int c3 = 0; c3 < numbers2[col]-row-1; ++c3) {
System.out.print(" ");
}
System.out.print("|");
for(int c3 = 0; c3 < numbers2[col]-row-1; ++c3) {
System.out.print(" ");
}
System.out.print("\\");

}else{
System.out.print("_");
}
// for(int spacesright = 1; spacesright < numbers2[col] + col + row -1; ++spacesright){
// System.out.print(" ");
// }
}
}
}
System.out.println();
//base generator
for(int i = 0; i<counter-1; ++i) {
System.out.print("<");
for(int i2 = 0; i2 < 2*numbers[i]+1; ++i2) {
System.out.print("=");
}
System.out.print(">");
}
System.out.println();

for(int i = 0; i<counter-1; ++i) {
if(numbers[i] != 0){
System.out.print(" |");
for(int i2 = 0; i2 < 2*numbers[i]-1; ++i2) {
System.out.print(" ");
}
System.out.print("| ");
}else{
System.out.print(" | ");
}
}
}
}


My output comes out like this:

_
/|\
/ | \
/ | \
/ | \
/ | \ _
/ | \ /|\
/ | \ / | \
/ | \ / | \
_ / | \ / | \
/|\ / | \ / | \
/ | \ _ / | \ / | \
/ | \/|\ / | \ _ / | \
<=======><===><=========================><=><===============>
| | | | | | | | |


I need some help figuring out how to add the missing spaces and remove some

Answer

You're almost there! Just a couple tweaks that need to be made.

  1. The calculation for number of outside spaces on the left and right side of the triangle legs is actually very simple: row + 1. Because each triangle is being built from the bottom up, triangles shown on row 0 (bottom row) need 1 space, row 1 need 2 spaces, etc.
  2. If the current row is "above" the triangle column you are displaying, you still need to output spaces to mark a placeholder for that triangle. So the if (numbers2[col] >= row) needs a corresponding else to display spaces instead.

Applying these two changes gets something like:

 if(numbers2[col] >= row){

    //            corrected calculation \-------/
    for(int spacesleft = 0; spacesleft < row + 1; ++spacesleft){
        System.out.print(" ");
    }

     if(numbers2[col] != row){
         System.out.print("/");
         for(int c3 = 0; c3 < numbers2[col] - row - 1; ++c3) {
             System.out.print(" ");
         }
         System.out.print("|");
         for(int c3 = 0; c3 < numbers2[col] - row - 1; ++c3) {
             System.out.print(" ");
         }
         System.out.print("\\");

     }else{
         System.out.print("_");
     }

     //              corrected calculation \-------/
     for(int spacesright = 0; spacesright < row + 1; ++spacesright){
         System.out.print(" ");
     }

 // output spaces to fill area for that column and shift everything over properly
 } else {
    for (int spaces = 0; spaces < numbers2[col] * 2 + 3; spaces++)
        System.out.print(" ");
 }

This should output the histogram as expected.


Now I'd like you to consider why this code is challenging to work with. There is a direct relationship to the number of variables and ideas you have to hold in your head at once, to the difficulty of reading and understanding a piece of code.

One way you could make this code easier to reason about is by breaking it up into different functions that handle different aspects of the problem individually. For example, we might add methods for:

  1. printing a certain number of spaces
  2. printing one row of a triangle

Also it helps to use more variables with intuitive names, so you don't have to keep reasoning through the entire calculations. Here is an example that should demonstrate:

// output 'count' spaces
public static void printSpaces(int count) {
    for (int spaces = 0; spaces < count; spaces++) System.out.print(" ");
}

// output one row of a triangle based on supplied height
// and current display row, starting at 0=top row.
public static void printTriangleSection(int triangleHeight, int rowOfTriangle) {

    int triangleWidth = triangleHeight * 2 + 3; // total width taken up by this triangle
    int halfWidth = triangleHeight + 1;     // total width taken up by one side (excluding the middle)

    int spacesOutside = halfWidth - rowOfTriangle;  // total spaces outside of triangle hypotenuse
    int spacesInside = rowOfTriangle - 1;           // total spaces inside triangle hypotenuse

    if (rowOfTriangle < 0) {        // above the first row of the triangle
        printSpaces(triangleWidth);
    } else if (rowOfTriangle == 0) {
        printSpaces(spacesOutside);
        System.out.print("_");
        printSpaces(spacesOutside);
    } else {
        printSpaces(spacesOutside);
        System.out.print("/");
        printSpaces(spacesInside);
        System.out.print("|");
        printSpaces(spacesInside);
        System.out.print("\\");
        printSpaces(spacesOutside);
    }
}

Then the relevant part of your main method would simplify to this:

for(int row = max+1; row >= 0; --row) {
   System.out.println();
   for(int col = 0; col < counter-1; ++col) {
       printTriangleSection(numbers2[col], numbers2[col] - row);
   }
}
Comments