我需要在Haskell中构造一个辅助函数,例如:让A是一个矩阵,例如:
[[10,2, 3, 4]
,[5, 10,10,8]
,[9, 10,10,12]
,[10,14,15,16]]
如果至少有一个后面跟三个十的对角线列表,则返回一个布尔值,因此:
*Main> [[10,2,3,4],[5,10,10,8],[9,10,10,12],[10,14,15,16]]
result: True
因为在上面的矩阵中,我们在主对角线上有三个10,在另一个对角线上有两个10(在这种情况下,两个对角线分别是主对角线和次对角线。但不一定是这样(这个代码计算矩阵的主对角线:
diagonal :: [[Int]] -> [Int]
diagonal [] = []
diagonal (x:xs) = head x : diagonal (map tail xs)
但我需要对任何对角线求解,而不必对平方矩阵求解。
我还做了一个函数,将3乘3分组,但我不知道如何";"连接";与之前的想法:
group3in3:: Int -> [a] -> [[a]]
group3in3 _ [] = [[]]
group3in3n n xs
|n > 0 = (take n xs) : (group3in3 n (drop n xs))
|otherwise = error "Error"
我对哈斯克尔没有太多经验。如有任何帮助,我们将不胜感激。
这里有一些提示。假设你写了一个函数来检查顶层角落是否有三个10的主对角线:
cornertens :: [[Int]] -> Bool
这将为以下矩阵提供True
,仅检查该精确位置的10s:
[[10, 0, 0, 0]
,[ 0,10, 0, 0]
,[ 0, 0,10, 0]
,[ 0, 0, 0, 0]]
现在,您可以编写一个递归函数,不仅在左上角查找这种模式,而且可以从顶行的任何位置开始查找:
toptens :: [[Int]] -> Bool
toptens mtx = cornertens mtx || toptens (map tail mtx)
这个定义不太适用。这是一个没有基本情况的递归函数,所以如果没有找到10s,它是一个无限循环,但你应该能够稍微修改它,这样它就知道什么时候停止递归。一旦它工作起来,它应该能够找到这10个:
[[0, 10, 0, 0, 0]
,[0, 0,10, 0, 0]
,[0, 0, 0,10, 0]
,[0, 0, 0, 0, 0]]
但是如果矩阵全为零,也不挂起。
一旦你做到了这一点,你就应该能够编写一个递归函数,不仅在顶行的任何地方,而且从任何一行开始寻找这种模式:
righthandtens :: [[Int]] -> Bool
righthandtens mtx = toptens mtx || righthandtens (tail mtx)
我在这个方向上从左上到右下叫了十;右手";。同样,这需要修改以知道何时停止,但一旦它工作起来,它就会发现这些10s:
[[0, 0, 0, 0, 0]
,[0, 10, 0, 0, 0]
,[0, 0,10, 0, 0]
,[0, 0, 0,10, 0]
以及在该特定方向上的任何其他10s。如果你在另一个方向上有一个10的矩阵:
[[0, 0, 10, 0]
,[0, 10, 0, 0]
,[10, 0, 0, 0]]
您可以reverse
它的行:
[[10, 0, 0, 0]
,[0, 10, 0, 0]
,[0, 0, 10, 0]]
以更改方向,让您使用righthandtens
找到它。这可以让您定义:
anytens mtx = righthandtens mtx || righthandtens (reverse mtx)
它应该能够在任何对角线上的任何地方找到那些10。