; zeroing a matrix
(define (make-matrix rows columns . value)
(do ((m (make-vector rows)) (i 0 (+ i 1)))
((= i rows) m)
(if (null? value)
(vector-set! m i (make-vector columns))
(vector-set! m i (make-vector columns (car value))))))
(define (matrix-rows x) (vector-length x))
(define (matrix-cols x) (vector-length (vector-ref x 0)))
(define (matrix-ref m i j) (vector-ref (vector-ref m i) j))
(define (matrix-set! m i j x) (vector-set! (vector-ref m i) j x))
(define-syntax for
(syntax-rules ()
((for (var first past step) body ...)
(let ((ge? (if (< first past) >= <=)))
(do ((var first (+ var step)))
((ge? var past))
body ...)))
((for (var first past) body ...)
(let* ((f first) (p past) (s (if (< first past) 1 -1)))
(for (var f p s) body ...)))
((for (var past) body ...)
(let* ((p past)) (for (var 0 p) body ...)))))
(define (adjoin x xs)
(if (member x xs) xs
(cons x xs)))
(define (zero mtrx)
(let ((rows (list)) (cols (list))
(n-rows (matrix-rows mtrx))
(n-cols (matrix-cols mtrx)))
(for (row 0 n-rows)
(for (col 0 n-cols)
(when (zero? (matrix-ref mtrx row col))
(set! rows (adjoin row rows))
(set! cols (adjoin col cols)))))
(do ((rows rows (cdr rows))) ((null? rows))
(for (col 0 n-cols)
(matrix-set! mtrx (car rows) col 0)))
(do ((cols cols (cdr cols))) ((null? cols))
(for (row 0 n-rows)
(matrix-set! mtrx row (car cols) 0)))
mtrx))
(display (zero '#(#(0 2 3 4 5)
#(1 0 3 4 5)
#(1 2 0 4 5)
#(1 2 3 0 5)
#(1 2 3 4 0))))