Find all over again, then all the second, then all the third, etc. List items in a list

Working with a self-made definition of a (9x9) matrix, described as a list of lists Maybe Int

s. I want to create a function that returns 9 columns of a matrix. I want to do something like:

cols :: Matrix a -> [Block a]
cols matrix = map (!! n) matrix
 where
  n = (the values 1 .. 9)

      

  • The matrix is โ€‹โ€‹described as [Rows]

    or[[values]]

  • The block is described as [a]

So, I want the output to be a list of lists, where these lists are a list of the first line items, the second line items, etc. etc.

I see what

map (!! 1) matrix

      

will return a list of the second elements of the rows, that is, the second column of the matrix; but I don't know how to propagate this to all columns of a matrix in a good function.

+3


source to share


2 answers


I see what

map (!! 1) matrix

      

Returns a list of the second elements of the rows, that is, the second column of the matrix; but I don't know how to propagate this to all columns of a matrix in a good function.

If that's what you want, you can just change it to

map (!!i) matrix

      

in



[map (!!i) matrix | i <- [0.. length (matrix!!0) - 1]]

      

for example

Prelude> let matrix = [[1,2,3],[4,5,6]]
Prelude> [map (!!i) matrix | i <- [0.. length (matrix!!0) - 1]]
[[1,4],[2,5],[3,6]]

      


The problem, of course, is that the complexity is unreasonably high since the complexity !!

is linear in the argument. Instead, you can build a recursive function like this:

  • Suppose you have divided each of the elements of the matrix by head

    and tail

    , respectively

  • Where are head

    all the matching elements in the transposed matrix?

  • What happens if you now try the same on tail

    all elements?

+3


source


If I understand correctly, you want to calculate transpose :: [[a]] -> [[a]]

matrices:

import Data.List(transpose)

cols :: [[a]] -> [[a]]
cols = transpose

      

You can implement it efficiently like this:

cols :: [[a]] -> [[a]]
cols [] = []
cols ([]:_) = []
cols l = (map head l) : cols (map tail l)

      



This code only works for rectangular matrices . The code works like this: if we give cols

an empty list or a list in which the first line is empty, we have reached the end of the transposition, so we return an empty list.

If, on the other hand, there is still a list and the first row contains one element (and since the matrix is โ€‹โ€‹square and the other is), we first take head

all rows as a column and then recurse into tail

rows to calculate the remaining columns.

The function works in O (n) with n number of elements (not rows / columns) of the matrix. Or O (r x c) with r number of rows and c number of columns.

+3


source







All Articles