1

我正在解决 Haskell 中的 8-queens 问题,只使用基本功能没什么
特别的,这是代码:

queens = [[x1,x2,x3,x4,x5,x6,x7,x8]|x1<-[1..8],x2<-[1..8],x3<-[1..8],x4<-[1..8],x5<-[1..8],x6<-[1..8],x7<-[1..8],x8<-[1..8],safeH [x2,x3,x4,x5,x6,x7,x8] x1,safeD [x2,x3,x4,x5,x6,x7,x8] x1 [x1,x2,x3,x4,x5,x6,x7,x8] 1] 
safeH l e = if elem e l then False 
            else if length (l)/=0 then safeH(tail l)(head l) 
                    else True
safeD l e xs n = if last(xs)/=e || length xs == 0 then
                if length(l)/=0 then 
                    if (head(l)+n==e || head(l)-n==e) then False 
                    else safeD(tail l)(e)(xs)(n+1) 
                else safeD(tail xs)(head xs)(tail xs)(1)
            else True

为了澄清SafeH函数检查没有皇后在同一行 H 代表 Horizantly 而SafeD应该检查对角线冲突
我确信该SafeH函数没问题SafeD
并且在编译代码时它给我没有问题但是在调用时 它给我这个错误的queens功能:

[1 of 1] Compiling Main             ( y.hs, interpreted )
Ok, modules loaded: Main.
*Main> queens
*** Exception: Prelude.last: empty list

谁能帮帮我吗??提前感谢每一件事:)

4

2 回答 2

5

xs您可以通过检查调用前的长度来解决眼前的问题last

safeD l e xs n = if length xs == 0 || last(xs)/=e then ...

但是,您会遇到另一个问题,因为您在此分支safeD(tail xs)(head xs)(tail xs)(1)的部分内部调用then,并且您可以thenlength xs == 0.

我强烈建议学习一点关于模式匹配的知识(Gentle Intro 部分Haskell Report 部分)并尝试编写整个代码片段而无需调用head, tail, init,lastlength. 相反,使用这两种模式[]来匹配空列表和(x:xs)(或类似的)模式来匹配以;开头x和结尾的列表。xs如有必要,reverse偶尔打个电话就可以了。

祝你好运,让我们知道你的情况以及你卡在哪里!

于 2013-08-20T21:19:31.147 回答
3

有没有想过先为零皇后解决这个问题?

那么对于一位女王呢?

然后发现归纳/递归模式?..我没有引用 3-liner 解决方案,因为它看起来像你的作业。

于 2013-08-21T16:13:08.187 回答