miku86

Posted on

JavaScript Katas: Draw Chessboard

Intro π

Problem solving is an important skill, for your career and your life in general.

That's why I take interesting katas of all levels, customize them and explain how to solve them.

Understanding the Exerciseβ

First, we need to understand the exercise!
If you don't understand it, you can't solve it!.

My personal method:

1. Input: What do I put in?
2. Output: What do I want to get out?

Today's exercise

Today, another `7 kyu` kata,
meaning we slightly increase the difficulty.

Source: Codewars

Write a function `drawChessboard`, that accepts two parameters: `rows` and `columns`.

Given a `rows` number, e.g. `3`, and a `columns` number, e.g. `3`,
return a chessboard as a two dimensional array, e.g.

``````[
[ "O", "X", "O" ],
[ "X", "O", "X" ],
[ "O", "X", "O" ]
]
``````

White should be represented by `"O"`, black by `"X"`, the first row starts with a `"O"`.

Input: two numbers.

Output: an array of array(s).

Thinking about the Solution π­

I think I understand the exercise (= what I put into the function and what I want to get out of it).

Now, I need the specific steps to get from input to output.

I try to do this in small baby steps:

1. Create a row with the correct length (= `columns`) that starts with `"O"`
2. Create a row with the correct length (= `columns`) that starts with `"X"`
3. Do this alternately until there are enough (= `rows`) rows
4. Return the array of array(s)

Example:

• Input: `3, 3`
• Create a row with the correct length (= `columns`) that starts with `"O"`: `[ "O", "X", "O" ]`
• Create a row with the correct length (= `columns`) that starts with `"X"`: `[ "X", "O", "X" ]`
• Do this alternately until there are enough (= `rows`) rows: 1 additional row `(=> 3 - 2 = 1)` : `[ "O", "X", "O" ]`
• Return the array of array(s): `[ [ "O", "X", "O" ], [ "X", "O", "X" ], [ "O", "X", "O" ]]`
• Output: `[ [ "O", "X", "O" ], [ "X", "O", "X" ], [ "O", "X", "O" ]]` β

Implementation (Explicit) β

``````function drawChessboard(rows, columns) {
// Create an empty board with the correct amount of rows
const board = [...Array(rows)].map((_) => []);

// Create a row with the correct length that starts with "O"
const rowO = [...Array(columns)].map((_, i) => (i % 2 ? "X" : "O"));

// Create a row with the correct length that starts with "X"
const rowX = [...Array(columns)].map((_, i) => (i % 2 ? "O" : "X"));

// Add the proper row to each board row
return board.map((_, i) => (i % 2 ? rowX : rowO));
}
``````

Result

``````console.log(drawChessboard(3, 3));
/*
[
[ "O", "X", "O" ],
[ "X", "O", "X" ],
[ "O", "X", "O" ]
]
*/
// β

console.log(drawChessboard(2, 4));
/*
[
[ "O", "X", "O", "X" ],
[ "X", "O", "X", "O" ]
]
*/
//  β
``````

Implementation (Implicit) β

``````function drawChessboard(rows, columns) {
return [...Array(rows)]
.map((_) => [])
.map((_, i) =>
i % 2
? [...Array(columns)].map((_, i) => (i % 2 ? "O" : "X"))
: [...Array(columns)].map((_, i) => (i % 2 ? "X" : "O"))
);
}
``````

Result

``````console.log(drawChessboard(3, 3));
/*
[
[ "O", "X", "O" ],
[ "X", "O", "X" ],
[ "O", "X", "O" ]
]
*/
// β

console.log(drawChessboard(2, 4));
/*
[
[ "O", "X", "O", "X" ],
[ "X", "O", "X", "O" ]
]
*/
//  β
``````

Playground β½

You can play around with the code here

Next Part β‘οΈ

Great work!

We learned how to use `...`, `Array`, `map`.

I hope you can use your new learnings to solve problems more easily!

Next time, we'll solve another interesting kata. Stay tuned!

If I should solve a specific kata, shoot me a message here.

If you want to read my latest stuff, get in touch with me!

Questions β

• How often do you do katas?
• Which implementation do you like more? Why?
• Any alternative solution?

Top comments (6)

Kostia Palchyk

π

I think, your second solution can even be a bit shortened:

``````function drawChessboard(rows, columns) {
return [...Array(rows)]
.map((_, i) =>
[...Array(columns)].map((_, j) => ((j+i) % 2 ? "X" : "O"))
);
}
``````

Gerges Nady

let arr = new Array()
let j = 0
let defArr = []
while (j <= m) {
defArr.push("o")
defArr.push("x")
j++
}
let x = defArr.slice(0, m)
let y = defArr.reverse().slice(0, m)

``````let count = 1
for (let i = 0; i < n; i += 2) {
arr[i] = x
if (count < n) {
arr[count] = y
count += 2
}
}
console.log(arr)
``````

miku86

Hey Gerges,

great work solving all these katas.
Looking forward to seeing some other solutions!

Gerges Nady

Ok, thanks

Kostia Palchyk • Edited

Couldn't let this kata go out of my mind, wanted to try something alternative:

``````const drawChessboard = (r, c) => [
...{ * [Symbol.iterator]() {
for (let i = 0; i < r; i++) yield [
...{ * [Symbol.iterator]() {
for (let j = i; j < c + i; j++) yield ['X', 'O'][j % 2]
}}
]
}}
]
``````

lbermudez

@kosich I've fixed and simplified your approach (thanks because it help me to open mind with generators + spread operator):

``````const drawChessboard = (r, c) => [
...(function* () {
for (let i = 0; i < r; i++)
yield [
...(function* () {
for (let j = 0; j < c; j++)
yield ['O', 'X'][(i + j) % 2];
})(),
];
})(),
];
``````