; monkey grid puzzle
(define (sum xs) (apply + xs))
(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 (make-matrix rows columns . value)
(do ((m (make-vector rows)) (i 0 (+ i 1)))
((= i rows) m)
(if (null? value)
(vector-set! m i (make-vector columns))
(vector-set! m i (make-vector columns (car value))))))
(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 (legit? x y)
(< (+ (sum (digits x)) (sum (digits y))) 20))
(define (count x y)
(cond ((and (zero? x) (zero? y)) 1) ; origin
((or (zero? x) (zero? y)) 2) ; axis
(else 4))) ; other points
(define visited (make-matrix 301 301 #f))
(define (monkey x y)
(if (matrix-ref visited x y) 0
(begin (matrix-set! visited x y #t)
(if (not (legit? x y)) 0
(+ (count x y)
(monkey (+ x 1) y)
(monkey x (+ y 1)))))))
(display (monkey 0 0))