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 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));

200_success
146k22 gold badges190 silver badges479 bronze badges
asked Mar 18, 2016 at 7:55
\$\endgroup\$

3 Answers 3

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));
answered Mar 18, 2016 at 9:52
\$\endgroup\$
0
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.

answered Mar 18, 2016 at 8:31
\$\endgroup\$
0
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'));

answered Mar 19, 2016 at 12:37
\$\endgroup\$
1
  • \$\begingroup\$ You are using the conditional expression as an if statement. It should be: base += index % 2 === oddOrEven ? '#' : ' ';. \$\endgroup\$ Commented Mar 19, 2016 at 17:04

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.