I am looking to make a diamond like this:
n=2
*
*$*
*
n=3
*
*$*
*$*$*
*$*
*
n=4
*
*$*
*$*$*
*$*$*$*
*$*$*
*$*
*
I can get the diamond with just * but cannot figure out how to add the $ in the mix
My code is as follows:
import java.util.Scanner;
public class ForNestedDemo
{
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Please input number of lines:");
int i = 0, j, k, n;
n = scan.nextInt();
for (k = 1; k <= (n + 1) / 2; k++) {
for (i = 0; i < n - k; i++) {
System.out.print(" ");
}
for (j = 0; j < k; j++) {
System.out.print("*$ ");
}
System.out.println("");
}
for (k = ((n + 1) / 2); k < n; k++) {
for (i = 1; i < k; i++) {
System.out.print(" ");
}
for (j = 0; j < n - k; j++) {
System.out.print(" *");
}
System.out.println("");
}
scan.close();
}
}
I agree that #GhostCat is the easiest way to go, but just for fun I figured it out using your way.
for (k = 1; k < (n + 1); k++) {
for (i = 0; i < n - k; i++) {
System.out.print(" ");
}
for (j = 0; j < k; j++) {
if(j == 0)
if(k == n+1)
System.out.print("*");
else
System.out.print(" *");
else{
System.out.print("$*");
}
}
System.out.println("");
}
for (k = 1; k < n; k++) {
for (i = 0; i < k; i++) {
System.out.print(" ");
}
for (j = 0; j < n - k; j++) {
if(j == 0)
if(k == n+1)
System.out.print("*");
else
System.out.print(" *");
else{
System.out.print("$*");
}
}
System.out.println("");
}
I have fixed some of your errors and added some checks in there also.
The logic I have in place is:
If you are the first character, are you the middle row (k == n+1), if so, only print *, otherwise print _*.
If you are not the first character, print $*.
After that I just simply took my logic and pasted it down below in your lower half loop.
A simply way would be: instead of directly printing those "patterns", push them into string variables first - without thinking about $ signs. Just put the required spaces and *s into those strings.
Like:
" *"
" **"
"***"
Then, take those strings, and build the final strings from them: walk through each string, and when you find that str[index] and str[index+1] are '*' you simply put "*$" into your result string (otherwise you just copy the character at index).
Using that algorithm, the above strings turn into
" *"
" *$*"
"*$*$*"
And finally, you simply *copy** the upper lines down!
For the record: of course there are easy solutions that create the whole output in one shoot. But: you already got the loops in place that build lines that just miss the $ chars. So you can use my approach go get from your current code to a working solution easily.
You could do it as follows:
1. first print spaces
2. then print alternate '*' and '$' as per the order of the line.
public void printDiamonds(int n) {
//print the top part
for (int i = n-1; i > 0 ; i--) {
printDiamondLine(n, i);
}
//print the bottom part
for (int i = 0; i < n; i++)
printDiamondLine(n, i);
}
private void printDiamondLine(int n, int i) {
// i denotes the number of preceding spaces per line
for (int j=i; j>0; j--)
System.out.print(" ");
// print alternate * and $
for (int k=2*(n-i)-1; k>0; k--)
if (k%2==0)
System.out.print("$");
else
System.out.print("*");
System.out.println(); //print a new line at the end
}
Since this seems like homework, I normally wouldn't give the full code. But, the cat's out of the bag.
I would try to think of things in a simple mathematical manner and carefully look at the relationships between spaces, *s, and $s. When you do the code may come a little easier to write, simple, and cleaner.
There are always as many *s in a row as the row number
There are always one less as many $s as there are *s
There are always n - rowNum spaces in a row precedings the first character
There is a top, middle, and bottom to the shape based on these characteristics
Given that, I would start by writing a solution that would be easy to debug and very clean. The interesting part of my main would reflect the characteristics of the shape listed above:
printTop(1, 1, n);
printMiddle(n);
printBottom(n - 1, n - 1, n);
These methods would be defined as follows:
public static void printTop(int i, int j, int n) {
for (; n - j > 0; ++i, ++j) {
printLine(n - j, i);
}
}
public static void printMiddle(int stars) {
printLine(0, stars);
}
public static void printBottom(int i, int j, int n) {
for (; i >= 0; --i, --j) {
printLine(n - j, i);
}
}
The printLine() method prints a line/row of the shape given a number of spaces and *s. This is the part I would normally leave out but...
public static void printLine(int spaces, int stars) {
printSpace(spaces);
for (int i = 1; i <= (2 * stars - 1); ++i) {
if (i % 2 == 0) {
System.out.print('$');
} else {
System.out.print('*');
}
}
System.out.println();
}
I'm certain you can figure out what printSpace() is doing.
The benefit of this approach is it leads you towards what is inevitably going to be a primary goal of yours: decompose and modularize your code. This will become increasingly important as solutions become more complex. Good luck.
public static void main(String[] args) {
int n = 2;
int mid = (int) Math.ceil((n+n-1)/2.0);
String[] stringArray = new String[n];
for(int i = 0 ; i < n ; i++) {
StringBuilder sb = new StringBuilder();
for(int j = 2*i+1; j > 0; j--) {
if(j%2 == 0)
sb.append("$");
else
sb.append("*");
}
stringArray[i] = sb.toString();
}
for(int i = 0 ; i < n ; i++) {
for(int j = mid - stringArray[i].length()/2; j >0 ;j--) {
System.out.print(" ");
}
System.out.print(stringArray[i] + "\n");
}
for(int i = n-2 ; i >= 0 ; i--) {
for(int j = mid - stringArray[i].length()/2; j >0 ;j--) {
System.out.print(" ");
}
System.out.print(stringArray[i] + "\n");
}
}
Here you go. This code is not optimized in any way. Hope this gives you a general idea.
Related
I have recently started java, so I unfortunately am terrible at this. I have an question about a for loop question that was asked in my class today, but I can't figure out a part of it.
We were supposed to print out:
__1__
_333_
55555
with only for loops.
I have started the code but can't figure out what to do to print out the numbers, though I figured out the spaces.
public class Question{
public static void main(String [] args){
for(int j=1; j<=3;j++){
for(int i=1; i<=3-j; i++){
System.out.print(" ");
}
for(int k=?; k<=?; k??){
System.out.print(???);
}
for(int m=1; m<=3-j; m++){
System.out.print(" ");
}
System.out.println();
}
The question mark are the place where I don't know what goes in there.
Thanks.
You can do something like this,
class Main {
public static void main(String[] args) {
int i, j, k;
for (i = 1; i <= 3; i++) {
for (j = 2; j >= i; j--) {
System.out.print("_");
}
for (k = 1; k <= (2 * i - 1); k++) {
System.out.print(i * 2 - 1);
}
for (j = 2; j >= i; j--) {
System.out.print("_");
}
System.out.println();
}
}
}
The first for loop will print the _ before the number, second one will print the number and 3rd one will print the _ after the number
The values are changing by two each time j increments, that leads to the formula 1 + (2 * (j - 1)) which is how you can finish your loops. Like,
for (int j = 1; j <= 3; j++) {
for (int i = 1; i <= 3 - j; i++) {
System.out.print(" ");
}
int n = 1 + (2 * (j - 1));
for (int k = 1; k <= n; k++) {
System.out.print(n);
}
for (int m = 1; m <= 3 - j; m++) {
System.out.print(" ");
}
System.out.println();
}
Outputs
1
333
55555
Thanks everyone for helping. I figured out the answer.
public class Welcome {
public static void main(String [] args){
for(int j=1; j<=3;j++){
for(int i=1; i<=3-j; i++){
System.out.print(" ");
}
for(int k=1; k<=(2*j-1); k++){
System.out.print(2*j-1);
}
for(int m=1; m<=3-j; m++){
System.out.print(" ");
}
System.out.println();
}
}
}
This can also be achieved as below
public class ForLoopPrinter {
public static void main(String[] args) {
int number = 1;
int row = 3;
int column = 5;
char space = '_';
for(int i = 1; i <= row; i++){
for(int j = 1; j <=column;j++){
int offset = (column - number)/2;
if( j <= offset ||
j > (number + offset)){
System.out.print(space);
}else{
System.out.print(number);
}
}
System.out.println();
number += 2;
}
}
}
Here number of For loops are limited to 2 (one for row and one for column).
Logic goes like this -
offset provides you number of spaces to be printed at both sides of number.
first if condition checks if j (position) is below or above offset and if true it prints underscore and if false it prints number
I know that right answer has been given for this question and it will work like charm. I just tried to optimise code by reducing number of For Loops in answers provided before. Reduction of For loop will improve performance.
Apart from reduction of For loops, this code has following advantage
- This code is more scalable. Just change row, column values (e.g. 5,9) or space char to '*' and check output. You can play with it.
I would suggest you to go with answer given by #Sand to understand For loop and then check this answer to understand how you can optimise it.
I am a newbie to java programming and I am working on this excercise from my textbook. The goal is to print a V shape pattern of numbers. From the picture below, you can see what the output should look like. I am having trouble creating the other half of numbers. I have pasted my code down below for reference.
for (int i = 7; i >= 1; i--) {
for (int j = 1; j <= i; j++) {
System.out.print(" ");
}
System.out.print(i);
for (int k = 1; k >= i*2; k++) {
System.out.print(" ");
}
System.out.println(i);
Use the following code (just made a few modifications to your code, did not check its efficiency):
public static void main(String[] args) {
for (int i = 7; i >= 1; i--) {
for (int k = 7; k >= i; k--) {
System.out.print(" "); // Print 7-i number of spaces before start of each line
}
System.out.print(i); // Print i
for (int j = 1; j <= i*2; j++) {
System.out.print(" "); // Print i*2 number of spaces after printing i
}
System.out.println(i); // Print i
}
}
Rather then nesting loops (and iterating backwards), I would decompose the generating of white-space with a method to repeat a given String a given number of times. Like,
private static String repeat(String s, int n) {
return Stream.generate(() -> s).limit(n).collect(Collectors.joining());
}
Then I would prefer a StringBuilder and a single call to println like
public static void main(String[] args) {
int start = 6;
for (int i = 0; i < start; i++) {
int v = start - i;
StringBuilder sb = new StringBuilder();
sb.append(repeat(" ", i)).append(v);
sb.append(repeat(" ", 2 * v)).append(v);
System.out.println(sb);
}
}
I need to create a nested for loops that gives the following output,
0
1
2
3
This is what I have, but for the second test, userNum is replaced by 6 and obviously my code fails.. help?
public class NestedLoop {
public static void main (String [] args) {
int userNum = 0;
int i = 0;
int j = 0;
for(i = 0; i <= userNum; i++){
System.out.println(i);
for(i = 1; i <= userNum; i++){
System.out.println(" " +i);
for(i = 2; i <= userNum; i++){
System.out.println(" " +i);
for(i = 3; i <= userNum; i++){
System.out.println(" " + i);
}
}
}
}
return;
}
}
I think (it's a guess, though) that you're looking for this.
public static void main (String [] args)
{
int limit = 6;
for(int i = 0; i <= limit; i++)
{
for(int j = 0; j < i; j++)
System.out.print(" ");
System.out.println(i);
}
}
The reason why your approach fails is, as I see it, that you are looping through the numbers to show (which is right) but you fail to loop up on the number of spaces (which I resolved by relating the inner loop's limit to the outer loop's current value.
Let's talk a bit about what your intention is with these loops.
The inner loop is meant to produce an arbitrary number of spaces, depending on what number you're iterating on. So if you're on number 0, you produce no spaces, and if you're on 1, you produce one space, and so forth. The other caveat is that they all must appear on the same line, so System.out.println is the incorrect choice.
You would want to use System.out.print to print out the spaces. So let's write that.
for(int j = 0; j < 6; j++) {
System.out.print(" ");
}
This will print out six spaces unconditionally. What that condition is depends on the current number we're iterating on. That comes from your outer loop.
You only need to define a loop that starts from an arbitrary starting point - like 0 - and then loop until you are at most your ending number. For this, your current loop is sufficient:
for(i = 0; i <= userNum; i++) {
}
Now, we need to bring the two pieces together. I leave the figuring out of the question mark and what to print after you've printed the spaces as an exercise to the user, bearing in mind that you must stop printing spaces after you've reached your number.
for(int i = 0; i <= userNum; i++) {
for(int j = 0; j < ?; j++) {
System.out.print(" ");
}
}
Let's analyse the task
In every line, we should print a number and different number spaces in the front of the number.
For that, we need two loops - one outer to iterate from 0 to N and one inner to add spaces in front of the number.
private static void method1(int userNum) {
int nummSpaces = 0;
for (int i = 0; i <= userNum; i++) {
for (int j = 0; j < nummSpaces; j++) {
System.out.print(" ");
}
nummSpaces++;
System.out.println(i);
}
}
In this solution, we have variable numSpaces which used to count the number of spaces in front of the number. It is unneeded - we can use variable i for that purpose.
private static void method2(int userNum) {
for (int i = 0; i <= userNum; i++) {
for (int j = 0; j < i; j++) {
System.out.print(" ");
}
System.out.println(i);
}
}
Let's analyses once again the output
- the fist line: printed zero spaces and number 0
- the second line: printed one space and number 1
- the third line: printed two spaces and number 2
- and so on
Finally, we can use just one variable, which contains spaces and after that print the length of it:
private static void method3(int userNum) {
for (String spaces = ""; spaces.length() <= userNum; spaces += " ") {
System.out.println(spaces + spaces.length());
}
}
C/C++
#include <iostream>
using namespace std;
int main() {
int userNum;
int i;
int j;
cin >> userNum;
for (i = 0; i <= userNum; ++i) {
for (j = 0; j < i; ++j) {
cout << " ";
}
cout << i << endl;
}
return 0;
}
Consider the following Java program:
public class RelativelyPrime {
public static void main(String[] args) {
int N = Integer.parseInt(args[0]); // Dimensions of grid
int i, j;
int r; // Remainder when i is divided by j
for (i = 1; i <= N; i++) {
for (j = 1; j <= N; j++) {
do { // Using Euclidean algorithm
r = i % j;
i = j;
j = r;
} while (r > 0);
if (i == 1) System.out.print("*");
else System.out.print(" ");
}
System.out.println();
}
}
}
This program prints an N x N table (or matrix, if you like) where N is a command-line argument.
The (i, j)-entry is a * if i and j are relatively prime, or a single whitespace if they are not relatively prime. When I run the program by entering, for instance, java RelativelyPrime 3 it endlessly prints *. Why is this happening?
You changed i and j in the while loop.
for (i = 1; i <= N; i++) {
for (j = 1; j <= N; j++) {
int ii = i, jj = j;
do { // Using Euclidean algorithm
r = ii % jj;
ii = jj;
jj = r;
} while (r > 0);
if (ii == 1) System.out.print("*");
else System.out.print(" ");
}
System.out.println();
}
This is where using the debugger would have helped you solve the problem.
Inside your loops, you alter both i and j which means they never reach N and thus you have an infinite loop.
I suggest you not alter these variables but instead use two new variables, ideally with meaningful names.
I'm practicing basic coding exercises and trying to print the following triangle in Java:
*
***
*****
***
*
The following code gives me the results but I feel like there must be a much more elegant solution
for (int i = 1; i <= 5; i++) {
if (i % 2 == 1) {
for (int j = 1; j <= i; j++) {
System.out.print("*");
}
System.out.println("");
}
}
for (int i = 3; i > 0; i--) {
if (i % 2 == 1) {
for (int j = 1; j < i + 1; j++) {
System.out.print("*");
}
System.out.println("");
}
}
Can anyone provide some insight into how to make this work in a better way?
Ok, here's some more code that produces the correct result that uses just the two for loops, but it looks even uglier:
for (int i = 1; i <= 10; i += 2) {
if (i <= 5) {
for (int j = 1; j <= i; j++) {
System.out.print("*");
}
System.out.println("");
}
else if(i > 5 && i < 8){
for(int j = i/2; j > 0; j--){
System.out.print("*");
}
System.out.println("");
}
else{
for(int j = 1; j > 0; j--){
System.out.print("*");
}
System.out.println("");
}
}
First, you are skipping each 2nd iteration of the loop because you want to increase two steps at once. You can do this by changing the "i++" in your loop to "i += 2" and "i--" to "i -= 2", that will have the same effect and allows you to remove the if inside both loops.
Another improvement would be using a single outer loop and figuring out whether the inner loop should be increasing or decreasing the amount of asterisks. Maybe you can come up with an equation that gives you the amount of asterisks based on the value of i? (I didn't want to solve it completely so you have some exercise left, just comment if you want a full solution)
Updated with a solution that might be considered elegant as you can change the height of the triangle and there is no repetition:
int height = 5;
for (int i = 1; i <= 2 * height; i += 2) {
int numAsterisks;
if (i <= height) {
numAsterisks = i;
} else {
numAsterisks = 2 * height - i;
}
for (int j = 0; j < numAsterisks; j++) {
System.out.print("*");
}
System.out.println();
}
What about the following?
public void printTriangle(int size) {
int half = size / 2;
for (int i = 0; i < size; i++) {
int stars = 1 + 2 * (i <= half ? i : size - 1 - i);
char[] a = new char[stars];
Arrays.fill(a, '*');
System.out.println(new String(a));
}
}
Or just a bit more optimized:
public void printTriangle(int size) {
int half = size / 2;
char[] a = new char[size];
Arrays.fill(a, '*');
for (int i = 0; i < size; i++) {
int stars = 1 + 2 * (i <= half ? i : size - 1 - i);
System.out.println(new String(a, 0, stars));
}
}
for(int i = 0; i < 7; i++) {
for(int j = 0; j < i; j++) {
print("*");
}
print("\n");
}
This can be another solution to print a regular right triangle...
Here's a different way of looking at the problem. By using an integer array, I can solve lots of shape drawing problems by changing the values in the array.
When solving more difficult problems, you would use model classes instead of simple integers. The idea, however, is the same.
Here's the output.
*
***
*****
***
*
And here's the code:
public class Triangle {
public static void main(String[] args) {
int[] heights = {1, 3, 5, 3, 1};
for (int i = 0; i < heights.length; i++) {
for (int j = 0; j < heights[i]; j++) {
System.out.print("*");
}
System.out.println("");
}
}
}
How about...
int width = 5;
for (int i = 1; i <= width; i+=2){
System.out.println(String.format("%"+i+"s", "").replaceAll(" ", "*"));
}
for (int i = width-2; i > 0; i-=2){
System.out.println(String.format("%"+i+"s", "").replaceAll(" ", "*"));
}
Or, even better yet...
int width = 7;
double half = width / 2
for (int i = 0; i < width; i++){
System.out.println(String.format("%"+((i < half ? i : (width-i-1))*2+1)+"s", "").replaceAll(" ", "*"));
}
Gives
*
***
*****
***
*