Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Re: Eight Queens Puzzle by Magnus Lie Hetland

Reply
Thread Tools

Re: Eight Queens Puzzle by Magnus Lie Hetland

 
 
Anton Vredegoor
Guest
Posts: n/a
 
      08-20-2003
(Bengt Richter) wrote:

>Obviously (after seeing your code and on thinking a board has two sides with
>four rotational positions each, for a total of 8 == 1 identity plus 7 T's ;-/ )


There is also something with this puzzle that makes me think of the
"getting a submatrix of all true" thread. A solution there was a
combination of the columns, here a solution is a permutation of
range(len(columns)). Below I'm giving a possible way to solve the
puzzle using this observation, but maybe someone can see a way to
improve it.

Anton

#permqueens.py
from sets import Set

def unique(n):
""" nqueens solver filtered for solutions that
are rotations or reflections """
seen = Set()
for sol in nqueens(n):
if sol not in seen:
m = mirrors(sol)
seen |= Set(m)
yield min(m)

def asqueens(sol):
""" ascii-art representation of a solution """
R,res = range(len(sol)),""
Q,n = zip(R,sol[::-1]),len(sol)
for i in R:
for j in R:
res += '+Q'[(n-j-1,n-i-1) in Q]+ ' '
res += '\n'
return res

def nqueens(n):
""" iterative nqueens solver using permutations """
QC,R = queencovers(n),range(n)
for i in xrange(fac(n)):
p = indexedperm(i,R)
if checksol(p,QC): yield tuple(p)

def mirrors(sol):
""" a list of mirror images of a solution """
def flip(x): return x[::-1]
def transpose(x):
xx = list(x)
for i,j in enumerate(x): xx[j] = i
return tuple(xx)
f,t = flip(sol),transpose(sol)
ft,tf = flip(t),transpose(f)
ftf,tft = flip(tf),transpose(ft)
ftft = flip(tft)
return [sol,f,t,ft,tf,ftf,tft,ftft]

def queencovers(n):
""" a dictionary of the positions that are covered by
queens on all board positions on an nxn board """
board,queens = [divmod(i,n) for i in range(n*n)],{}
for pos in board: queens[pos] = Set(cover(pos,board))
return queens

def fac(n):
""" faculty of n """
return reduce(lambda x,y*y,range(2,n+1),1L)

def indexedperm(m,L):
""" permutations of list L by index """
n,res,T = len(L),L[:],L[:]
for i in range(n):
m,d = divmod(m,n-i)
res[i] = T.pop(d)
return res

def checksol(sol,QC):
""" a solution is a permutation of a range, to convert it to
a list of queen positions it is zipped with a range, a
solution is true if no queen threatens the other queens """
n = len(sol)
#first a little optimization, queens cannot be adjacent
for i in range(n-1):
if abs(sol[i]-sol[i+1]) == 1: return False
queens = Set(zip(range(n),sol))
#check if no queen threatens another queen
for queen in queens:
if queens & QC[queen]: return False
return True

def cover((i,j),board):
""" positions that are covered by queen(i,j),
without (i,j) itself """
def keep((x,y)):
if (i,j) == (x,y) : return False
return i==x or j==y or abs(x-i)==abs(y-j)
return filter(keep,board)

def test():
""" test the unique nqueens solver """
n = 8
for i,sol in enumerate(unique(n)):
print i, sol
print asqueens(sol)

if __name__=='__main__':
test()


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Lie Hetland book: Beginning Python.. Vittorio Python 8 11-11-2005 05:15 PM
The eight queens problem jblazi C++ 9 08-30-2004 05:01 PM
"Eight Queens" program Matt C Programming 5 08-21-2004 04:14 AM
Is this OT(was:Re: "Eight Queens" program) sathya_me C Programming 5 08-20-2004 03:57 PM
Eight queens using stacks instead of recursion cfanatic C++ 3 10-16-2003 06:47 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57