1

I'm learning basics of JavaScript. I try to code a program that logs the following scheme to the console:

*
* *
* * *
* * * *
* * * * *
* * * * *
* * * *
* * *
* *
*

I managed to get first half of the task by the code:

 var x = 5;
    var line;

    for(var i = 0; i<x; i=i+1){
        line = "";
        for(var j=0; j<x; j=j+1){
            if(j <= i){
                line = line + " * ";
            }
        }
    console.log(line);
    }

So it looks like:

*
* *
* * *
* * * *
* * * * *

Could anybody give me a hint how to get the secod part of the scheme? I'd like to use another loop like the one I have but to revert it's action so that there would be less and less stars in each line.

3
  • 1
    Make a second loop with descending values (from 5 to 0) Commented Oct 8, 2015 at 16:07
  • 1
    Your problem doesn't lie in looping technique, rather you've to handle line differently. Instead of setting line to an empty string, you need to set it something like * * * *, and then remove one star on each round. It doesn't matter, if i is increased or decreased in the loop, as long as the loop just stops after a correct count of rounds. Commented Oct 8, 2015 at 16:12
  • Why reverse the loop? You can simply build the second part while building the first: jsfiddle.net/sdgtpkhL Commented Oct 8, 2015 at 16:12

7 Answers 7

1

Hints: You need to decrement i and j in the for loop and turn-around the <. instead of starting var i = 0 start at the end with 5.

Sign up to request clarification or add additional context in comments.

1 Comment

Hmmm...I don't think you need to decrement j with this approach, at least not in the code I tried. (Granted, since we're just throwing hints around, our implementations may vary.)
1

With two for loops after another. The first one adds stars and the second one removes stars:

var line = "";
for (var i = 0; i < 5; i += 1) {
    line += "*";
    console.log(line);
}
for(var j = 5; j > 0; j -= 1) {
    line = line.replace(line[j], "");
    console.log(line);
}

Comments

1

spoiler:

What about just using a while loop?

var count = 0,
    i = 1,
    addition = 1,
    str = null;
while (i) {
    str = new Array(i+1).join('*');
    console.log(str);
    if (i === 5) {
        console.log(str);
        addition = -1;
    }
    i += addition;
}

4 Comments

"Then you won't need to nest multiple loops into eachother". uhhh...You nested a for loop into your while loop? EDIT: Grr, sneaky edits...
Hence I removed that part since I was trying to remove the inner loop, but didn't find a decent solution without using future tech like string cloning.
Voila, I cheated and looked up a way to create the string without explicit looping inside the while. Anything else?
@GlenKeane I wouldn't worry so much about the n loops if their avoidance disrupts the readability.
0

You can, as one possible solution, put another if clause inside of your loop (read carefully):

If the line index reached half of the pyramid (maximum line length), start printing maximumLineLength * 2 - index - 1 instead.

This will essentially change the behaviour of the loop after the half is reached, so that the number of starts will start to decrease instead of increasing.


Another solution, if you're keeping the number of stars in the string, would be to add them until maxLineLength is reached, and then subtract them until you go back to 0 (you can use a boolean flag for that).

I'm not posting actual code to avoid spoiling the solution.

Comments

0

I think the solution with the conditionals and the one with the two loops are the ones you should use but you can compute the number of asterisks with a bit of modular arithmetic directly:

var x = 5;
var line;
for(var i = 1;i < x * 2;i++){
  line = '';
  for(var j = 0;j < Math.abs( (i+3) % 8 - 4) + 1;j++){
    line = line + ' * ';
  }
  console.log(line);
}

I used a trick that will most probably be seen here as a little bit dirty but it works. The sequence I use here is 1,2,3,4,5,4,3,2 and to get the last 1 I just run it one more time.

In general: To get a sequence from 1 to x and back to 1 again (with x > 1) run the outer loop x*2 times with Math.abs( (i+(x - 2)) % (2*x - 2) - (x - 1)) + 1 as the upper limit for the inner loop with i going from 1 to 2x-1.

Proof is left as an exercise for the student.

Comments

0

It's anti-pattern; why would you want this?

Nevertheless - accumulative variable:

var x = 5,
    y,
    line,
    result = [];

while (x--) {
    y = 5 - x;
    line = '';

    while (y--) {
        line = line + '*';
    }

    result.push(line);
}

document.write(result.join('<br>'));
document.write('<br>');
document.write(result.reverse().join('<br>'));

Comments

-2

Many solutions are possible but the simplest, like you suggest, is reverting the loop; this is what loop statement should look like:

 for(var i = x-1 ; i>=0 ; i--)

Basically you have to change the for-loop conditions that will go backwards starting from the max-value , this is the first statement part and is called initializer ;

the loop must stop/break at 0 , second part of statement called test (until the loop satisfies this condition it will go on in next iteration );

the last part of statement is the iteration update (how the state should change in next loop);


that said changing the statement you should be able to keep your body unchanged :

var x = 5;
for (var i = x - 1; i >= 0; i--) {
  line = "";
  for (var j = 0; j < x; j = j + 1) {
    if (j <= i) {
      line = line + " * ";
    }
  }
  console.log(line);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.