; monkeys and coconuts
(define (range . args)
(case (length args)
((1) (range 0 (car args) (if (negative? (car args)) -1 1)))
((2) (range (car args) (cadr args) (if (< (car args) (cadr args)) 1 -1)))
((3) (let ((le? (if (negative? (caddr args)) >= <=)))
(let loop ((x(car args)) (xs '()))
(if (le? (cadr args) x)
(reverse xs)
(loop (+ x (caddr args)) (cons x xs))))))
(else (error 'range "unrecognized arguments"))))
(define (coconuts sailors)
(let loop ((nuts sailors) (left sailors)
(takes sailors) (result (list)))
(cond ((and (zero? takes) (zero? (modulo left sailors)))
(reverse (cons (list left (quotient left sailors) 0) result)))
((and (positive? takes) (= (modulo left sailors) 1))
(loop nuts (- left (quotient left sailors) 1) (- takes 1)
(cons (list left (quotient left sailors) 1) result)))
(else (loop (+ nuts 1) (+ nuts 1) sailors (list))))))
(display (coconuts 5)) (newline)
(display (coconuts 6)) (newline)
(define (coconuts n)
(if (odd? n)
(- (expt n n) n -1)
(* (- n 1) (- (expt n n) 1))))
(display (map coconuts (range 31))) (newline)