Write a function that accepts an integer matrix and returns a copy of the matrix in which each the zero value in the original matrix has been smeared along the row and column containing it in the copy.
$ cat mzr.rkt #lang racket (require math/matrix) (define (matrix-zero-runs m) ; Return a copy of the given integer matrix m. The copy has a ; zero row and column intersecting at the location of every ; zero element in m. ; This code is disgusting. (define (zero-row-info) ; Return ; ; a list of boolean zero-row indicators. The ith element in the ; list is #t iff the ith row contains a zero element. ; ; a row vector in which each element is either zero iff at least ; one column in m contains a corresponding zero element or one ; otherwise (that is, iff every column in m has a corresponding ; non-zero element). (let* ((zri (make-vector (matrix-num-rows m) #f)) (zri-check (lambda (ri e) (vector-set! zri ri (or (= e 0) (vector-ref zri ri)))))) (let loop ((r (- (matrix-num-rows m) 1)) (rzm (make-matrix 1 (matrix-num-cols m) 1))) (if (< r 0) (values (vector->list zri) rzm) (loop (- r 1) (matrix-map (lambda (e1 e2) (zri-check r e1) (if (or (= e1 0) (= e2 0)) 0 1)) (matrix-row m r) rzm)))))) (let-values (((zero-row-indices zero-col-mask) (zero-row-info))) (let ((zero-row (make-matrix 1 (matrix-num-cols m) 0))) (matrix-map-rows (lambda (row) (let ((zr (car zero-row-indices))) (set! zero-row-indices (cdr zero-row-indices)) (if zr zero-row (matrix-map * row zero-col-mask)))) m)))) (require rackunit) (check-equal? (matrix-zero-runs (matrix [[0]])) (matrix [[0]])) (check-equal? (matrix-zero-runs (matrix [[1]])) (matrix [[1]])) (check-equal? (matrix-zero-runs (matrix [[1 0][0 1]])) (make-matrix 2 2 0)) (check-equal? (matrix-zero-runs (matrix [[0 1][1 0]])) (make-matrix 2 2 0)) (check-equal? (matrix-zero-runs (matrix [[0 1][1 1]])) (matrix [[0 0][0 1]])) (check-equal? (matrix-zero-runs (matrix [[1 0][1 1]])) (matrix [[0 0][1 0]])) (check-equal? (matrix-zero-runs (matrix [[1 1][0 1]])) (matrix [[0 1][0 0]])) (check-equal? (matrix-zero-runs (matrix [[1 1][1 0]])) (matrix [[1 0][0 0]])) $ mzscheme mzr.rkt $