Sync
This commit is contained in:
parent
6f050a029e
commit
776bba907c
3887 changed files with 59894 additions and 7280 deletions
|
|
@ -1,41 +1,33 @@
|
|||
# based on http://www.mathpropress.com/stan/bibliography/spigot.pdf
|
||||
|
||||
sub stream(&next, &safe, &prod, &cons, $z is copy, @x) {
|
||||
my $x-list = @x.iterator.list;
|
||||
gather loop {
|
||||
my $y = next($z);
|
||||
if safe($z, $y) {
|
||||
take $y;
|
||||
$z = prod($z, $y);
|
||||
} else {
|
||||
$z = cons($z, $x-list.shift);
|
||||
}
|
||||
$z = safe($z, my $y = next($z)) ??
|
||||
prod($z, take $y) !!
|
||||
cons($z, @x[(state $)++])
|
||||
}
|
||||
}
|
||||
|
||||
sub extr([$q, $r, $s, $t], $x) {
|
||||
($q * $x + $r) div ($s * $x + $t);
|
||||
($q * $x + $r) div ($s * $x + $t)
|
||||
}
|
||||
|
||||
my $unit = [1, 0, 0, 1];
|
||||
|
||||
sub comp([$q,$r,$s,$t], [$u,$v,$w,$x]) {
|
||||
[$q * $u + $r * $w,
|
||||
$q * $v + $r * $x,
|
||||
$s * $u + $t * $w,
|
||||
$s * $v + $t * $x];
|
||||
$s * $v + $t * $x]
|
||||
}
|
||||
|
||||
sub pi-stream() {
|
||||
my @pi :=
|
||||
stream -> $z { extr($z, 3) },
|
||||
-> $z, $n { $n == extr($z, 4) },
|
||||
-> $z, $n { comp([10, -10*$n, 0, 1], $z) },
|
||||
&comp,
|
||||
$unit,
|
||||
<1 0 0 1>,
|
||||
(1..*).map: { [$_, 4 * $_ + 2, 0, 2 * $_ + 1] }
|
||||
|
||||
loop {
|
||||
print @pi.shift;
|
||||
once print '.'
|
||||
}
|
||||
|
||||
my @pi := pi-stream;
|
||||
|
||||
print @pi[0], '.';
|
||||
print @pi[$_] for 1..*;
|
||||
|
|
|
|||
44
Task/Pi/Perl/pi-1.pl
Normal file
44
Task/Pi/Perl/pi-1.pl
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
use bigint;
|
||||
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;
|
||||
55
Task/Pi/Perl/pi-2.pl
Normal file
55
Task/Pi/Perl/pi-2.pl
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
use Math::BigInt;
|
||||
use bigint;
|
||||
|
||||
# Pi/4 = 4 arctan 1/5 - arctan 1/239
|
||||
# expanding it with Taylor series with what's probably the dumbest method
|
||||
|
||||
my ($ds, $ns) = (1, 0);
|
||||
my ($n5, $d5) = (16 * (25 * 3 - 1), 3 * 5**3);
|
||||
my ($n2, $d2) = (4 * (239 * 239 * 3 - 1), 3 * 239**3);
|
||||
|
||||
sub next_term {
|
||||
my ($coef, $p) = @_[1, 2];
|
||||
$_[0] /= ($p - 4) * ($p - 2);
|
||||
$_[0] *= $p * ($p + 2) * $coef**4;
|
||||
}
|
||||
|
||||
my $p2 = 5;
|
||||
my $pow = 1;
|
||||
|
||||
$| = 1;
|
||||
for (my $x = 5; ; $x += 4) {
|
||||
($ns, $ds) = ($ns * $d5 + $n5 * $pow * $ds, $ds * $d5);
|
||||
|
||||
next_term($d5, 5, $x);
|
||||
$n5 = 16 * (5 * 5 * ($x + 2) - $x);
|
||||
|
||||
while ($d5 > $d2) {
|
||||
($ns, $ds) = ($ns * $d2 - $n2 * $pow * $ds, $ds * $d2);
|
||||
$n2 = 4 * (239 * 239 * ($p2 + 2) - $p2);
|
||||
next_term($d2, 239, $p2);
|
||||
$p2 += 4;
|
||||
}
|
||||
|
||||
my $ppow = 1;
|
||||
while ($pow * $n5 * 5**4 < $d5 && $pow * $n2 * $n2 * 239**4 < $d2) {
|
||||
$pow *= 10;
|
||||
$ppow *= 10;
|
||||
}
|
||||
|
||||
if ($ppow > 1) {
|
||||
$ns *= $ppow;
|
||||
#FIX? my $out = $ns->bdiv($ds); # bugged?
|
||||
my $out = $ns / $ds;
|
||||
$ns %= $ds;
|
||||
|
||||
$out = ("0" x (length($ppow) - length($out) - 1)) . $out;
|
||||
print $out;
|
||||
}
|
||||
|
||||
if ( $p2 % 20 == 1) {
|
||||
my $g = Math::BigInt::bgcd($ds, $ns);
|
||||
$ds /= $g;
|
||||
$ns /= $g;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue