比较矩阵中的Bool值

时间:2010-10-31 14:47:24

标签: haskell

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

这是一个示例矩阵:

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

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

例如:anzNachbarn [[True,False,False],[True,False,False],[False,True,False]](0,1)

返回2。

:修改

我仍然有一个问题,我现在如何实现结果矩阵的每个组件,具有True相邻字段的命名元素的数量表示参数矩阵的相应组件适用于

[[True,False,False],

[真,假,假],

[False,True,False]]

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

2 个答案:

答案 0 :(得分: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)为中心的三乘三方位的9个位置的指数(如果你不想考虑角落的邻居,你需要做一个小改动)。 / p>

第一个守卫(x' /= y')忽略(x, y)本身。第二个抛出不在数组范围内的位置。最后的守卫抛出阵列中的位置,但值为False

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

答案 1 :(得分: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)]]

请注意,这种表现非常糟糕。