Reputation: 103
I want a function that takes a integer n
, and a square matrix of size (n*n) x (n*n)
, and returns a matrix where each chunk (of size n x n
) is now a row, ordering chunks by going from left-to-right, then top-to-bottom.
For example:
type Matrix a = [[a]]
chunks :: Int -> Matrix a -> Matrix a
chunks n = ...
Example : chunks 2 a == b
a b
+--+--+ +--+--+
|ab|cd| |ab|ef|
|ef|gh| |cd|gh|
+--+--+ --> +--+--+
|ij|kl| |ij|mn|
|mn|op| |kl|op|
+--+--+ +--+--+
Example : chunks 3 c == d
c d
+---+---+---+ +---+---+---+
|abc|def|ghi| |abc|jkl|stu|
|jkl|mno|pqr| |def|mno|vwx|
|stu|vwx|yzA| |ghi|pqr|yzA|
+---+---+---+ +---+---+---+
|BCD|EFG|HIJ| |BCD|KLM|TUV|
|KLM|NOP|QRS| --> |EFG|NOP|WXY|
|TUV|WXY|Z$%| |HIJ|QRS|Z$%|
+---+---+---+ +---+---+---+
|...|...|...| |...|...|...|
|...|...|...| |...|...|...|
|...|...|...| |...|...|...|
+---+---+---+ +---+---+---+
*** Edit:
The answer:
chunks :: Int -> [[a]] -> [[a]]
chunks n m = concat (map chunks' (splitEvery n m))
where
chunks' :: [[a]] -> [[a]]
chunks' m = map concat (transpose (map (splitEvery n) m))
I suppose I should define splitEvery
too:
splitEvery :: Int -> [a] -> [[a]]
splitEvery _ [] = []
splitEvery n xs = chunk : (splitEvery n xxs)
where
(chunk, xxs) = splitAt n xs
Upvotes: 1
Views: 129
Reputation: 52029
Here are some hints:
Note that some elements always stay together. For example, in the 2x2 case "ab"
stays together, as does "cd"
, "ef"
, "gh"
, etc. In fact, you canvisualize the transformation this way:
+---+---+ +---+---+
| 1 | 2 | | 1 | 3 | 1 = ab
| 3 | 4 | | 2 | 4 | 2 = cd
+---+---+ ---> +---+---+ 3 = ef
| 5 | 6 | | 5 | 7 | 4 = gh
| 7 | 8 | | 6 | 8 | 5 = ...
+---+---+ +---+---+
And observe how each row gets transformed:
1 2 -> 1 3
3 4 2 4
5 6 -> 5 7
7 8 6 8
Think about your linear algebra class. Do these transformations look familiar? Note that the diagonal elements don't move.
Now have a look at this section from the Data.List
docs, and
see if one of those functions seems applicable:
https://hackage.haskell.org/package/base-4.8.1.0/docs/Data-List.html#g:2
Upvotes: 2