; damm algorithm
; http://en.wikipedia.org/wiki/Damm_algorithm
(define (digits n . args)
(let ((b (if (null? args) 10 (car args))))
(let loop ((n n) (d '()))
(if (zero? n) d
(loop (quotient n b)
(cons (modulo n b) d))))))
(define damm '#(
#(0 3 1 7 5 9 8 6 4 2)
#(7 0 9 2 1 5 4 8 6 3)
#(4 2 0 6 8 7 1 3 5 9)
#(1 7 5 0 9 8 3 4 2 6)
#(6 1 2 3 0 4 5 9 7 8)
#(3 6 7 4 2 0 9 5 8 1)
#(5 8 6 9 7 2 0 1 3 4)
#(8 9 4 5 3 6 2 0 1 7)
#(9 4 3 8 6 1 7 2 0 9)
#(2 5 8 1 4 3 6 7 9 0)))
(define (check num)
(let loop ((d 0) (ds (digits num)))
(if (null? ds) (+ (* num 10) d)
(loop (vector-ref (vector-ref damm d) (car ds)) (cdr ds)))))
(define (valid? num)
(let loop ((d 0) (ds (digits num)))
(if (null? ds) (zero? d)
(loop (vector-ref (vector-ref damm d) (car ds)) (cdr ds)))))
(display (check 572)) (newline)
(display (valid? 5724)) (newline)