[plt-scheme] HTDP 27.5.6

From: wooks . (wookiz at hotmail.com)
Date: Fri Jul 28 19:10:44 EDT 2006

My solution to 27.5.5 accomplished the switch by moving the top row to the 
bottom of the matrix.

However coming to Ex 27.5.6 I can see that if all the remaining first row 
cells are zero I will infinitely loop. Now ok I could check if thats the 
case and handle it in some way. Alternatively I could pre sort the matrix by 
descending 1st colmumn which would eliminate the need for any switching, but 
I am getting an uneasy feeling about this solution esp since the fact I 
didn't recourse to the hint in 27.5.5 shows some divergent thinking from the 

Have I or am I about to take a wrong turn.

Here is what I have as the result of 27.5.5 (I have annotated the code with 
some extras that I felt were needed).

;triangulate : [[num]] -> [[num]]
;produces a matrix in lower echelon form
(define (triangulate matrix)
    [(empty? matrix) empty]
    [else (local ((define top-row (first matrix)))
              [(zero? (first top-row)) (triangulate (append (rest matrix) 
(list top-row)))]
              [else (cons top-row
                          (triangulate (map (lambda (current-row) (subtract 
top-row current-row))
                                            (rest matrix))))]))]))

;subtract: [number] [number] -> [number]
;repetitively subtracts the 1st list from the 2nd until the 1st cell of the 
2nd list is eliminated
(define (subtract lista listb)
    [(empty? listb) empty]
    [(zero? (first listb)) (rest listb)]

    ;;ensures that 1st cell in listb is a multiple of the first cell in 
    ;;otherwise we will infinitely loop trying to eliminate the cell in 
    [(not (zero? (remainder (first listb) (first lista))))
     (subtract lista (map (lambda (cell) (* (first lista) cell)) listb))]

    ;;determines whether elimination is accomplished by addition or 
    [else (local ((define op (if (or (and (< (first listb) 0)
                                          (< (first lista) 0))
                                     (and (> (first listb) 0)
                                          (> (first lista) 0))) - +))
                  (define (subEach lista listb)
                      [(empty? lista) empty]
                      [else (cons (op (first listb) (first lista))
                                  (subEach (rest lista) (rest listb)))])))
            (subtract lista (subEach lista listb) ))]))

Posted on the users mailing list.