2010-10-31 93 views
0
t = True 
f = False 
anzNachbarn :: [[Bool]] -> (Integer,Integer) -> Integer 
anzNachbarn a (x,y) 
     | x < 0 || y < 0=-1 
     | otherwise ... here comes the comparison 

这是一个例子基质:bool值在矩阵比较

[[True,False,False], 
[True,False,False], 
[False,True,False]] 

在这里,我需要一个算法,它计算(对于给定的x和矩阵y位置)及其邻国(只有“真”邻居),并为每个真正的邻居增加1。

例如:anzNachbarn [[真,FALSE,FALSE],[真,FALSE,FALSE],[假,真,假]](0,1)

返回2背面。

:编辑

我仍然有一个问题,我怎么能现在执行的结果矩阵的每个组成部分,具有真周边领域命名元素的数字表示参数矩阵的相应单元适用于

[[真,FALSE,FALSE],

[真,FALSE,FALSE],

[假,真,假]]

函数func返回结果矩阵[[1,2,0],[2,3,1],[2,1,1]] with signature func :: [[Bool]] - > [[整数]] 你有什么想法吗?

回答

1

这是丑陋的,但似乎工作...

anzNachbarn :: [[Bool]] -> (Int,Int) → Integer 
anzNachbarn a (x,y) 
    | x < 0 || y < 0 = -1 
    | otherwise = sum [v x' y' | x' <- [max 0 (x-1)..x+1], 
           y' <- [max 0 (y-1)..y+1], 
           x ≠ x' || y ≠ y' ] 
    where v i j = if j >= length a 
         || i >= length (a !! 0) 
         || not (a !! j !! i) 
        then 0 else 1 

[编辑]

为了整个数组转换,你可以写同样丑陋

conv a = [line y | y <- [0 .. (length a) - 1]] 
    where line y = [anzNachbarn a (x,y) | x <- [0 .. ((length (a !! 0) - 1)]] 

请注意,这是可怕的表现。

+0

我怎样才能改变索引(整数,整数)为(整数,整数)程序运行正确 – marco 2010-11-01 06:13:45

+0

我仍然有一个问题,我现在怎么能实现结果矩阵的每个组件,用True相邻字段命名的数字表示参数矩阵的相应分量适用于[[True,False,False],[True,False,False],[False,True,False]],函数 转换结果矩阵[[1,2,0], [2,3,1],[2,1,1]]带签名func :: [[Bool]] - > [[Integer]] – marco 2010-11-01 07:08:16

+0

Integer的问题是,那!期望一个Int。所以如果你写'a! (来自整合j)! (来自I积分)'我认为它应该与Integer一起工作。 – Landei 2010-11-01 08:05:12

3

在这种情况下,您几乎可以肯定地想要使用一个数组(从Data.Array),因为通过其索引在列表中查找项目非常缓慢。

这里有一个快速的实现使用Array

countNeighbors :: Array (Int, Int) Bool -> (Int, Int) -> Int 
countNeighbors board (x, y) = length 
    [ (x', y') 
    | x' <- [x - 1, x, x + 1] 
    , y' <- [y - 1, y, y + 1] 
    , x' /= x || y' /= y 
    , inRange (bounds board) (x', y') 
    , board ! (x', y') 
    ] 

这是两个发电机和三个后卫列表理解。发电机只是给我们提供了一个三乘三平方的九个位置的指数,集中在(x, y)(如果你不想让拐角处的邻居被考虑,你需要做一些小的改动)。 (x' /= y')忽略(x, y)本身。第二个抛出不在数组边界内的位置。最后一名后卫抛出阵列中的位置,但具有False的值。

因此,我们现在有一个True值的邻居索引列表。该列表的长度是所需的计数。

+0

谢谢你的帮助,但我需要它没有阵列 – marco 2010-10-31 16:53:17

+0

护卫'x'/ = y''去除沿对角线的所有值,而不是忽略给定的值。我认为你的意思是'x'/ = x || y'/ = y'。 – Paul 2010-11-02 05:30:28

+0

@保罗:你当然是对的。我输入的太快了,但现在已经修复了。 – 2010-11-02 07:08:08