Skip to content

Instantly share code, notes, and snippets.

@Ramasubramanian
Last active December 19, 2015 11:19
Show Gist options
  • Save Ramasubramanian/5946429 to your computer and use it in GitHub Desktop.
Save Ramasubramanian/5946429 to your computer and use it in GitHub Desktop.
N Queens implementation to identofy all solutions on a Tree based storage instead of generating all combinations of solutions
package nqueens;
import java.util.*;
import nqueens.Tree.Leaf;
import nqueens.Tree.Node;
public class NQueensTree {
static class Count {
long count = 0;
public void incr() {
count++;
}
public long value() {
return count;
}
}
static class Position {
static Position[][] cache = new Position[20][20];
static {
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 20; j++) {
cache[i][j] = new Position(i, j);
}
}
}
final int x;
final int y;
private Position(int i, int j) {
x = i;
y = j;
}
public boolean placeable(Position other) {
return x != other.x && y != other.y && Math.abs(x - other.x) != Math.abs(y - other.y);
}
public String toString() {
return "(" + x + "," + y + ")";
}
}
public static Position position(int i, int j) {
return Position.cache[i][j];
}
static class RowComparator implements Comparator<Position> {
public int compare(Position o1, Position o2) {
return o1.x - o2.x;
}
}
public boolean isValid(Position prospect, Node<Position> node) {
do {
if (!prospect.placeable(node.value)) {
return false;
}
} while ((node = node.parent) != null);
return true;
}
public List<Position> nextColPositions(int col, int n, Node<Position> node) {
List<Position> ret = new ArrayList<>();
Position temp;
for (int i = 0; i < n; i++) {
temp = position(i, col);
if (isValid(temp, node)) {
ret.add(temp);
}
}
return ret;
}
public void processNode(Node<Position> node, int n, int col) {
if (col >= n) {
return;
}
List<Position> positions = nextColPositions(col, n, node);
Node<Position> temp;
for (Position p : positions) {
if (col == (n - 1)) {
temp = Tree.leaf(node, p);
} else {
temp = Tree.node(node, p);
}
processNode(temp, n, col + 1);
if (!temp.children.isEmpty() || temp instanceof Leaf) {
node.addChild(temp);
}
}
}
public List<Position> getPath(Node<Position> node) {
List<Position> ret = new ArrayList<>();
do {
ret.add(node.value);
} while ((node = node.parent) != null);
Collections.sort(ret, new RowComparator());
return ret;
}
public void solution(Node<Position> node, Count count, int n) {
for (Node<Position> child : node.children) {
if (child instanceof Leaf) {
count.incr();
printSolution(getPath(child), n);
} else {
solution(child, count, n);
}
}
}
public void printRow(Position p, int n) {
for (int i = 0; i < n; i++) {
if (i == p.y) {
System.out.print(" Q ");
} else {
System.out.print(" + ");
}
}
System.out.println();
}
public void printSolution(List<Position> solution, int n) {
for (Position p : solution) {
printRow(p, n);
}
System.out.println();
}
public long generateSolution(Tree<Position> tree, int n) {
Count count = new Count();
solution(tree.root, count, n);
return count.value();
}
public void nqueens(int n) {
long count = 0;
Tree<Position> temp;
for (int i = 0; i < n; i++) {
temp = new Tree<Position>(position(i, 0));
processNode(temp.root, n, 1);
count += generateSolution(temp, n);
}
System.out.println("n=" + n + ";solutions=" + count);
}
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
for (int i = 0; i <= n; i++) {
long start = System.currentTimeMillis();
new NQueensTree().nqueens(i);
System.out.println("Time taken(ms) : " + (System.currentTimeMillis() - start));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment