Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert List to Matrix (Haskell)

Tags:

haskell

matrix

I'm trying to convert a list to an array (list of lists) from a function that receives an Int (i) that is a counter that always starts at 0, another Int (n) that is the length of each row and the list that I have to convert to matrix.

createMatrix :: (Int, Int, [Int]) -> [[Int]]
createMatrix (i, n, ([])) = []
createMatrix (i, n, (x:y)) = if (i < n) then [x] : createMatrix (i+1, n, (y))
                            else  [] ++ createMatrix (0, n, (x:y))

This gives me as output:  

[[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17],[18]]

when it should be something like:  

[[1,2,3,4,5,6],[7,8,9,10,11,12],[13,14,15,16,17,18]]

in case n is 6

Does anyone have an idea that I may be failing? I tried several things and found no solution.

Thanks

like image 903
Fcr Avatar asked Dec 05 '25 22:12

Fcr


2 Answers

You're always adding an entire new list to your output when you write [x]:createMatrix (...). And when you do [] ++ createMatrix (...), you aren't doing anything to your result; concating an empty list does nothing.

You want to prepend x to the first list in the result of createMatrix (...), instead of prepending [x] to the entire result.

In the else case, you want to prepend a new empty list, rather than trying to use ++, which concatenates two lists.

like image 178
Izaak Weiss Avatar answered Dec 08 '25 20:12

Izaak Weiss


An alternate solution that does without the counter and simply splits your list every given n:

matrixEvery :: Int -> [a] -> [[a]]
matrixEvery _ [] = []
matrixEvery n xs = as : matrixEvery n bs
  where (as,bs) = matrixEvery n xs

Recursion is being used instead of passing around a counter. The only downfall is you if you want to make your matrices all of equal sizes this won't work but get's you closer :)

like image 43
cmdv Avatar answered Dec 08 '25 20:12

cmdv