static Zs find(const Z& n) { Z limit = 0; Z sqn = sqrt(n); for ( ; limit<primes.size() && primes[limit] <= sqn; ++limit ) ; // quadroot Z qrn = 2; while ( qrn*qrn*qrn*qrn < n ) ++qrn; Z limitc = 0; for ( ; limitc<primes.size() && primes[limitc] <= qrn; ++limitc ) { Z l=primes[limitc]; l = l*l*l*l; if ( l >= n ) break; } // cuberoot Z crn = 2; while ( crn*crn*crn < n ) ++crn; Z limitb = 0; for ( ; limitb<primes.size() && primes[limitb] <= crn; ++limitb ) { Z l=primes[limitb]; l = l*l*l; if ( l >= n ) break; } for ( Z c=0; c<limitc; ++c ) { Z pc = primes[c]; pc = pc*pc*pc*pc; for ( Z b=0; b<limitb; ++b ) { Z pb = primes[b]; pb = pb*pb*pb; if ( pb+pc >= n ) continue; for ( Z a=0; a<limit; ++a ) { Z pa = primes[a]; pa = pa*pa; if ( pa+pb+pc == n ) { Zs v(3); v[0] = primes[a]; v[1] = primes[b]; v[2] = primes[c]; return v; } } } } return Zs(); }
int main() { cout << "Max prime: " << primes[primes.size()-1] << endl; assert(count(50) == 4); assert(count(1000) == 98); assert(count(100000) == 4704); cout << count(2000000) << endl; }
int main() { cout << "Sieving primes" << endl; cout.flush(); const prime_sieve<Z, MAXNUM> primes; cout << "Starting loop" << endl; cout.flush(); for ( size_t i=0; primes[i]<MAX && i<primes.size(); ++i ) { const Z a = primes[i]; for ( size_t j=0; primes[j]*a<MAX && j<=i; ++j ) { const Z b = primes[j]; check(b*b); check(a*b); } } cout << "Count: " << cnt << endl; cout << "Expect: 17427258" << endl; }
INT phi(const INT& n) { static prime_sieve<INT, PRIMES> primes; // Negative numbers if ( n < 0 ) return phi<PRIMES, INT>(-n); // By definition if ( n == 1 ) return 1; // Base case if ( n < 2 ) return 0; // Lehmer's conjecture if ( less(n, primes.size()) && primes.isprime(n) ) return n-1; // Even number? if ( (n & 1) == 0 ) { INT m = n / 2; return (m & 1) == 0 ? 2*phi<PRIMES, INT>(m) : phi<PRIMES, INT>(m); } // For all primes less than n ... const INT sqrt_n = 1+sqrt(n); for ( typename std::vector<INT>::const_iterator p = primes.first(); p != primes.last() && *p <= sqrt_n; ++p ) { INT m = *p; // Is m not a factor? if ( (n % m) != 0 ) continue; // Phi is multiplicative INT o = n/m; INT d = binary_gcd<INT>(m, o); return d==1? phi<PRIMES, INT>(m) * phi<PRIMES, INT>(o) : phi<PRIMES, INT>(m) * phi<PRIMES, INT>(o) * d / phi<PRIMES, INT>(d); } // Find out if n is really prime INT p; for ( p=2+*(primes.last()-1); p < n && (n % p) != 0; p += 2 ) ; // loop // If n is prime, use Lehmer's conjecture if ( p >= n ) return n-1; // n must be composite, so divide up and recurse INT o = n/p; INT d = binary_gcd<INT>(p, o); return d==1? phi<PRIMES, INT>(p) * phi<PRIMES, INT>(o) : phi<PRIMES, INT>(p) * phi<PRIMES, INT>(o) * d / phi<PRIMES, INT>(d); }