创建所有''小''来自更大的矩阵 - Haskell

时间:2016-03-18 22:08:36

标签: haskell matrix

我有一个矩形矩阵,包含B或N的情况。矩阵的一个例子:

g0 = [[B,B,B,B,B,B,N],
      [B,B,N,B,N,B,B],
      [N,B,N,N,N,N,N],
      [B,B,B,N,N,B,N],
      [N,N,N,B,B,B,B],
      [B,B,B,N,N,B,N]]

我有一个像[Int,Int,Int,Int]这样的类型矩形和一个从我的矩阵中获得这种类型的较小矩形矩阵的函数。这是功能,但这不是最重要的部分:

getRectangle :: Rectangle -> Grille -> Grille -- cette fonction récupère la grille qui correspond au rectangle donné
getRectangle (i,j,l,c) g = transpose (getLigne (j,c,(nbLigne (transpose g0))) (transpose (getLigne (i,l,(nbLigne g0)) g0)))
--transpose get create a matrix with (n,m) = (lines,columns) in a matrix (m,n) and nbLigne return the number of lines (or columns when used with transpose) of a matrix.

getLigne :: (Int,Int,Int) -> Grille -> Grille 
getLigne (i,l,0) g = []                     
getLigne (1,l,1) g = [head g]                
getLigne (i,l,indice) [] = []
getLigne (i,l,indice) g         
    | indice == (i+l) =  getLigne (i,l,(indice-1)) (init g) ++ [last g]
    | indice == i = [last g]
    | i < indice && indice < (i+l) = getLigne (i,l,(indice-1)) (init g) ++ [last g]
    | otherwise = getLigne (i,l,(indice-1)) (init g)

以下是一个例子:

*Main> affiche (getRectangle (1,2,2,3) g0)
[B,B,B,B]
[B,N,B,N]
[B,N,N,N]

所以,我有一个(i,j,l,c)的元组。知道1<=i<i+l<=n1<=j<j+c<=m,其中n是矩阵的行数,m是列数。 要清楚,使用元组(i,j,l,c),我的函数会根据我的矩阵创建一个矩形,由以下几种情况组成:(i,j)(i+l,j)(i,j+c)和{{1} }。

现在我可以创建一个矩形,我需要在任何矩阵中创建所有可能的矩形。我对如何做到这一点没有任何线索,因为我觉得在一个矩阵中有这么多的矩形并覆盖所有的情况对我来说似乎很难和很长。

也许我在某些方面并不清楚,随便问一下。

1 个答案:

答案 0 :(得分:1)

Salut :),

对于组合,我经常使用列表monad。 请注意,使用这样的do表示法等同于使用列表推导

从一个位置,您可以推导出所有可能来自给定点的矩形:

allRectsOriginatingFrom :: Point -> Grille -> [Rectangle]
allRectsOriginatingFrom (x, y) g
    -- Si le point est dans ta grille...
    | (x >= 1 && x <= width g) && (y >= 1 && y <= height g) = do
        w <- [0 .. width g - x]
        h <- [0 .. height g - y]
        return (x, y, w, h)
    -- Sinon y'a pas de rectangle possible
    | otherwise = [] 

从那里,您只需将功能映射到网格上的所有可能位置:

allPointsOf :: Grille -> [Point]
allPointsOf g = do
    x <- [1 .. width g]
    y <- [1 .. height g]
    return (x, y)

allRectsOf :: Grille -> [Rectangle]
allRectsOf g = do
    pos <- allPointsOf g
    allRectsOriginatingFrom pos g

最后,使用getLigne函数映射它将获得网格中的每个矩形。

PS:尝试创建数据类型而不是类型别名,我认为它更好(例如创建类似data Rectangle = Rectangle Int Int Int Int而不是type Rectangle = (Int, Int, Int, Int)的数据类型。)