Mr. Pethiyagoda gives us this lovely example:

Now what does this tweet mean?

After chuckling or groaning at the wordplay displayed in the naming of the parameters for the function lets reformat the tweet.

function N(Q, u, ee, n, s, H, R) { s = 0;

Q = u ? Q : (1 << Q) - 1;

H = ~(u | ee | n) & Q; while (H) H ^= R = -H & H, s += N(Q, (u | R) << 1, ee | R, (n | R) >> 1); return s += ee == Q }

Now the code ooks like the algorithm from Martin Richards paper. Here Martin uses bit patterns to keep track of queen placements for the columns, left diagonals and right diagonals. The blue lines in the following diagram are what represents a bit in the bit patterns.

A 1 in the bit pattern denotes that there is a queen attacking that column or diagonal line and 0 means that no queens are attacking that position. A caveat that you may later notice from the diagram below is that the bit patterns for the left and right diagonals only represent what is happening on the current row we are analyzing. This is because like most N-Queens solutions, we only react to the circumstances of the current row we are working with. I will later explain how Martin uses binary operators to change the bit patterns of the diagonals as we switch rows and how to find possible queen placements.

To help us decipher the tweet, I will first give you what the parameters mean: Q is the size of a board side/number of queens we must place on the board but later becomes the binary representation of a full board. u, ee, and n are each a number that is the bit pattern to what left diagonals, columns, and right diagonals are being currently attacked by queens on the board. s maintains the count of the number of solutions found. H is a bit pattern that represents all a board. R is the bit pattern of the right most possible position to place a queen.

// Start of the function

s = 0;

Q = u ? Q : (1 << Q) - 1;

H = ~(u | ee | n) & Q;

Mr. Pethiyagoda’s function’s first step is to set the solution count, s, to 0. s will later be incremented as solutions are found. He then checks if any pieces have been placed on the board. If not, a binary representation of a full board, Q, is created through

(1 << Q) - 1

// example of how this works

// if Q = 5

(1 << 5) = 100000 // binary representation of 32

32 - 1 = 100000 - 000001 = 11111

Diagram from Backtracking Algorithms in MCPL using Bit Patterns and Recursion

Once Q is instantiated, a bitwise OR operator is run on u, ee, and n. By combining all of the 1’s in the 3 bit patterns into one bit pattern, we can see where all the places on the current row of the board that are being attacked by a queen. We can then find all the possible placements of queens on the row by inverting the combined bit pattern with a bitwise NOT operator and than masking it with Q. This new bit pattern becomes H.

// for example in the above diagram, the combination of ld, cols,

// and rd are attacking:

(u | ee | n ) = 11011101 // a bitwise NOT operator flips the 1’s and 0’s producing the places // that are not under attack:

~(u | ee | n) = 00100010 // because computers create numbers from a x amount of bits,

// we have to mask that ~(u | ee | n) with Q to remove the 1’s in

// the bit pattern larger than Q (ex. javascript numbers are 32 bit

// large)

// ~(u | ee | n) will look like ...1111111111111100100010

H = ~(u | ee | n) & Q = ...00000000000000100010

While H is not 0, which means as long as there are possible queen placements left, we run:

H ^= R = -H & H, s += N(Q, (u | R) << 1, ee | R, (n | R) >> 1);

The first thing that gets evaluated here is the -H & H. This expression is a bitwise techique that helps isolate the right most bit of H which gets saved to R. R will be the position where we will place our newest queen. To run a test of all possible queen placements on the current row, we run function N with the parameters Q, a bit pattern representation of a full board, (u | R) << 1, the left diagonal bit pattern, ee | R, the column bit pattern, and (n | R) >> 1, the right diagonal bit pattern. The bitwise OR operator is used to represent the placement of the new queen at its rightmost available spot. The diagonal bit patterns were right and left shifted to represent what diagonals the queens are attacking on the new row. The plus equals operator after s adds the result from this function to the total count for the number of solutions.

I will now go back and explain the H ^= R expression. This removes the rightmost bit from H. Since a while loop of all possible positions, H, is what determines how many times the N function gets run, once all possible H values are tested for the row, the loop ends. In layman terms, all possible queen positions have been tested for the row and all we can do is wait to see if each tests resulted in a solution or failure. As each test spawns new tests, all possible board placements are found.

return s += ee == Q

The last line return determines what gets returned and when s gets to increment. In this case, if columns, ee, is equal to a full board, Q, which simplified means that N queens were placed on the board, a solution is found and the function can increment s by 1.

Now this function is impressive by how short it is and it may seem that this is the fastest way you can solve N-Queens with using javascript but its not. Bitwise operations are fast but you can combine it with another javascript feature to improve the speed of your N-Queens solution but that is for another time.