Reputation: 373
I have a rectangular matrix with cases containing B or N. An example of matrix:
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]]
I have a type rectangle like [Int,Int,Int,Int]
and a function that gets a smaller rectangular matrix from my matrix with this type. Here's the function but that's not the most important part:
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)
Here's an example:
*Main> affiche (getRectangle (1,2,2,3) g0)
[B,B,B,B]
[B,N,B,N]
[B,N,N,N]
So, I have a tuple with (i,j,l,c)
. Knowing that 1<=i<i+l<=n
and 1<=j<j+c<=m
with n the number of lines of the matrix and m the number of columns.
To be clear, with a tuple (i,j,l,c)
, my function create a rectangle, from my matrix, formed with these cases: (i,j)
, (i+l,j)
, (i,j+c)
and (i+l,j+c)
.
Now that I can create a single rectangle, I need to create all the possibles rectangles in any matrix. I don't have any clue on how I can do this since I feel like there is so many rectangles in a single matrix and cover all the cases seems very hard and long to me.
Maybe that I wasn't clear on some points, feel free to ask.
Upvotes: 0
Views: 114
Reputation: 1494
Salut :),
For combinations, I often work with the list monad.
Note that using the do
notation like this is equivalent to working with list comprehensions
From a position you can deduce all the rectangles that can originate from a given point:
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 = []
From there, your just have to map the function over all the possible positions on your grid:
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
And finally, mapping it with your getLigne
function will get you every rectangle in your grid.
PS: Try to create datatypes instead of type aliases, it's better in my opinion (e.g. create a datatype like data Rectangle = Rectangle Int Int Int Int
instead of type Rectangle = (Int, Int, Int, Int)
).
Upvotes: 1