#!/usr/local/bin/guile \
-e main -s
!#

;;; $Id: matrix.guile,v 1.6 2001/06/29 23:12:37 doug Exp $
;;; http://www.bagley.org/~doug/shootout/
;;; with help from Brad Knotwell

(define size 30)

(define (mkmatrix rows cols)
  (define count 1)
  (define (set-row cols)
    (let ((row (make-vector cols 0)))
      (do ((i 0 (1+ i)))
      ((= i cols) row)
    (begin (vector-set! row i count) (set! count (1+ count))))))
  (let ((mx (make-vector rows cols)))
    (begin (array-map-in-order! mx set-row mx) mx)))
  
(define (mmult rows cols m1 m2)
  (let ((m3 (make-vector rows 0)))
    (do ((i 0 (+ i 1)))
    ((= i rows))
      (let ((m1i (vector-ref m1 i))
        (row (make-vector cols 0)))
    (do ((j 0 (+ j 1)))
        ((= j cols))
      (let ((val 0))
        (do ((k 0 (+ k 1)))
        ((= k cols))
          (set! val (+ val (* (vector-ref m1i k)
                  (vector-ref (vector-ref m2 k) j)))))
        (vector-set! row j val)))
    (vector-set! m3 i row)))
    m3))

(define (main args)
  (let ((n (or (and (= (length args) 2) (string->;number (cadr args))) 1))
    (m1 (mkmatrix size size))
    (m2 (mkmatrix size size))
    (mm 0))
    (do ((i 0 (1+ i)))
    ((= i n) (begin 
           (display (vector-ref (vector-ref mm 0) 0)) (display " ")
           (display (vector-ref (vector-ref mm 2) 3)) (display " ")
           (display (vector-ref (vector-ref mm 3) 2)) (display " ")
           (display (vector-ref (vector-ref mm 4) 4)) (newline)))
    (set! mm (mmult size size m1 m2)))))