« Invoking an EJB Session Bean from a BPEL Process | Main | SOA Wishlist »

An attempt on 8 Queens Problem

I was trying out a different approach to 8-Queen's problem. I visualized each cell [that has a coordinate from (0,0) to (7,7) as a single number 10x + y. So you would have sort of an octal number set from 0 to 77. Each column would be 0-7, 10-17, 20-27 etc and so on till 70-77.
Each row would be 0-70, 1 to 71 etc, in increments of 10.

7 17 27 37 47 57 67 77
6 16 26 36 46 56 66 76
5 15 25 35 45 55 65 75
4 14 24 34 44 54 64 74
3 13 23 33 43 53 63 73
2 12 22 32 42 52 62 72
1 11 21 31 41 51 61 71
0 10 20 30 40 50 60 70

The solution was a recursive function that takes in a current column index [ranging from 0 to 7], and computing the matching lists of size 8, after applying an exclusion rule.

The exclusion rule is interesting.
For an item with value, lets say 43, the exclusion rule would test the row-wise, columnwise and diagonal collisions through a simple modulo-checking logic. The code is given below. Note that the code has not been subjected to any review, including self-review, though it generates the required 92 distinct permutations as the 8Q solution demands.

package equeen;

import java.io.FileWriter;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class EightQueens {

public boolean computeMatches(int rowIndex, List matchedList) throws Exception{
if(matchedList.size() == 8) {
printToFile(matchedList);
}
boolean matched = false;
for(int i = 10*rowIndex ; i <= 10*rowIndex + 7 ; i++) {
int cellValue = i;
boolean isExcluded = computeExclusionRule(cellValue, matchedList);
if(!isExcluded) {
matched = true;
matchedList.add(cellValue);
if(computeMatches(rowIndex+1,matchedList)) matched = !matched;
}
}

if(!matched && matchedList.size() > 0) {
matchedList.remove(matchedList.size() - 1);
return true;

}
else return false;
}

private boolean computeExclusionRule(int value, List matchedList) {
for(int i = 0 ; i < matchedList.size() ; i++) {
int prevNumber = Integer.parseInt("" + matchedList.get(i));
int diff = (value - prevNumber);
if((diff % 9 == 0 && (prevNumber % 10 > value % 10)) ||
(diff % 10 == 0) ||
(diff % 11 == 0 && (prevNumber % 10 < value % 10))) {
return true;
}
}
return false;
}

public static void main(String[] args) throws Exception {
EightQueens q = new EightQueens();
List emptyList = new ArrayList();
int ZEROTHCOLUMN_INDEX = 0;
long t = System.currentTimeMillis();
q.computeMatches(ZEROTHCOLUMN_INDEX,emptyList);
System.err.println("Number of ms for execution - " + (System.currentTimeMillis() - t));
}

private static FileWriter fw = null;
private static void printToFile(List matchedList) throws Exception {
if(fw == null) {
fw = new FileWriter("d:\\temp\\results.log");
}
String str = "";
for(int i = 0 ; i < matchedList.size() ; i++) {
int itemValue = Integer.parseInt("" + matchedList.get(i));
str += getCoords(itemValue) + " ";

}
fw.write(str + "\r\n");
fw.flush();
}
private static String getCoords(int cellValue) {
int x = cellValue/10;
int y = cellValue % 10;
return "(" + x + "," + y + ")";
}

}

Comments (6)

Ramu:

Hi,

I happened to see this logic, when one prospective recruit copied this code as his own!

Interesting with the encoded cell number. But on the first impression the 'exclusion rule' may not be computationally simpler or better than plain checks, especially if you consider that a queen position does not need co-ordinates (x and y), but just col is enough as there should be one in each row.

Hey Ram, glad to see your orablog.

I was asked this exact same question during my interview for Oracle during my S7 campus placements and this is what i told him.

when you are doing a brute force search to place the next queen in the search criteria, what is pretty obvious to us is that we cannot place this queen in the same row and same column of any of the queens that are already on board. Now what remains is the diagonals which can go anyway. (i1 = i2 and j1 = j2).

So what do we do about the diagonal power of the queens, now what we do is, call a function which will check whether the principal diagonal elements of the minor matrix formed by that element has any of the previous queens. (The classic i1 = j1 or i2 = j2). This should be fairly simple to implement with a function doing everything for you.

Again, "if there are many solutions to a single problem, the simplest one is the best solution" and hence at any point comparing any (i,j) using i1 = i2 or j1 = j2 and i1+j1 = i2+j2 for the entire solution is hugely simpler than either mine or yours.

Cheers,
Abdul

p.s. We should catch us sometimes, its been a long time. (abdulbijur@gtalk/aim/hotmail)

Hello,

I would like to share the following site:
Eight Queens solution using GWT

I have used the Java code from this blog entry and incorporated it into a web site using the Google Web Toolkit to display the solutions. The site also tracks the amount of time each browser takes to calculate the Eight Queens Solution.

See my Blog entry here

Thanks,

Jim

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)

About This Entry

This page contains a single entry from the blog posted on June 30, 2008 11:07 PM.

The previous post in this blog was Invoking an EJB Session Bean from a BPEL Process.

The next post in this blog is SOA Wishlist.

Many more can be found on the main index page or by looking through the archives.

Powered by
Movable Type and Oracle