|
该帖已经被评为良好帖
|
|
|---|---|
| 作者 | 正文 |
|
时间: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
|
|
| 返回顶楼 | |






