[libmath-prime-util-perl] 17/55: Another couple percent speedup for very small factor inputs
Partha P. Mukherjee
ppm-guest at moszumanska.debian.org
Thu May 21 18:53:40 UTC 2015
This is an automated email from the git hooks/post-receive script.
ppm-guest pushed a commit to annotated tag v0.41
in repository libmath-prime-util-perl.
commit 94f19015c476f0da117472af98040b9b70f5aec9
Author: Dana Jacobsen <dana at acm.org>
Date: Fri May 2 13:40:25 2014 -0700
Another couple percent speedup for very small factor inputs
---
factor.c | 26 +++++++++++++++++---------
lib/Math/Prime/Util.pm | 7 ++++---
2 files changed, 21 insertions(+), 12 deletions(-)
diff --git a/factor.c b/factor.c
index 5e4c35a..774ad31 100644
--- a/factor.c
+++ b/factor.c
@@ -61,24 +61,32 @@ int factor(UV n, UV *factors)
while ( (n & 1) == 0 ) { factors[nfactors++] = 2; n /= 2; }
while ( (n % 3) == 0 ) { factors[nfactors++] = 3; n /= 3; }
while ( (n % 5) == 0 ) { factors[nfactors++] = 5; n /= 5; }
+ }
- if (f*f <= n) {
- UV sp = 3;
- UV const lastsp = (n < 20000000) ? NPRIMES_SMALL-1 : 83;
- while (++sp < lastsp) {
- f = primes_small[sp];
+ if (f*f <= n) {
+ UV sp = 4, lastsp = 83;
+ while (sp < lastsp) { /* Trial division from 7 to 421 */
+ if (f*f > n) break;
+ while ( (n%f) == 0 ) {
+ factors[nfactors++] = f;
+ n /= f;
+ }
+ f = primes_small[++sp];
+ }
+ /* If n is small and still composite, finish it here */
+ if (n < 2011*2011 && f*f <= n) { /* Trial division from 431 to 2003 */
+ while (sp < NPRIMES_SMALL) {
if (f*f > n) break;
while ( (n%f) == 0 ) {
factors[nfactors++] = f;
n /= f;
}
+ f = primes_small[++sp];
}
- f = primes_small[sp];
}
}
- if (n < f*f) {
- if (n != 1)
- factors[nfactors++] = n;
+ if (f*f > n) {
+ if (n != 1) factors[nfactors++] = n;
return nfactors;
}
/* Perfect squares and cubes. Factor root only once. */
diff --git a/lib/Math/Prime/Util.pm b/lib/Math/Prime/Util.pm
index 793fd32..533e36a 100644
--- a/lib/Math/Prime/Util.pm
+++ b/lib/Math/Prime/Util.pm
@@ -2899,7 +2899,7 @@ Here is the right way to do PE problem 69 (under 0.03s):
$n++ while pn_primorial($n+1) < 1000000;
say pn_primorial($n);
-Project Euler, problem 187, stupid brute force solution, ~3 minutes:
+Project Euler, problem 187, stupid brute force solution, 2 to 3 minutes:
use Math::Prime::Util qw/forcomposites factor/;
my $nsemis = 0;
@@ -2907,10 +2907,11 @@ Project Euler, problem 187, stupid brute force solution, ~3 minutes:
say $nsemis;
Here is one of the best ways for PE187: under 20 milliseconds from the
-command line. This is faster than Mathematica until C<10^13>.
+command line. Much faster than Pari, and competitive with Mathematica.
use Math::Prime::Util qw/forprimes prime_count/;
- my $limit = shift || int(10**8)-1;
+ my $limit = shift || int(10**8);
+ $limit--;
my ($sum, $pc) = (0, 1);
forprimes {
$sum += prime_count(int($limit/$_)) + 1 - $pc++;
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libmath-prime-util-perl.git
More information about the Pkg-perl-cvs-commits
mailing list