示例#1
0
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();
}
示例#2
0
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;
}
示例#3
0
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;
}
示例#4
0
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);
}