10
\$\begingroup\$

What can be more elegant ways to solve the given problem.

    #
   ##
  ###
 ####

Code:

function StairCase(n) {
    for (var i = 1; i <= n; i++) {
        var col = i;
        for(var j = 1; j <= n - col; j++) {
            process.stdout.write(' ');
        }
        for(var j = 1; j <= col; j++) {
            process.stdout.write('#');
        }
        process.stdout.write('\n');
    }

}
\$\endgroup\$

8 Answers 8

11
\$\begingroup\$

JavaScript function names should start with a lowercase character, and "staircase" is one compound word in English.

Since every line is nearly the same, and only one character changes at a time, you should take advantage of that and use an array as a buffer.

function staircase(n) {
    var line = Array(n + 1).fill(' ');
    line[n] = '\n';
    for (var i = n - 1; i >= 0; i--) {
        line[i] = '#';
        process.stdout.write(line.join(''));
    }
}
\$\endgroup\$
1
6
\$\begingroup\$

No need for the additional for loops:

function StairCase(n) {
    var s = '';
    for (var i = 1; i <= n; i++) {
            s += ' '.repeat(n - i) + '#'.repeat(i)  + '\n';
    }
    return s;
}

If you don't have repeat for some reason, another implementation could be:

String.prototype.Repeat = function(count) {
    var ret = '';
    for(var i = 0; i < count; i++){
        ret += this.valueOf();
    }
    return ret;
}

function StairCase(n) {
    var s = '';
    for (var i = 1; i <= n; i++) {
            s += ' '.Repeat(n - i) + '#'.Repeat(i)  + '\n';
    }
    return s;
}
\$\endgroup\$
3
  • \$\begingroup\$ Why not write Repeat as String.prototype.repeat? Wouldn't that allow for more flexibility? \$\endgroup\$ Commented Jul 26, 2016 at 15:27
  • \$\begingroup\$ @HemanGandhi Thanks, I've updated my answer. \$\endgroup\$
    – ChatterOne
    Commented Jul 26, 2016 at 16:03
  • \$\begingroup\$ Why not write String.prototype.repeat as repeat, to avoid polluting the global namespace? \$\endgroup\$ Commented Jan 5, 2020 at 12:11
6
\$\begingroup\$

This traditional Javascript code works fine:

function staircase(n) {
  var line = Array(n + 1).fill(' ');
  //line[n] = '';
  for (var i = n - 1; i >= 0; i--) {
    line[i] = '#';
    console.log(line.join(''));
  }
}

and ES6 we can write:

const staircase = n => {
  const line = Array(n + 1).fill(' ');
  //line[n] = ''; 
  for (let i = n - 1; i >= 0; i--) {
    line[i] = '#';
    console.log(line.join(''));
  }
}

If our given input is 6 the output should be:

     #
    ##
   ###
  ####
 #####
######
\$\endgroup\$
0
4
\$\begingroup\$

No need to use two for loops, you can use repeat function inside for loop.

See the below example.

var staircase = "",
    n = 6,
    space = " ",
    hash = "#";
for(var i = n ; i > 0 ;i--){
    staircase+=space.repeat(i-1).concat(hash.repeat(n-(i-1))) + "\n";
}
console.log(staircase);

Output Will be :

     #
    ##
   ###
  ####
 #####
######
\$\endgroup\$
1
  • \$\begingroup\$ Welcome to StackExchange Code Review! Please see: How do I write a good answer?, where you will find: "Every answer must make at least one insightful observation about the code in the question. Answers that merely provide an alternate solution with no explanation or justification do not constitute valid Code Review answers and may be deleted". \$\endgroup\$ Commented Mar 22, 2017 at 6:18
0
\$\begingroup\$

The last loop must not be the same as the previous one, because the problem ask for not leave any space characters. So You need to skip from creating it as '\n'.

let i = 0;
let stair = '';

for (i = 1; i <= n; i++){
    if (i < n) {
    stair += ' '.repeat(n - i) + '#'.repeat(i) + '\n';   
    } else {
        stair += '#'.repeat(i);   


    } 
}

console.log(stair)

}
\$\endgroup\$
3
  • 2
    \$\begingroup\$ Welcome to Code Review! Your answer states: "the problem ask for not leave any space characters". Where is this mentioned? \$\endgroup\$ Commented Jul 17, 2019 at 21:19
  • \$\begingroup\$ (if you terminated the loop on i < n, you would not need a conditional statement unless to provide for n < 1.) \$\endgroup\$
    – greybeard
    Commented Jan 4, 2020 at 8:40
  • \$\begingroup\$ Please format your code properly. While here, you must also fix the trailing } at the end, which has no { counterpart. \$\endgroup\$ Commented Jan 5, 2020 at 12:14
0
\$\begingroup\$

I prefer use functional and prototypical inheritance over native loops because it's cleaner. And I use MAP because ES6 feature is far more short and useful, though MAP has no side effects.

const reversedArr = (n) => Array.from(Array(n).keys()).reverse()

const staircase = (n) => reversedArr(n).map((value, index) => {
        return console.log(' '.repeat(value)+'#'.repeat(index+1)+'\n')
    })

staircase(50)

func is a output of a logic: Array.from(Array(n).keys()).reverse() that receives n:integer parameter.

Array.from is a new syntax from ES6, it means that you can fill an array from "here" to "there" ie: Array.from(0, 6) returns [0,1,2,3,4,5,6]

so all the staircase(n) return is a output of map of this array. Such array that receive Array(n).keys() and reverses it with prototype reverse()

so that the array could be: [6,5,4,3,2,1,0] instead.

the map repeat iterate over the array created from Array.from(Array(n).keys()).reverse() and return a log for each item such as every item repeats ' ' (blank space) + "#" at the end of this string.

\$\endgroup\$
6
  • 1
    \$\begingroup\$ Can you add an intuition or a rationale for your preference? \$\endgroup\$
    – greybeard
    Commented Jan 2, 2020 at 17:43
  • \$\begingroup\$ It's clear? back here with what you did not get. \$\endgroup\$ Commented Jan 4, 2020 at 2:08
  • 1
    \$\begingroup\$ My question has been and is Why prefer this over the code as presented in the question?, not Does this indeed work, and why? (Intuition would be something like I think I prefer this because I generally prefer functional style coding, rationale something like This has 13 tokens instead of 42, so it is easier to understand and maintain) \$\endgroup\$
    – greybeard
    Commented Jan 4, 2020 at 8:42
  • \$\begingroup\$ I didn't know that. Thank you \$\endgroup\$ Commented Jan 5, 2020 at 11:24
  • 1
    \$\begingroup\$ arr is a terrible name for a function that returns a reversed range. \$\endgroup\$ Commented Jan 5, 2020 at 12:17
-1
\$\begingroup\$

Here is the solution using ES6 array.map() with no for-loop used, which to me is the most clear and intuitive solution:

function staircase(n) {
    // intiate an empty n*n matrix
    let matrix = Array(n).fill().map(() => Array(n).fill());

    matrix.map((curArr, idY) => { // for each array row in matrix
        curArr.map((curVal, idX) => { // for each element in the current array row
            // evaluate each element's to-be-assigned value
            matrix[idY][idX] = (idX + idY + 1 >= n) ? '#' : ' ';
        }, [])
    }, [])

    // convert each row into string
    matrix.forEach((row) => {
        console.log(row.join(''));
    })
    // now we have the staircase
}

If you're interested, go researching about functional programming, pure functions and immutability.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ Welcome to Code Review. Your current answer is an alternative implementation, not really a review of the code provided. While alternative implementations can be a good part of an answer, all answers should at least say something about the code and/or approach provided in the question. \$\endgroup\$
    – Mast
    Commented Jan 8, 2020 at 7:07
  • \$\begingroup\$ Can you please argue an increase in elegance of the proposed use of nested map()s over the code presented in the question? \$\endgroup\$
    – greybeard
    Commented Jan 8, 2020 at 8:05
-1
\$\begingroup\$

No need to declare loads of variables.

function staircase(n) {
    let a = "#";
    for(let i =1;i<=n;i++){
        console.log(" ".repeat(n-i)+a.repeat(i))
    }
}
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.