c++mathprimes

Prime-k solution doesn’t go above certain number in c++


Im currently trying to solve the prime-k factor problem, where I have to find the sum of all primes factorial 1-5 ! and then mod(%) to itself. An example would be the prime 7.

(7-1)!+(7-2)!....(7-5)!=...%7.

The answer to this would be 4. I have to find this answer to the sum of all primes to 10^8. Therefore I have written the following code(which I know I not optimized)!.

#include<iostream>    
#include<vector> 

using namespace std;


bool prime(unsigned long long int n){
    if (n==2 || n==3){
        return true; 
    }
    if (n % 2 == 0 || n % 3 == 0) return false;
    for (unsigned long long int i = 5; i * i <= n; i += 6) {
        if (n % i == 0 || n % (i + 2) == 0) return false;
    }
    return true;
}

vector<unsigned long long int> Prime_lst(unsigned long long int n){
    vector<unsigned long long int> v {}; 
    for(unsigned long long int i = 5; i<n+1; i++){
        if(prime(i)==1){
            v.insert(v.end(), i); 
        }
    }
    return v; 
}

unsigned long long int factorial(unsigned long long int n)
{
    unsigned long long int res = 1;
    for (unsigned long long int i = 2; i <= n; i++)
        res *= i;
    return res;
}
unsigned long long int prime_p(unsigned long long int n){
    unsigned long long int c = 0; 
    for(int i = 1; i<6; i++){
        c += factorial(n-i); 
    }
    return c%n; 
}

unsigned long long int sum_prime_p(unsigned long long int n){
    unsigned long long int k = 0; 
    vector<unsigned long long int> prime_lst = Prime_lst(n); 
    for(unsigned long long int i = 0; i<prime_lst.size(); i++){
        cout << k << " "; 
        k += prime_p(prime_lst.at(i)); 
    }
    return k; 
}

int main(){
    //vector<unsigned long long int> v = Prime_lst(100); 

    //for(auto i=v.begin(); i<v.end(); i++)
    //{
    //  cout<<" "<<*i << " ";
    //}
    cout << sum_prime_p(100); 

    return 0;
} 

I have to get 480, but I always get 305 due to ints being 32 bits therefore I have used unsigned long long int. But I still can't get the right answer. Hope someone can help:)!


Solution

  • First of all, here is a link to the original problem: https://projecteuler.net/problem=381

    Solution with N=100:

    Sum( S(p) ) = 480
    

    Solution with N=100'000'000:

    Sum( S(p) ) = 139602943319822
    

    You do not need to sum over 5 factorials; you can reduce to 1. For small n it is reasonable to do these modulo p (as already noted). However, for large n you need a faster way. (Sorry to have to turn the maths into an image).

    enter image description here

    #include <iostream>
    #include <vector>
    #include <cmath>
    using namespace std;
    
    using INT = unsigned long long;
    
    //======================================================================
    
    vector<int> sieve( int nmax )
    {
       vector<bool> is_prime( 1 + nmax, true );
       is_prime[0] = is_prime[1] = false;
       for ( int i = 4; i <= nmax; i += 2 ) is_prime[i] = false;
       int imx = sqrt( nmax + 0.5 );
       for ( int i = 3; i <= imx; i += 2 )
       {
          if ( is_prime[i] )
          {
             for ( int j = i * i; j <= nmax; j += 2 * i ) is_prime[j] = false;
          }
       }
    
       vector<int> primes;
       for ( int i = 2; i <= nmax; i++ ) if ( is_prime[i] ) primes.push_back( i );
       return primes;
    }
    
    //======================================================================
    
    INT ipow( INT X, INT p, INT M )
    {
       INT result = 1;
    
       while ( p )
       {
          if ( p % 2 ) result = ( result * X ) % M;
          X = ( X * X ) % M;
          p /= 2;
       }
    
       return result;
    }
    
    //======================================================================
    
    int main()
    {
    // const int N = 100;
       const int N = 100'000'000;
       auto primes = sieve( N );
       INT SumS = 0;
       for ( auto p : primes )
       {
          if ( p < 5 ) continue;
          INT S = ( ipow( 24, p-2, p ) * ( 2 * p - 9 ) ) % p;
          SumS += S;
       }
       cout << "Sum( S(p) ) = " << SumS << '\n';
    }
    
    //======================================================================