; matrix fill-in

(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 (fill-in m)
  (let ((nrows (matrix-rows m))
        (ncols (matrix-cols m))
        (xs (list)))
    (for (r 0 nrows)
      (for (c 0 ncols)
        (when (= (matrix-ref m r c) 1)
          (set! xs (cons (cons r c) xs)))))
    (let loop ((xs xs))
      (cond ((null? xs) m)
      (else (for (r 0 nrows)
              (matrix-set! m r (cdar xs) 1))
            (for (c 0 ncols)
              (matrix-set! m (caar xs) c 1))
            (loop (cdr xs)))))))

(display
  (fill-in '#(
    #(0 0 0 0 0)
    #(0 0 0 0 0)
    #(0 0 0 1 0)
    #(1 0 0 0 0)
    #(0 0 0 0 0))))