misterhtmlcss
misterhtmlcss

Reputation: 391

How to do a combined pyramid with stars and numbers together in a single pattern

Need a pyramid with numbers and stars and there are no examples to review.

        *
      * 0 *
    * 1 0 1 *
  * 0 1 0 1 0 *
* 1 0 1 0 1 0 1 *

Can I get some assistance with this?

This is what I have, but I can't figure out how to get the the numbers in there..

function displayPyramid(n) {
  for (let i = 0; i < n; i++) {
    let str = ''
    let count = 0
    // Spacing before each row
    for (let j = 1; j < n - i; j++) {
      str = str + ' '
    }
    // Row worth of data
    const max = 2 * i + 1
    for (let k = 1; k <= max; k++) {
      str = str + '*'
    }
    console.log(str);
  }
}

displayPyramid(5)

Upvotes: 1

Views: 389

Answers (7)

Barthy
Barthy

Reputation: 3231

Here's the thought process to get the expected result:

  • All rows with even indices are called 'even rows' (0, 2, 4, 6, …)

  • All rows with uneven indices are called 'uneven rows' (1, 3, 5, 7, …)

  • All stars are either the first or the last column in any row

  • For all even rows, the even indices display 0s, the uneven indices display 1s

  • For all uneven rows, the uneven indices display 0s, the even indices display 1s

I added a function called getSymbol that performs the last three checks and returns the appropriate symbol. I also renamed you iterator variables for better readability.

function getSymbol(column, max, row) {
  if (column === 0 || column === max - 1) { // if it is the first or last index within the row
    return '*'
  }

  if (row % 2 === 0) { // if it is an uneven row
    if (column % 2 === 0) { // if it is an even column
      return '0';
    }

    return '1' // if it is an uneven column within that row
  }

  // if it's not an even row, it's an uneven row
  if (column % 2 === 0) { // if it is an even column within that row
    return '1';
  }

  return '0' // if it is an uneven column within that row
}

function displayPyramid(n) {
  for (let row = 0; row < n; row++) {
    let str = ''
    let count = 0

    // Spacing before each row
    for (let spaces = 1; spaces < n - row; spaces++) {
      str = str + ' '
    }

    // Row worth of data
    const max = 2 * row + 1
    for (let column = 0; column < max; column++) {
      str = str + getSymbol(column, max, row)
    }

    console.log(str);
  }
}

displayPyramid(5)

Upvotes: 1

pank
pank

Reputation: 142

const rows = 5;
const columns = 2 * rows - 1;
// create an array filled with " "
const array = Array(rows).fill().map( () => Array(columns).fill(" "));
// if r and c are the row and column indices of the array, then
// in each row place two askerisks where c = rows -1 ± r   (if r is 0, there's only one asterisk)
// and alternating 1's (if c is odd) and 0's (if c is even) for all elements between columns rows - 1 - r and rows - 1 + r
const pyramid = array.map(function(row, r) {
	return row.map(function(v, c) {
		return c === rows - 1 - r || c === rows - 1 + r ? "*" : c > rows - 1 - r && c < rows - 1 + r ? c % 2 === 1 ? "1" : "0" : v;
	});
});
// const pyramid = array.map( (row, r) => row.map( (v, c) => c === rows - 1 - r || c === rows -1 + r ? "*" : c > rows - 1 - r && c < rows - 1 + r ? c % 2 === 1 ? "1" : "0" : v))

Upvotes: 1

Romen
Romen

Reputation: 1766

Let's first try to write a function for just one line of the pyramid, any line. We'll ignore the whitespace for now too.

Every line of the pyramid seems to follow a few simple rules:

  • All lines start with a *.
  • The 'inner sequence' is just alternating 1 and 0 a certain number of times.
  • There are 2*n - 1 digits in the inner sequence of each line, except the first.
  • Even lines (0, 2, 4, ...) begin the inner sequence with a 1.
  • Odd lines (1, 3, 5, ...) begin the inner sequence with a 0.
  • All lines end with an additional *, except the first.

In the rules above, everything can be determined from n. So our function only needs one argument:

function GetLine(n) {
   // ...
}

We can also determine whether a line is even or odd, and how many characters the inner sequence has:

EvenLine = (n % 2 == 0);
Count = 2*n - 1;

Building the sequence between the two stars can be done with a simple for loop.

Putting that all together, we can build the following function.

function GetLine(n) {
    // Create a string for the line that starts with a star
    var Line = "*";

    // Determine whether the line is even or odd
    var EvenLine = (n % 2 == 0);

    // Calculate the total number of ones and zeros in the line
    var Count = (2 * n - 1);

    // We need a variable to store whether the next character should be a one or zero
    var One = EvenLine ? true : false; // Even lines start with 1, Odd starts with 0

    // Repeat 'Count' times, alternating between ones and zeros
    for (var i=0; i<Count; i++)
    {
        Line += One ? "1" : "0";
        One = !One; // Toggle the bool value to alternate on the next iteration
    }

    // Only add a tail star if we're not on the first line
    if (n > 0) Line += "*";

    return Line;
}

When we call GetLine() with some consecutive numbers we can see that the pattern is mostly there:

console.log(GetLine(0));
console.log(GetLine(1));
console.log(GetLine(2));

*
*0*
*101*

Now all that needs to be done is insert the whitespace in two steps:

  1. A space between each character.
  2. The leading space to align the pyramid.
function printPyramid(s) {
    for (var n=0; n<s; n++) {
        // Get the line for n
        var line = GetLine(n);

        // This one-liner can be used to insert whitespace between each character
        // split('') will explode the characters into an array
        // join(' ') will turn the array back into a string with ' ' inbetween each element
        line = line.split('').join(' ');

        // Then we just add the necessary whitespace for alignment
        // We need 2 * (s - n - 1) spaces in front of each line.
        line = "  ".repeat(s - n - 1) + line;

        // Print the line
        console.log(line);
    }
}

Finally,

printPyramid(5);


        *
      * 0 *
    * 1 0 1 *
  * 0 1 0 1 0 *
* 1 0 1 0 1 0 1 *

Upvotes: 1

Nenad Vracar
Nenad Vracar

Reputation: 122077

You could do something like this but if in the middle is 0 or 1 will depend on the number you provided.

function build(n) {
  let grid = ''
  let total = n * 2;

  for (let i = 0; i < n - 1; i++) {
    let row = [];
    let start = total / 2 - i - 1
    let end = total / 2 + i
    if (!i) grid += ' '.repeat(start + 1) + '*' + '\n'
    for (let j = 0; j < total; j++) {
      if (j < start) row.push(' ');
      else if (j > end) row.push(' ');
      else {
        if (j == start) row.push('*');
        if (j == end) row.push('*');
        else row.push(j % 2 == 0 ? 1 : 0)
      }
    }

    grid += row.join('') + '\n'
  }

  return grid;
}

console.log(build(3))
console.log(build(6))
console.log(build(9))

Upvotes: 0

Ricardo Pinho
Ricardo Pinho

Reputation: 61

I wasn't sure if you needed the spaces, or if you wanted to change the characters in the tree, so I added them as parameters.

If you want to have more than 2 elements in the array, and have the first element in the center, you can shift the array on every row, instead of reversing it.

function displayPyramid(n, charArray, withSpace) {
  let charArrayOrdered = charArray
  for (let i = 0; i < n; i++) {
    let str = ''
    let count = 0
    // Spacing before each row
    let withSpaceChar = ''
    if(withSpace) {
      withSpaceChar=' '
    }
    for (let j = 1; j < n - i; j++) {
      str = str + ' ' + withSpaceChar
    }
    // Row worth of data
    const max = 2 * i
    charArrayOrdered = charArrayOrdered.reverse()
    let charState = 0
    for (let k = 0; k <= max; k++) {
      let char = '*'
      if(k!=0 && k !=max) {
        char=charArrayOrdered[charState]
        charState++
      } 
      if(charState==charArrayOrdered.length){
        charState=0
      }
      if(k!=max && withSpace) {
        char = char+' '
      }
      str = str + char
    }
    console.log(str);
  }
}

displayPyramid(5,[0,1], true)

Upvotes: 0

fYre
fYre

Reputation: 1280

function displayPyramid(n)
{
    for (let i = 0; i < n; i++)
    {
        let str = ''
        let count = 0
        // Spacing before each row
        for (let j = 1; j < n - i; j++)
        {
            str = str + ' '
        }
        // Row worth of data
        const max = 2 * i + 1
        str = str + '*'
        const innerChars = ['0', '1'];

        for (let k = 1; k < max; k++)
        {
            if (k === max - 1)
                str += '*'
            else
                str += innerChars[(i % 2 + k) % 2];
        }
        console.log(str);
    }
}

displayPyramid(5)

The main observations to make:

  • The first row we have no innner char
  • The second row begins with inner char 0
  • The third row begins with inner char 1 then alternates
  • The forth row begins with inner char 0 then alternate

We notice a pattern, even rows (or odd if zero based) begin with 0, and vice versa. Alternating pattern should hint to an array that we loop around.

Upvotes: 0

Kamen Minkov
Kamen Minkov

Reputation: 3747

function displayPyramid(n) {
  for (let i = 0; i < n; i++) {
    let str = "";
    let count = 0;
    // Spacing before each row
    let padCount = 2 * n - 2 * i - 1;

    for (let j = 1; j < padCount; j++) {
      str = str + " ";
    }

    // Row worth of data
    const max = 2 * i + 1;

    for (let k = 1; k <= max; k++) {
      if (k === 1 || k === max) {
        str = str + "* ";
      } else {
        str += (k % 2).toString() + " ";
      }
    }

    console.log(str);
  }
}

displayPyramid(5);

Upvotes: 1

Related Questions