Question

I have been trying to write function which returns the transpose of a matrix . so an example output would be, (transpose (list '(1 2) '(4 5))) ;==> ((1 4) (2 5)) Here is my function:

(define transpose
  (lambda (m1)
    (if (null? (cadr m1))
        null
        (list (indiv (car m1) (cadr m1)) (transpose (rest m1)))))) 


(define indiv 
  (lambda (l1 l2)
    (if (empty? l1)
        null
        (list (list (car l1) (car l2)) (indiv (rest l1) (rest l2))))))

the indiv function takes care of the rows recursion whereas transpose calls the indiv function to get the transpose. My question is why doesn't (if (null? (cadr m1)) work in order to check that I have reached the last row of the matrix? is there any possible way to check this in scheme? I don't want another way to solve this problem, I just want to know if this is possible and if yes then how?

Was it helpful?

Solution 2

Using map is really going to simplify things.

 (define transpose
      (lambda (m1)
        (if (null? (car m1))
            null
            (cons (map car m1) 
                  (transpose (map cdr m1)))))) 

Rest is usually the same as cdr, and you don't want that, you want to map cdr onto the matrix representation to get past the first row. You've done this in indiv nicely, but the problem is it won't scale to larger matrices.

The reason your doesn't work is it calls tranpose on the rest of '((1 2) (4 5)) which is '((4 5)) whose cdr has no car. (it's the null list) and you hit an error.

OTHER TIPS

This is a rather common function, the usual way to implement it is:

(define (transpose lst)
  (apply map list lst))

Think of lst as a list of lists which will be passed as parameters to map, and remember that map accepts more than one input list as parameter:

(map list '(1 2) '(4 5))

Now it's easy to see what's happening: we're mapping list over all the arguments and building a sublist with the first element of the first input list and the first element of the second input list, etc. Then, we'll build a sublist with the second element of the first input list and the second element of the second input list, etc. and so on. And map collects all of the sublists in a single output list. There you go!

'((1 4) (2 5))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top