锁定老帖子 主题:用 Python 秒掉八皇后问题!
该帖已经被评为良好帖
|
|
---|---|
作者 | 正文 |
发表时间:2007-08-10
hax 写道 我来个js版本:
function queen(x, y) { if (x < y || y < 1) throw Error(); var r = []; if (y == 1) { for (var i = 0; i < x; i++) { r.push([i]); } return r; } var r0 = queen(x, y - 1); for (var r0n = r0.length, r0i = 0; r0i < r0n; r0i++) { var a = r0[r0i]; var n = a.length; var p = []; for (var i = 0, j = n; i < n; i++, j--) { p[a[i]] = true; p[a[i] + j] = true; p[a[i] - j] = true; } for (var i = 0; i < x; i++) { if (p[i]) continue; r.push(a.concat([i])); } } return r; } 代码风格不是函数式了。而变成命令式了。 |
|
返回顶楼 | |
发表时间:2007-09-21
我也来个Ruby的
def check(e, i) e.each_with_index{ |x, index| return false if x == i || # | x + (e.length - index) == i || # \ x - (e.length - index) == i # / } return true end def queens(n, m = n) n, m = m, n if n < m return (0...n).collect { |i| [i] } if m == 1 return queens(n, m -1).inject([]) { |s, e| 0.upto(n - 1) { |i| s << e + [i] if check(e, i) } s } end p queens(8) |
|
返回顶楼 | |
发表时间:2007-09-21
还有楼主上面留的小问题
def convert(ary) s = [] ary.each_with_index { |x, i| s << [i, x] } return s end def format(ary) convert(ary).collect { |x| "(#{x[0]}, #{x[1]})" }.join(' ') end convert([2, 3, 4, 5]) # => [[0, 2], [1, 3], [2, 4], [3, 5]] format([2, 3, 4, 5]) # => "(0, 2) (1, 3) (2, 4) (3, 5)" |
|
返回顶楼 | |
发表时间:2007-11-29
问句题外话:
函数式编程的力量就在于抽象等级的空前提高 这句话是楼主自己的还是引用的?我喜欢 |
|
返回顶楼 | |
发表时间:2007-11-29
zenny 写道 问句题外话:
函数式编程的力量就在于抽象等级的空前提高 这句话是楼主自己的还是引用的?我喜欢 应该是《计算机程序的构造和解释》这本书上的,但我好像没找到。 反正差不多就是SICP里面的那个意思。SICP成天唠叨抽象来抽象去,就是没怎么提OOP。 |
|
返回顶楼 | |
发表时间:2007-12-18
给一个 haskell 版本:
import Control.Monad import Control.Monad.Writer import Data.List diagonal (x1,y1) (x2,y2) = x1 + y1 == x2 + y2 || x1 - y1 == x2 - y2 nqueens n = execWriter $ f [1..n] 1 [] where f [] _ ps = tell [ps] f cs r ps = forM_ cs $ \c -> unless (any (diagonal (r,c)) ps) $ f (delete c cs) (r + 1) ((r,c):ps) main = print $ nqueens 4 执行结果: [[(4,3),(3,1),(2,4),(1,2)],[(4,2),(3,4),(2,1),(1,3)]] 这个结果返回了所有可能的结果,如果这个N很大的话,将耗费很长的时间! hoho~ Haskell中完全没问题,我们只要一个大的结果中的第一项: Haskell中的惰性计算 main = print $ head $ nqueens 8 这样,将只得到一个结果然后就停止计算,haskell的表示 Lazy 的。 对程序的具体解释 求解一个N皇后问题,问题本身不描述了,地球人都知道。 面对一个N×N的棋盘,我们一行行放,开始我们有N个列可以放棋子,按照规则(互相不能攻击)我们一行行的放下去,可用的列便逐渐减少,而我们的行数在增加,已经摆放的棋子也在增加。直到全部放完N行,也就是说没有空余的列了。 对于放棋子的操作,我们称为 f 函数,有三个参数: 当前剩余的列,当前行数,已经摆放的棋子的位置。 第一种情况: 当前的剩余列空了,说明我们都摆放完了,那么我们得到一个结果并 tell 出去:(相当于 python中的 yield) f [] _ ps = tell [ps] 第二种情况: 从剩余的列中一个个都试验,看看能不能放下棋子。对每个位置(r, c) ,除非它和任何一个已有的棋子冲突,否则我们将得到一个合适的位置。对这个位置,递归调用f 来检测, 把c从剩余列中删除,行数加1,把(r,c)位置记录到ps中。(最近有老年痴呆症装,唠叨见多) f cs r ps = forM_ cs $ \c -> unless (any (diagonal (r,c)) ps) $ f (delete c cs) (r + 1) ((r,c):ps) 求N皇后,就是调用下 f [1..n] 1 [] ,把 f tell我们的结果抽取出来。 nqueens n = execWriter $ f [1..n] 1 [] 整个程序基本上相当于口语的翻译。 FP语言都说难理解,我却找不到比这更容易理解的算法描述了。 |
|
返回顶楼 | |
发表时间:2008-03-28
直接出自ML
|
|
返回顶楼 | |
发表时间:2008-05-19
弱弱的问下
“ran ≠ x 很好理解,就是不为同一列;|ran - x| ≠ y + 1 则意味着左右不在同一斜线上。” |ran - x| ≠ y + 1 则意味着左右不在同一斜线上。” 这一句我一直理解不了。。 不是|ran - x|== |y的相差值|么? |
|
返回顶楼 | |