4
\$\begingroup\$

I've completed the small challenge in the eloquent JS book to create a chess board pattern:

Write a program that creates a string that represents an 8×8 grid, using newline characters to separate lines. At each position of the grid there is either a space or a “#” character. The characters should form a chess board. When you have a program that generates this pattern, define a variable size = 8 and change the program so that it works for any size, outputting a grid of the given width and height.

I've used a function instead of a variable, but what do you think about my little script?

function chessboard(size) {
  var output = "";
  for(var i = 0; i < size; i++) {
    for(var j = 0; j < size / 2; j++) {
      if(i % 2 === 0) {
        output += " ";
        output += "#";
      } else {
        output += "#";
        output += " ";      
      }
    }
    output += "\n";
  }
  return output;
}
console.log(chessboard(8));

\$\endgroup\$
3
\$\begingroup\$

Your little script is clear and to the point, but (as 200_success pointed out) it writes out two squares at a time so it only works for even sizes.

You can calculate the color of each square, using the evenness of the coordinades. Squares with both even coordinates (like 2,2) or both odd coordinates (like 1,3) have one color. If i % 2 has the same value as j % 2 then it's one color, otherwise the other color:

function chessboard(size) {
  var output = "";
  for(var i = 0; i < size; i++) {
    for(var j = 0; j < size; j++) {
      output += i % 2 === j % 2 ? " " : "#";
    }
    output += "\n";
  }
  return output;
}

console.log(chessboard(5));
\$\endgroup\$
3
\$\begingroup\$

You always append two squares at a time, so the output will be wrong if size is odd.

String concatenation is a rather expensive operation. Since strings in JavaScript are immutable, each += involves allocating a new string, copying the entire contents of the string, then copying the characters to be appended. Therefore, it would be a good idea to reduce the number of concatenation operations. (The obvious change would be to coalesce two append operations into output += " #"; and output += "# ", but as I noted above, that produces wrong results.)

One improvement would be to construct an even line (e.g. " # # # #\n") and an odd line (e.g. "# # # # \n"), then compose the board a line at a time.

An eloquent solution would probably involve Array.join("\n"), but I suppose that would not be an expected solution at this early point in the book.

\$\endgroup\$
0
\$\begingroup\$

Can't help myself but I dislike nested loops.

Have you thought about using recursion?

function constructBoard(size) {
  var ret = '';
      
  function constructLine(oddOrEven, index, size, base) {
 
    index % 2 === oddOrEven ? base += '#' : base += ' ';
             
    if (++index > size) {       
      return base += '\n';
    } else {            
      return constructLine(oddOrEven, index, size, base);
    }
  }
  
  for (var i = 1; i <= size; i++) {   
    ret += constructLine(i % 2, 1, size, '');             
  }
          
  return ret;
}

console.log(constructBoard('16'));

\$\endgroup\$
  • \$\begingroup\$ You are using the conditional expression as an if statement. It should be: base += index % 2 === oddOrEven ? '#' : ' ';. \$\endgroup\$ – Guffa Mar 19 '16 at 17:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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