; casting out nines

(define-syntax assert
  (syntax-rules ()
    ((assert expr result)
      (if (not (equal? expr result))
          (for-each display `(
            #\newline "failed assertion:" #\newline
            expr #\newline "expected: " ,result
            #\newline "returned: " ,expr #\newline))))))

(define (nines n)
  (let loop ((n n) (s 0))
    (if (< 0 n)
        (let ((q (quotient n 10))
              (r (remainder n 10)))
          (loop q (+ r s)))
        (if (< 9 s) (nines s)
          (if (= 9 s) 0 s)))))

(display (do ((n 0 (+ n 1))) ((= n 1000) 'done)
    (assert (nines n) (modulo n 9))))
(newline)

(display
  (= (nines (+ (nines  3074)
               (nines  6017)
               (nines 13814)
               (nines  1810)
               (nines    27)
               (nines  3611)))
     (nines           28353)))