#!/usr/bin/ruby
# https://rosettacode.org/wiki/Arithmetic-geometric_mean
func agm0(a0, g0) {
var (a1, g1);
do {
a1 = float(a0+g0 / 2);
g1 = sqrt(a0 * g0);
a0 = (a1+g1 /2);
g0 = sqrt(a1 * g1);
} while (a0 != a1);
return a0;
}
func agm1(a, g) {
loop {
given (var ag = [float(a+g / 2), sqrt(a*g)]) {
when (a, g) { return a }
default { (a, g) = ag... }
}
}
}
func agm2(a, g) {
loop {
var ag = [float(a+g / 2), sqrt(a*g)];
ag == [a,g] ? return(a) : ((a, g) = ag...);
}
}
const sqrt2 = sqrt(2);
const test = [agm0(1, 1/sqrt2)]*2;
assert_eq([agm1(1, 1/sqrt2), agm2(1, 1/sqrt2)], test);
say "AG: #{test[0]}";