Java - How to create alternating triangle pyramid? - java

I am trying to create a triangle pyramid of alternating "*" and "o" characters, with the number of rows being based on user input. The expected output I am trying to achieve, if the user inputs "6" for the number of rows, is:
*
*o*
*o*o*
*o*o*o*
*o*o*o*o*
*o*o*o*o*o*
The code I have written to achieve this is:
String star = "*";
String circle = "o";
System.out.println("Please enter number of rows: ");
int rows = in.nextInt();
for (int i = 0; i < rows; i++){
for (int j = 0; j < rows-i; j++){
System.out.print(star);
}
for (int k = 0; k <= i; k++){
System.out.print(circle);
}
System.out.println();
}
However, the output from my code does not match the pyramid above. The output of my code, with a user input of "6", is:
******o
*****oo
****ooo
***oooo
**ooooo
*oooooo
After spending the last three hours scouring both this website and others, I have still come up lost on how to alternate the characters, how to have the correct number of characters in each row, and how to format the pyramid as the expected output is. I don't know if my code is completely wrong, or if I am only missing a part to make it work correctly, but any advice or references is greatly appreciated.

You could approach it another, far simpler, way.
In pseudo code:
create a String of n spaces
add "*" to it
loop n times, each iteration of the loop:
print it
replace " *" with "*O*"
This recognises a simple way to create the first line, and a simple way to create the next line from the previous line. Each replacement will match only the last (leading) space and the first star, replacing the space with a star, the star with an O and adding a star.
Usually the best way to solve a hard problem is to look at it in a way that makes it a simple problem (or a collection of simple problems).
A couple of ways to create a String of n spaces:
A loop that adds ' ' each iteration
new String(new char[n]).replace('\0', ' ')
How to replace certain characters of a String with other characters:
str = str.replace(" *", "*O*");

This method will work fine:
public void printPyramid (int input) {
for (int row = 1; row <= input; row++) {
for (int whitespace = input - 1; whitespace >= row; whitespace--) {
System.out.print(" ");
}
System.out.print("*");
for (int circle = 1; circle < row; circle++) {
System.out.print("o*");
}
System.out.println();
}
}
*
*o*
*o*o*
*o*o*o*
*o*o*o*o*
*o*o*o*o*o*
*o*o*o*o*o*o*
*o*o*o*o*o*o*o*
*o*o*o*o*o*o*o*o*
*o*o*o*o*o*o*o*o*o*
*o*o*o*o*o*o*o*o*o*o*
*o*o*o*o*o*o*o*o*o*o*o*
*o*o*o*o*o*o*o*o*o*o*o*o*
*o*o*o*o*o*o*o*o*o*o*o*o*o*
*o*o*o*o*o*o*o*o*o*o*o*o*o*o*
*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*
*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*
*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*
*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*
*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*
*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*o*

Welcome to Stack Overflow!
First, the "o"s and "*"s are not alternating because the for loops execute until completion. This means the stars and circles will print out separately. For this application you only need one for loop and two if statements based on whether the "i" in the for loop is odd or even. An easy way to do this is with the modulo function :
String star = "*";
String circle = "o";
System.out.println("Please enter number of rows: ");
int rows = in.nextInt();
for (int i = 0; i < rows; i++){
if ((i % 2) == 0)
{
System.out.print(circle);
}
else
{
system.out.print(star);
}
System.out.println();
}
See if that works.
Thanks!

Here is a solution, easy to understand and friendly for beginners.
(If you want to go more advanced, look at the solution from #Bohemian♦ )
String star = "*";
String circle = "o";
System.out.println("Please enter number of rows: ");
int rows = in.nextInt();
for (int i = 0; i < rows; i++){
// How many "o" do we need?
int count_circle = i;
// How many * do we need?
int count_star = count_circle + 1;
// Let's create the string with o and *
String output = "";
for(int j = 0; j < (count_circle + count_star); j++){
if(j % 2 == 0) // if it is odd
output = output + star;
else // if it is even
output = output + circle;
}
// Do we need spaces at the beginning?
String spaces = "";
for(int j = 0; j < rows - i - 1; j++){
spaces = spaces + " ";
}
// Final output
output = spaces + output;
System.out.println(output);
}

Try this.
Scanner in = new Scanner(System.in);
System.out.println("Please enter number of rows: ");
int rows = in.nextInt();
for (int i = 0; i < rows; ++i) {
System.out.printf("%" + (rows - i) + "s", "*");
for (int j = 0; j < i; ++j)
System.out.print("o*");
System.out.println();
}

Ex:
If rows=3
*##
**#
***
class Main{
public static void main(String x[]){
Scanner scan=new Scanner(System.in);
int rows=scan.nextInt();
for(int i=1;i<rows;i++){
for (int j=0;j<i;j++)
{
System.out.print("*");
}
for (int j=rows;j>i;j--)
{
System.out.print("#");
}
System.out.println();
}
}
}
See if that works.
Thanks!

Related

not getting correct input for checking for duplicates

for the problem, i am required to take in 10 integers, and then print out the unique numbers. My problem solving approach for this was to scan all the numbers behind the one we are checking to see if there are any duplicates. here's the code I have so far. if i enter in numbers like "1234567891", it only will print "pl: 1" because I add the first number before running the algorithm. Any hypothesis on why it's not working?
//setup
Scanner input = new Scanner(System.in);
String text = input.nextLine();
text = text.replaceAll("\\s",""); //remove all spaces
int[] intDigits = new int[10];
//turn the string into an int array
for (int i = 0; i < 10; i++){
intDigits[i] = text.charAt(i) - '0';
}
input.close();
//add the first number since it will always be unique with my algorithm
String pl = intDigits[0] + " ";
//check every number behind the one we are checking, if all the numbers are not equal to the one we are checking, then add it to the string of unique numbers.
for (int i = 1; i < 10; i++) {
int count = 0;
for (int j = i-1; j >= 0; j--) {
if (intDigits[i] != intDigits[j]) {
count++;
}
}
if (count == i-1) {
pl += intDigits[i];
}
}
System.out.println("\n\npl: " + pl);
The issue is with if (count == i-1). Instead it should be if (count == i).Since you are checking from index 1, count will be 1(j=0) if no duplicate. Similarly, for i=2 count will be 2(j=1,0) if no duplicate. And same for the rest.

How to dynamically format Strings in Java

The following program prints the multiplication table 9xN which N is given by the user. My cells are fixed to be aligned only when the product is 2 numbers long.
What can I do so the cells will be aligned with any size of numbers?
public static void main(String[] args) {
//Reading the number n.
System.out.print("Give a number: ");
int n = StdIn.readInt();
//Validating the number.
while(n<1) {
System.out.println("Please give a number greater or equal to 1");
n = StdIn.readInt();
}
/*---------------------------------
*
*Lines 27-36 -> Creating the first
*line and the first line's design.
*
----------------------------------*/
for (int i = 1; i <= n; i++) {
System.out.printf(" %-4d", i);
}
System.out.println();
System.out.print(" +");
for (int i = 1; i <= n; i++) {
System.out.print("-------+");
}
System.out.println();
/*----------------------------------
*
*Lines 45-58 -> Printing the product
*of the numbers and the design of
*the table.
*
----------------------------------*/
for (int i = 1; i <=9 ; i++) {
System.out.print(i + " | ");
for (int j = 1; j <= n; j++) {
int a = (i * j);
String b = " | ";
System.out.printf("%2d %s", a, b);
}
System.out.println();
System.out.print(" +");
for (int k = 1; k <= n; k++) {
System.out.print("-------+");
}
System.out.println();
}
}
}
What can I do so the cells will be aligned with any size of numbers?
Not Aligned Cells
Aligned Cells
Thanks in advance.
To expand #Thomas Weller's comment a little, you need to separate the table cell value calculation loop from the table printing loop because you need to know the maximum number of digits in any cell before you start printing out the table so the 2 in %2d can be that max value instead.
EDIT: You will also need to know that max value in order to create the correct cell width instead of hard coding "-------+"

Printing spaces to align numbers according to my pyramid pattern

It sounds a lot easier than it looks. Basically I have my code finished this is my output where the leading number is whatever integer the program receives as input. In this case n = 5:
1
21
321
4321
54321
but this is what it is suppose to look like:
1
2 1
3 2 1
4 3 2 1
5 4 3 2 1
How should I go about adding spaces in between my numbers while maintaining this pattern? I've tried editing here and there but it keeps coming out like this:
1
2 1
3 2 1
4 3 2 1
5 4 3 2 1
My code:
import java.util.Scanner;
public class DisplayPattern {
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
System.out.print("Enter an integer and I will display a pattern for you: ");
int n = input.nextInt();
displayPattern(n);
}
public static void displayPattern(int n) {
final int MAX_ROWS = n;
for (int row = 1; row <= MAX_ROWS; row++) {
for (int space = (n - 1); space >= row; space--) {
System.out.print(" ");
}
for (int number = row; number >= 1; number--) {
System.out.print(number + " "); /*<--- Here is the edit.*/
}
System.out.println();
}
}
Edit:
#weston asked me to display what my code looks like with the second attempt. It wasn't a large change really. All i did was add a space after the print statement of the number. I'll edit the code above to reflect this. Since it seems that might be closer to my result I'll start from there and continue racking my brain about it.
I managed to get the program working, however this only caters to single digit number (i.e. up to 9).
import java.util.Scanner;
public class Play
{
public static class DisplayPattern
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
System.out.print("Enter an integer and I will display a pattern for you: ");
int n = input.nextInt();
displayPattern(n);
}
public static void displayPattern(int n)
{
final int MAX_ROWS = n;
final int MAX_COLUMNS = n + (n-1);
String output = "";
for (int row = 1; row <= MAX_ROWS; row++)
{
// Reset string for next row printing
output = "";
for (int space = MAX_COLUMNS; space > (row+1); space--) {
output = output + " ";
}
for (int number = row; number >= 1; number--) {
output = output + " " + number;
}
// Prints up to n (ignore trailing spaces)
output = output.substring(output.length() - MAX_COLUMNS);
System.out.println(output);
}
}
}
}
Works for all n.
In ith row print (n-1 - i) * length(n) spaces, then print i+1 numbers, so it ends with 1 separated with length(n) spaces.
public static void printPiramide(int n) {
int N = String.valueOf(n).length();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n - 1 - i; j++) {
for (int k = 0; k < N; k++)
System.out.print(" ");
}
for (int j = i+1; j > 0; j--) {
int M = String.valueOf(j).length();
for (int k = 0; k < (N - M)/2; k++) {
System.out.print(" ");
}
System.out.print(j);
for (int k = (N - M)/2; k < N +1; k++) {
System.out.print(" ");
}
}
System.out.println();
}
}
public class DisplayPattern{
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter an integer and I will display a pattern for you: ");
int n = input.nextInt();
List<Integer> indentList = new ArrayList<Integer>();
int maxLength= totalSpace(n) + (n-1);
for(int i = 1; i <= n; i++ ){
int eachDigitSize = totalSpace(i);
int indent = maxLength - (eachDigitSize+i-1);
indentList.add(indent);
}
for(int row = 1; row<=n; row++){
int indentation = indentList.get(row-1);
for(int space=indentation; space>=0; space--){
System.out.print(" ");
}
for(int number = row; number > 0; number--){
System.out.print(number + " ");
}
System.out.println();
}
}
private static int totalSpace(int n) {
int MAX_ROWS = n;
int count = 0;
for(int i = MAX_ROWS; i >= 1; i--){
int currNum = i;
int digit;
while(currNum > 0){
digit=currNum % 10;
if(digit>=0){
count++;
currNum = currNum/10;
}
}
}
return count;
}
}
It works properly for any number of rows(n).
java-8 solution to the problem:
IntStream.rangeClosed(1, MAX)
.forEach(i -> IntStream.range(0, MAX)
.map(j -> MAX - j)
.mapToObj(k -> k == 1 ? k + "\n" : k <= i ? k + " " : " ")
.forEach(System.out::print)
);
Output for MAX = 5:
1
2 1
3 2 1
4 3 2 1
5 4 3 2 1
For the bottom row, you have the right number of spaces. But for the next row from the bottom, you're missing one space on the left (the 4 is out of line by 1 space). In the next row up, you're missing two spaces on the left (the 3 is out of line by 2 spaces)... and so on.
You're adding a number of spaces to the beginning of each line, but you're only taking into account the number of digits you're printing. However, you also need to take into account the number of spaces you're printing in the previous lines.
Once you get that part working, you might also consider what happens when you start to reach double-digit numbers and how that impacts the number of spaces. What you really want to do is pad the strings on the left so that they are all the same length as the longest line. You might check out the String.format() method to do this.

Stopping a for loop without using break

I'm trying to write a program that prints all substrings of entered string. For example if user enter "rum" the output will be this:
r
u
m
ru
um
rum
import java.util.Scanner;
public class AllSubStrings
{
public static void main(String[]args)
{
Scanner in = new Scanner(System.in);
System.out.print("Enter a string: ");
String str = in.next();
String sub = "";
for(int i=0; i<str.length(); i++)
{
for(int a=0; a<str.length() ; a++)
{
if(i+a+1>str.length())break;
sub = str.substring(a,i+a+1);
System.out.println(sub);
}
}
}
}
This program works perfectly but since we didn't learn how to use "break" in classes, i'm looking for something different. Any idea apart from "break" are welcome.
Thanks in advance.
You can use this while loop cycle instead of for:
int a = 0;
while (a < str.length && i + a < str.length()) {
sub = str.substring(a, i + a + 1);
System.out.println(sub);
a++;
}
Also it is possible to replace break with return statement
Calculate how many possible substrings there can be for a certain length. For example, length 1 = 1 substring, length 2 = 3, length 3 = 6, and so on.
Then loop for that many times. There should be a generic formula you can use for no matter how long of an input string.
You don't need a break to do this task.
int len = str.length();
for (int i = 0; i < len; i++) {
for (int j = i; j < len; j++) {
System.out.println( str.substring( i, j + 1 ) );
}
}
You can have two conditions in the for loop
for(int a = 0; a < str.length() && i + a < str.length(); a++)
{
sub = str.substring(a,i+a+1);
System.out.println(sub);
}
Note that i + a + 1 <= str.length() is the same as i + a < str.length()

How to reverse a string of numbers in a nested loop

This is a homework question so I would like help, not an answer.
I'm trying to create 2 triangles out of numbers based on a number entered by the user.
"Enter a number between 2-9: "3"
1
12
123
1
21
321
IE2:
"Enter a number between 2-9: "5"
1
12
123
1234
12345
1
21
321
4321
54321
I have been able to get the first triangle complete. But when I add my nested loop it messes up my first triangle with the numbers developed from the nested loop. It also puts all the numbers in a straight vertical line. I've tried variations for different nest loops and even tried messing with a StringBuilder, but was still unsuccessful.
Here's what I have in code so far:
import java.util.Scanner;
public class NestedLoops
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
System.out.print("Enter a Number between 2-9: ");
int width = input.nextInt();
String r = "";
for (int i = 1; i <= width; i++)
{
r = r + i;
System.out.println(r);
}
}
}
Again, I'm looking for help/understanding and not just an answer.
There are two aspects the 2nd part of the question.
You need to generate strings with the numbers in the reverse order:
You could do this by adding the numbers at the other end.
You could do this by reversing the strings.
You need to arrange that there are spaces to the left.
You could do this by adding the required number of spaces to the left end of the string.
You could do this by using the System.out.format(...) with a template that right aligns the string in a field with the required number of characters. (OK, that's a bit too obscure ...)
Or, you can build the string in a character array or string builder rather than using string concatenation.
The "trick" is to figure out what strategy you are going to use ... before you start cutting code.
try
int width = 5;
// for all lines; number of lines = width
for (int line = 1; line <= width; line++) {
// print numbers from 1 to current line number
for (int n = 1; n <= line; n++) {
System.out.print(n);
}
// end of line
System.out.println();
}
// add empty line between triangles
System.out.println();
// for all lines; number of lines = width
for (int line = 1; line <= width; line++) {
// printing padding spaces, number of spaces = with - line number
int nSpaces = width - line;
for (int i = 0; i < nSpaces; i++) {
System.out.print(" ");
}
// print numbers from number of current line to 1
for (int n = line; n >= 1; n--) {
System.out.print(n);
}
// end of line
System.out.println();
}
Can you just add another loop after your first loop like
String r = "";
String space = "";
for (int i = width; i >= 1; i--)
{
r = r + i;
System.out.println(r);
}
Try it. not yet tested
You need to use a queue.
eg. http://docs.oracle.com/javase/1.5.0/docs/api/java/util/LinkedList.html
Enque the numbers till you reach the max, and then start dequing them.
And while you dequeue, you need to apply the reverse
Queue<String> q = new LinkedList<String>();
for (int i = 1; i <= width; i++)
{
r = r + i;
q.add(r);
System.out.println(r);
}
while(!q.isEmpty()){
String j = q.remove();
//reverse j
System.out.println(reverse(j));
}
I leave the reversing part for you to do :)
public static void main(String[] args)
{
int n = 5;
for(int i=1; i<=n; i++)
{
for (int j=(n*2), k=n; j>1; j--)
{
if (k <= i)
{
System.out.print(k);
}
else
{
System.out.print('*');
}
k += (j)-1 > n ? -1 : 1;
}
System.out.println();
}
}
Just tried to implement in scala. Ignore if you don't like it..:-)
class Triangle extends App
{
val width = Console.readInt()
if (width < 2 || width > 9)
{
throw new RuntimeException()
}
var i, j = 1;
for (i <- 1 to width)
{
for (j <- 1 to i)
{
print(j)
}
print("\n")
}
for (i <- 1 to width)
{
for (dummy <- 1 to width-i)
{
print(" ")
}
for (j <- i to 1 by -1)
{
print(j)
}
print("\n")
}
}

Categories