果然这个八皇后是每个编程语言都要玩一下的项目。看了中文版的解释之后,感觉很不舒服,对于我这样的三脚猫是无法深刻理解它的。于是又下载了英文版同时还进行了一顿搜。终于算80%的弄清楚了这个问题。
先上代码,然后细节一个个来说,
import random
def conflict(state, nextX):
nextY = len(state)
for i in range(nextY):
if abs(state[i]-nextX) in (0, nextY-i):
#这块我看到了网上的一些误导,
#这里只查(对角线关系和不同行同列关系)。
#同行问题已经在prettyprint那里确保了。
#"It is true if the horizontal distance
#between the next queen and the previous one
#under consideration is either zero (same column)
#or equal to the vertical distance (on a diagonal).
#Otherwise, it is false."
#再展开一点点,
#这里用两个点之差算横坐标,不能等于纵坐标的差。来确保对角线问题。
#棋盘是方滴嘛
return True
return False
def queens(num, state=()):
#这个state=()说明state一上来是一个空元组。
#这部分代码在zhihu上的解释,个人觉得很好:
#http://www.zhihu.com/question/32322577
for pos in range(num):
if not conflict(state, pos):#这个if是没有else的,因为当跑到conflict那里为真的时候,层层stack就被返上来,取消掉了整个这组排列(也就是没结果)
if len(state) == num-1:
yield (pos, )
else:
#这里多种组合分叉着走,也是遍历的关键。
for result in queens(num, state+(pos,)):
yield (pos, ) + result
def prettyprint(solution):
def line(pos, length=len(solution)):
return '. ' * (pos) + 'X ' + '. '*(length-pos-1)
for pos in solution:
print line(pos)
if __name__ == "__main__":
print list(queens(8))
prettyprint(random.choice(list(queens(8))))
#if main以上的部分其实是把所有皇后布阵都给出来了,random.choice是选择了其中一个list 去打印。
最后想说,这个八皇后问题,让我用上面这种表达方式,我是无法想到的。一上来那步空元组占位,就直接把我秒了。
光理解就费了很大的功夫,佩服佩服。