# [plt-scheme] HTDP 27.5.6

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
authors.
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)
(cond
[(empty? matrix) empty]
[else (local ((define top-row (first matrix)))
(cond
[(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)
(cond
[(empty? listb) empty]
[(zero? (first listb)) (rest listb)]
;;ensures that 1st cell in listb is a multiple of the first cell in
lista
;;otherwise we will infinitely loop trying to eliminate the cell in
listb
[(not (zero? (remainder (first listb) (first lista))))
(subtract lista (map (lambda (cell) (* (first lista) cell)) listb))]
;;determines whether elimination is accomplished by addition or
subtraction
[else (local ((define op (if (or (and (< (first listb) 0)
(< (first lista) 0))
(and (> (first listb) 0)
(> (first lista) 0))) - +))
(define (subEach lista listb)
(cond
[(empty? lista) empty]
[else (cons (op (first listb) (first lista))
(subEach (rest lista) (rest listb)))])))
(subtract lista (subEach lista listb) ))]))