45 lines
997 B
Perl
45 lines
997 B
Perl
use bigint try=>"GMP";
|
|
sub stream {
|
|
my ($next, $safe, $prod, $cons, $z, $x) = @_;
|
|
$x = $x->();
|
|
sub {
|
|
while (1) {
|
|
my $y = $next->($z);
|
|
if ($safe->($z, $y)) {
|
|
$z = $prod->($z, $y);
|
|
return $y;
|
|
} else {
|
|
$z = $cons->($z, $x->());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
sub extr {
|
|
use integer;
|
|
my ($q, $r, $s, $t) = @{shift()};
|
|
my $x = shift;
|
|
($q * $x + $r) / ($s * $x + $t);
|
|
}
|
|
|
|
sub comp {
|
|
my ($q, $r, $s, $t) = @{shift()};
|
|
my ($u, $v, $w, $x) = @{shift()};
|
|
[$q * $u + $r * $w,
|
|
$q * $v + $r * $x,
|
|
$s * $u + $t * $w,
|
|
$s * $v + $t * $x];
|
|
}
|
|
|
|
my $pi_stream = stream
|
|
sub { extr shift, 3 },
|
|
sub { my ($z, $n) = @_; $n == extr $z, 4 },
|
|
sub { my ($z, $n) = @_; comp([10, -10*$n, 0, 1], $z) },
|
|
\&comp,
|
|
[1, 0, 0, 1],
|
|
sub { my $n = 0; sub { $n++; [$n, 4 * $n + 2, 0, 2 * $n + 1] } },
|
|
;
|
|
$|++;
|
|
print $pi_stream->(), '.';
|
|
print $pi_stream->() while 1;
|