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; [[整数]] 你对此有什么想法吗?
答案 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)]]
请注意,这种表现非常糟糕。