Last active
December 19, 2015 11:19
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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