; geothmetic meandian

(define (agm x y)
  (let loop ((a (max x y)) (g (min x y)))
    (if (< (/ a g) 1.00000001)
        (/ (+ a g) 2)
        (loop (/ (+ a g) 2) (sqrt (* a g))))))

(define (gm . xs)
  (define (median3 a b c)
    (cond ((or (<= b a c) (<= c a b)) a)
          ((or (<= a b c) (<= c b a)) b)
          (else c)))
  (let* ((len (length xs))
         (a (/ (apply + xs) len))
         (g (expt (apply * xs) (/ len)))
         (m (list-ref (sort xs <) (quotient len 2))))
    (let loop ((a a) (g g) (m m))
      (if (and (< (/ a g) 1.00000001)
               (< (/ a m) 1.00000001)
               (< (/ g m) 1.00000001))
          (/ (+ a g) 2)
          (loop (/ (+ a g m) 3)
                (expt (* a g m) 1/3)
                (median3 a g m))))))

(display (agm 24 6)) (newline)
(display (gm 1 1 2 3 5)) (newline)