I am trying to write a method that outputs the following figure:
*
**
***
****
*****
I tried everything but my code always outputs this instead:
*****
****
***
**
*
Here is my code:
public void outputFigure(int y) {
count1 = y;
count2 = y;
int spaces = 0;
int x = y;
int x2 = y;
boolean s = false;
while (s != true) {
for (int i = spaces; i > 0; i--) {
System.out.print(" ");
}
spaces++;
if (spaces == y - 1) {
s = true;
}
for (count2 = 0; count2 < x; count2++) {
for (count1 = 0; count1 < x2; count1++) {
System.out.print("*");
}
x2--;
System.out.println();
}
}
}
Any help will be appreciated.
Too many loops; you need an outer loop i from 0 to y (the # of lines). Then a loop from i to y - 1 for spaces and another one from y - i - 1 to y for stars. Then a new-line. Also, no need for an instance here; so we can make the method static. Like,
public static void outputFigure(int y) {
for (int i = 0; i < y; i++) {
for (int j = i; j < y - 1; j++) {
System.out.print(" ");
}
for (int j = (y - i - 1); j < y; j++) {
System.out.print("*");
}
System.out.println();
}
}
There is repetitious code here though, which violates the DRY (don't repeat yourself) principle; let's refactor that - first a method to repeat a String an arbitrary count, there are many ways to do that. One (using Java 8+) would be
private static String repeat(String str, int count) {
return Stream.generate(() -> str).limit(count).collect(Collectors.joining());
}
Then we can use that to generate the figure. Like,
public static void outputFigure(int y) {
IntStream.range(0, y).forEachOrdered(i -> System.out.printf(
"%s%s%n", repeat(" ", y - i - 1), repeat("*", i + 1)));
}
In addition to what #Elliott Frisch pointed out, here's another version:
for (int i = 1; i <= 5; i++)
{
for (int j = 5; j >= 1; j--)
{
if (j <= i)
{
System.out.print("*");
}
else
{
System.out.print(" ");
}
}
System.out.println();
}
You only actually need to do two loops.
Also, one quick stylistic point: don't explicitly compare to true and false.
while (s != true)
can be simplified to
while (!s)
which is much "cleaner" and more concise.
Edit: As pointed out in the comments, you may also want to consider using a more meaningful variable name than s - names like this can be very confusing for debugging (or if you or someone else has to modify the code later).
Related
While this code works and executes, there's a problem with it. The goal of the code is to move [x] across the matrix. It does but, after completing the first row, it prints a completely blank array. Meaning there is no point where both i == x and j == y.
Then, after it prints again, it continues where it left off. This means it never finishes circling the array by the prints allotted.
A picture to showcase what I mean:
.
How would I solve this? It's happening because, after that else property of moveX activates, j == 0 and y == 1; at least, that's what I have to assume is causing the blank print.
public class MovingX {
private int rowsN;
private int columnsM;
private int[][] matrixArr = new int[rowsN][columnsM];
private int x = 0;
private int y = 0;
public MovingX(int n, int m) {
rowsN = n;
columnsM = m;
matrixArr = new int[n][m];
}
public void forLoopGrid() {
for(int i = 0; i < matrixArr.length; i++) {
for(int j = 0; j < matrixArr.length; j++) {
if(i == x && j == y) System.out.print("[x] ");
else {
System.out.print("[ ] ");
}
}
System.out.println();
}
System.out.println();
}
public void moveX() {
if(x < 4) x++;
else {
x = 0;
y++;
}
}
public void runProgram() {
System.out.println("Program Starting");
System.out.println("Rows, Columns: " + rowsN + " " + columnsM);
for(int i = 0; i < (rowsN * columnsM); i++) {
forLoopGrid();
moveX();
}
System.out.println("Program Ending");
}
public static void main(String[] args) {
MovingX xLoop = new MovingX(4, 4);
xLoop.runProgram();
}
}
In your function moveX() you should change condition inside if-statement. Below correct version:
public void moveX(){
if(x < 3) x++;
else{
x = 0;
y++;
}
}
0 indexing can play a tricky factor in all kinds of loops. Since your moveX() method goes up to x = 4, the 0-index count of up to for is 0,1,2,3,4. That is 5 elements. Your matrix is 4x4. You want a count of x=3, giving 0,1,2,3. 4 elements!
You must change your moveX() to
public void moveX(){
if (x < 3)
x++;
else {
x = 0;
y++;
}
}
public class MagicSquare
{
public static int[][] grid = new int[3][3];
public static int i = 0;
public static int j = 0;
public static void main(String[] args) {
int x = 1;
int y = 2;
int z = 0;
while(z < 9)
{
int holdx = x;
int holdy = y;
z++;
x++;
y--;
if(x == 3)
{
x = 0;
}
if(y == -1)
{
y = 2;
}
if(y == 3)
{
y = 0;
}
if(grid[x][y] == 0)
{
grid[x][y] = z;
}
else
{
holdy++;
if(holdy == 3)
{
holdy = 0;
}
grid[holdx][holdy] = z;
x = holdx;
y = holdy;
}
}
for(int i = 0; i < 3; i++)
{
System.out.print(grid[i][0]+", ");
}
System.out.println(" ");
for(int i = 0; i < 3; i++)
{
System.out.print(grid[i][1]+", ");
}
System.out.println(" ");
for(int i = 0; i < 3; i++)
{
System.out.print(grid[i][2]+", ");
}
}
THE OUTPUT LOOKS LIKE THIS:
2, 4, 9,
6, 8, 1,
7, 3, 5,
Hello,
I wrote a Black Magic code that is able to fill in the grids of the square up and the right of it, but if it is filled with a number then the next number would be put in the square that is below its current spot.
Then, go one square up and to the right and put the next integer there, and if I also go off the grid, then the next number will wrap around to the bottom and/or left. This program run until all the squares are filled.
I was wondering if it is possible to condense my code starting at my while loop to the end of my for loop into a shorter code?
Someone said that I would be able to code this USING JUST 2 lines, and I think that is bizarre... but they said it's doable!
Any hints, help, or pointer would be appreciated!
Thank you so much!
Not sure about less than 3 lines (at least without sacrificing readability), but you can condense these if statements for sure.
if(x == 3) {
x = 0;
}
if(y == -1) {
y = 2;
}
if(y == 3) {
y = 0;
}
Down into simply
x = x % 3;
y = (y + 3) % 3;
And you could pull those into the previous x++ and y--
x = (x + 1) % 3;
y = ((y - 1) + 3) % 3;
Similarly with holdy (if you actually need that value, I do not know).
Then, if you just want to print the array, the for loops can be shortened.
for(int[] row : grid) {
System.out.println(Arrays.toString(row));
}
About 10 years ago, I wrote the following code for computing the entries of a magic square. This, in some sense, boils down to a single line of code, and works for arbitrary odd edge lengths:
class M
{
public static void main(String args[])
{
int n = 5;
int a[][] = new int[n][n];
f(n,1,n/2,n-1,a);
print(a);
}
static int f(int j,int i,int k,int l,int I[][])
{
return i>j*j?i-1:(I[k][l]=f(j,i+1,(k+(i%j==0?0:1))%j,(l+(i%j==0?-1:1))%j,I))-1;
}
public static void print(int a[][])
{
for (int i=0; i<a.length; i++)
{
for (int j=0; j<a[i].length; j++)
{
System.out.print((a[j][i]<10?" ":"")+a[j][i]+" ");
}
System.out.println();
}
}
}
Of course, it is somehow inspired by the IOCCC and would be better suited for Programming Puzzles & Code Golf, but might show how much you can press into a single line of code when you (ab)use the ternary operator and recursion appropriately...
I'm supposed to modify code that I've written for an assignment:
public class ToweringStrings2 {
public static final int H = 2; //constant for the tower
public static void main(String[] args) {
drawTowers(H);
}
public static void drawTowers(int H) {
for (int i = 1; i <= H; i++) {
System.out.print(" ");
for (int j = 1; j <= i; j++) {
System.out.print("+");
}
System.out.println();
}
for (int k = 1; k <= H + 2; k++) {
System.out.print("#");
}
System.out.println();
}
}
so that it prints sequential numbers starting at 1, instead of +s. Currently, it prints:
This is what the new code is supposed to print:
and so on.
For some reason I'm just really stuck and can't figure it out.
You can create an extra variable to print and increment
Like that:
public class ToweringStrings2 {
public static final int H = 10; //constant for the tower
public static void main(String[] args) {
drawTowers(H);
}
public static void drawTowers(int H) {
int count = 1;
for (int i = 1; i <= H; i++) {
System.out.print(" ");
for (int j = 1; j <= i; j++) {
System.out.print(count++ + " ");
}
System.out.println();
}
for (int k = 1; k <= H + 2; k++) {
System.out.print("# ");
}
System.out.println();
}
}
Step 1 - make it print a variable rather than a hard-coded string. Instead of System.out.print("+"), System.out.print(counter).
For this to work you need to have declared counter somewhere in the same scope as the statement: int counter = 0.
Run this. You'll see it print "0" where it used to print "+".
Step 2 - Now you need to make counter increase by one every time it prints.
Find the right place to add:
counter = counter + 1;
Run it and see it work.
Further notes
A more concise alternative to var = var + 1 is var++.
You can even do this at the same time as you use the value of a variable:
System.out.println(var++);
This can be used to express some algorithms very concisely -- but it can be confusing for beginners, so feel free to not use this technique until you're comfortable with the basics.
I'm taking a beginners Java course over the summer. I need to make a pyramid using loops for homework. The pyramid has to be made out of asterisks; in addition, size of pyramid is determined by user.
This is what I have for code now;
public class Pyramid {
public static void main(String[] args) {
int size = 6;
for (int x = 0; x < size; x++) {
for (int y = x; y < size; y++) {
}
for (int z = 0; z <= x; z++) {
System.out.print("*");
}
System.out.println("");
}
}
}
The problem of my code is that the number of asterisks in each row is wrong by one.
for (int z = 0; z <= x; z++) {
will execute the loop until z <= x is no longer true. That means it executes for z=0, z=1, z=2, ..., z=x--which means it actually executes the loop x+1 times. (The next z, z=x+1, is the first z that makes z<=x false.)
The normal idiom in Java (and other language with C-like for statements) is to start at 0 and use < when checking for the upper bound:
for (int z = 0; z < x; z++) {
You'll run into cases where you want to use <=, and you'll run into cases where you want to start at 1 instead of 0, but the majority of for loops with an integer index follow this form.
If I understand your question correctly :
public class Pyramid {
public static void main(String[] args) {
int size =6;
for (int i = 1; i <= size; i++) {
for (int x = size - 1; x >= i; x--) {
System.out.print(" ");
}
for (int y = 1; y<= i; y++) {
System.out.print("*");
}
for (int z= 1; z <= i - 1; z++) {
System.out.print("*");
}
System.out.println();
}
}
}
The output is :
*
***
*****
*******
*********
***********
If I understand your question, you could do something like this
int levels = 0;
Scanner input = new Scanner(System.in);
while (levels < 1) {
System.out.println("What size triangle would you like?");
if (input.hasNextInt()) {
levels = input.nextInt();
} else if (input.hasNext()) {
System.out.println("Not a valid size: " + input.next());
} else {
System.err.println("no more input");
System.exit(1);
}
}
for (int i = 1; i <= levels; i++) {
StringBuilder sb = new StringBuilder();
int t = i;
while (--t > 0) {
sb.append("*");
}
StringBuilder spaces = new StringBuilder();
for (t = 0; t < levels - i; t++) {
spaces.append(' ');
}
System.out.println(spaces.toString() + sb + "*" + sb);
}
To solve this problem it's best to think about the numbers that go into it...
*
***
*****
If you label the parts of the triangle
* row 1, 2 spaces, 1 star
*** row 2, 1 space, 3 stars
***** row 3, 0 spaces, 5 starts
Then you can just start playing with the numbers
The number of spaces to display is 3 - row # + 1
The number of stars to display is 2 * row - 1
Then construct a loop to draw each line.
within this loop, you need a loop to draw the number of spaces
and a loop to draw the number of stars
I'm working on the Conway's game of life program. I have the first two generations of cells printed out, but I can not get anymore printed. So I decided to use recursion so multiple batches of cells can be printed. My NewCells method creates the second generation. I thought that If I were to repeat said method by returning NewCells(c) instead of c, It would print out different results, but it prints out the same batch of cells over and over again.
public class Life {
public static boolean[][] NewCells(boolean[][] c)
{
int N = 5;
int o=0;
int p=0;
int livecnt = 0; //keeps track of the alive cells surrounding cell
int store = 0; //amount of surrounding cells for each individual cell
int livestore[] = new int[N*N];
System.out.println("Next Generation");
// Checks for the amount of "*" surrounding (o,p)
for (o=0; o < N; o++)
{
for (p=0; p<N; p++)
{
for (int k=(o-1); k <= o+1; k++)
{
for (int l =(p-1); l <=p+1; l++)
{
if ( k >= 0 && k < N && l >= 0 && l < N) //for the border indexes.
{
if (!(k== o && l==p)) //so livecnt won't include the index being checked.
{
if (c[k][l] == true)
{
livecnt++;
}
}
}
}
}
livestore[store]= livecnt;
livecnt = 0;
store++;
}
}
//Prints the next batch of cells
int counter= 0;
for (int i2 = 0; i2 <N; i2++)
{
for (int j2 = 0; j2 < N; j2++)
{
if (c[i2][j2] == false)
{
if (livestore[counter] ==3)
{
c[i2][j2]=true;
System.out.print("* ");
}
else
System.out.print("- ");
}
else if (c[i2][j2] == true)
{
if (livestore[counter] ==1)
{
c[i2][j2]= false;
System.out.print("- ");
}
else if (livestore[counter] >3)
{
c[i2][j2]= false;
System.out.print("- ");
}
else
System.out.print("* ");
}
counter++;
}
System.out.println();
}
return NewCell(c);
}
/*************************************************************************************************************************************************/
public static void main(String[] args)
{
int N = 5;
boolean[][] b = new boolean[N][N];
double cellmaker = Math.random();
int i = 0;
int j = 0;
int o=0;
int p=0;
int livecnt = 0; //keeps track of the alive cells surrounding cell
int store = 0; //amount of surrounding cells for each individual cell
int livestore[] = new int[N*N];
System.out.println("First Generation:");
// Makes the first batch of cells
for ( i = 0; i < N ; i++)
{
for ( j = 0; j< N; j++)
{
cellmaker = Math.random();
if (cellmaker > 0.5) // * = alive; - = dead
{
b[i][j]=true;
System.out.print( "* ");
}
if (cellmaker < 0.5)
{ b[i][j] = false;
System.out.print("- ");
}
}
System.out.println();
}
boolean[][] newcells = new boolean[N][N];
newcells = NewCells(b);
}
}
I do not think recursion is a good idea for this application. It leads to a StackOverflowError because each generation pushes another call stack frame. Recursion, as this program uses it, has no advantage over iteration.
Instead, put the main method call to NewCells in a loop. That way, you can run as many iterations as you like, regardless of stack size.
You are not calling NewCell from within NewCell, which is how recursion works.
I'm assuming it's not a typo in your question, but rather a lack of understanding of what it is and how it works, I recommend some reading on recursion in Java.
After you understand the basics, come back here for more help!