Pythagorean triples: Difference between revisions

→‎{{header|Perl 6}}: faster to avoid gather/take
(→‎{{header|Perl 6}}: typos, more explanation)
(→‎{{header|Perl 6}}: faster to avoid gather/take)
Line 454:
{{works with|niecza}}
<lang perl6>sub triples($limit) {
my $primitive = 0;
 
my $civilized = 0;
sub oyako($a, $b, $c) {
my $perim = $a + $b + $c;
return if $perim > $limit;
++$primitive; take 1$civilized += ($limit div $perim)i;
oyako( $a - 2*$b + 2*$c, 2*$a - $b + 2*$c, 2*$a - 2*$b + 3*$c);
oyako( $a + 2*$b + 2*$c, 2*$a + $b + 2*$c, 2*$a + 2*$b + 3*$c);
oyako(-$a + 2*$b + 2*$c, -2*$a + $b + 2*$c, -2*$a + 2*$b + 3*$c);
}
 
my $complex = 0i + [+] gather oyako(3,4,5);
"$limit => ({$complex.re,primitive $complex.im}civilized)";
}
 
for 10,100,1000 ... * -> $limit {
say triples $limit;
Line 474 ⟶ 476:
<pre>10 => (0 0)
100 => (7 17)
1000 => (70 32510000 => (703 4858325)
10000 => (703 4858)
100000 => (7026 64741)
1000000 => (70229 808950)
10000000 => (702309 9706567)
100000000 => (7023027 113236940)
1000000000 => (70230484 1294080089)
^C</pre>
Note the cute trick of adding complex numbers to add two numbers in parallel. Also, theThe geometric sequence of limits will continue on forever, so eventually when you get tired of thrashingwaiting (at about 100a millionbillion on my computer), you can just stop it. Another efficiency trick of note: we avoid passing the limit in as a parameter to the inner helper routine, but instead supply the limit via the lexical scope. TheLikewise, usethe ofaccumulators <tt>gather</tt>/<tt>take</tt>are allowsreferenced thelexically, summationso toonly runthe intriples athemselves differentneed threadto thanbe the helperpassed functiondownward, atand leastnothing inneeds theory..to be returned.
 
Here is an alternate version that avoids naming any scalars that can be handled by vector processing instead:
Line 506 ⟶ 511:
}</lang>
Using vectorized ops allows a bit more potential for parallelization, though this is probably not as big a win in this case, especially since we do a certain amount of multiplying by 1 that the scalar version doesn't need to do.
Note the cute trick of adding complex numbers to add two numbers in parallel.
The use of <tt>gather</tt>/<tt>take</tt> allows the summation to run in a different thread than the helper function, at least in theory...
 
In practice, this solution runs considerably slower than the previous one, due primarily to passing <tt>gather</tt>/<tt>take</tt> values up many levels of dynamic scope. Eventually this may be optimized. Also, this solution currently chews up gigabytes of memory, while the previous solution stays at a quarter gig or so. This likely indicates a memory leak somewhere in [[niecza]].
 
=={{header|Python}}==
Anonymous user