在Haskell中构造一个函数,如果有三个相等且后跟对角线元素的列表,则返回"True"



我需要在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。

最新更新