How far can I go with this program of computing prime numbers? - c++

#include <iostream>
using namespace std;
int ifprime(long long int);
int main()
{
long long int number;
cout<<"Enter the number of prime numbers you want to know:\n";
cin>>number; //number is the number of prime numbers to be displayed
long long int j=0;
long long int m=2; //m would be used as consecutive natural numbers on which, test of prime number is performed
while (1<2)
{
if(ifprime(m)==1)
{
j+=1; // j is the counter of the prime numbers found and displayed
cout<<m<<endl;
}
m+=1;
if(j==number)
{
break;
}
}
}
int ifprime(long long int a)
{
for(int i=2;i<a;i++)
{
if(a%i==0)
{
return 0;
}
}
return 1;
}
The range of long long int seems to be small compared to the biggest primes known :/
Even if I were to compute the last prime number in the range of the long long int , can I compute the time it would take to compute that number?

Let's say the biggest prime number was n = 13. Your program would then try the following numbers: 2, 3, 4,.. 11, 12
So you have to test your number n - 2 times (which is more or less n times) and until you reach that point your program has to go through 2, 3, 4, ... 11, 12, 13, which is also (more or less) n times. -->The complexity is O(n^2).
Simple tip to speed up your program: store every prime number you've found so far in std::vector and only try these. This way you avoid integer factorization (like dividing with 6 (2 * 3) or 8 (2 * 2 * 2)).

Related

Anomaly in program related to legendre's formula

First of all, I would clarify that I am new to programming and started with c++ recently. There was a problem related to Legendre's formula in my math textbook and I thought about making a program related to it. It takes a number from user n, and finds the highest power of n which divides n!
It runs fine for a lot of numbers but messes up for a few others and it is completely random. This is a snippet from the code.
#include <iostream>
#include <math.h>
using namespace std;
int prime(int);
int calc(int, int);
int main()
{
int n;
int hpf=2;
cout<<"This program finds highest power x that divides x!"<<endl;
cout << "Enter number : " << endl;
cin>>n;
for(int i=2; i<=n; i++)
{
bool p=prime(i);
if(p==true && n%i==0)
hpf=i;
}
cout<<"The highest prime factor of the number is : "<<hpf<<endl;
int p=calc(hpf, n);
cout<<"The highest power of "<<n<<" that divides "<<n<<"!"<<" is : "<<p;
return 0;
}
calc(int f, int n)
{
int c=0 , d=1, power=1, i=0;
while(i>=0)
{
int x= pow(f,power+i);
if(i>0 && n%x==0)
d++;
if(x<=n)
{
c+=n/x;
i++;
}
else
break;
}
return c/d;
}
prime(int n)
{
bool isPrime = true;
for(int i = 2; i <= n/2; i++)
{
if (n%i == 0)
{
isPrime = false;
break;
}
}
return isPrime;
}
I pass the highest prime factor of n and the number n itself to int calc(int, int).
Now here is the problem:
when I input n=9, I get
Enter number :
9
The highest prime factor of the number is : 3
The highest power of 9 that divides 9! is : 2
on the other hand, if I input 25, I get
Enter number :
25
The highest prime factor of the number is : 5
The highest power of 25 that divides 25! is : 6
This is clearly wrong, the highest power should be 3.
It also works for bigger numbers accurately, but not all.
PS: I use codeblocks.
I'm not sure why exactly it works for 9 and not for 25(your program seems fine, but you probably have a problem when you calculate d or something), although both are squares of primes and your code seems to take care of that, but I do know why it doesn't work with number like 12. This happens because your code only looks at the highest prime factor and ignores the others. This will give you the true result when the other prime factors appear less frequently then the biggest one, but in all other cases this assumption leads to wrong results, because the highest is then also limited by smaller primes. So a correct solution has to take care of all prime factors.
For that you first need to factor the number(getting the prime factors and their power!). You can just google that if you are unsure how to do that. I don't want to include it here because then the answer would get to long.
Then you need to find how often the number is present in the factorial.
As you already know(at least you used it in your code) you can count by summing up the occurence as a factor of each power of the prime in every factor of the factorial which can be done through division like this:
n/p¹ + n/p² + n/p³ + n/p⁴ + …
That can be put into a simple function(using a simple self-made power calculation):
int occurenceInFaculty(int factor, int faculty) {
int sum = 0;
for(int power = factor; power <= faculty; power *= factor) { // Go through all powers
sum += faculty/power;
}
return sum;
}
Now you can calculate the occurrence for each of the prime factors of your number and if you divide by the power of that prime factor in the factorization you get an upper limit for the highest power.
Then all that's left to do is take the minimum over all prime factors and you are done.
Assuming one possible way of storing the prime factorization here is what the resulting code could look like:
Somewhere in the beginning of your code:
typedef struct {
int prime;
int power;
} PrimeFactor;
Assuming a prime factorization method like this:
PrimeFactor* factorization(int number, int* factors) {
// Factorize here. Return a pointer to an array of PrimeFactors and set the pointer factors to the arrays length.
}
And then the calculation part:
int number = 25; // Put your number here.
int length = 0;
PrimeFactor* factors = factorization(25, &length);
int min = number; // Some reasonable upper border because n! < n^n
for(int i = 0; i < length; i++) {
if(occurenceInFaculty(factors[i].prime, number)/factors[i].power < min)
min = occurenceInFaculty(factors[i].prime, number)/factors[i].power;
}
This program also gets 25 right!

Failing prime factorisning program (c++)

Im trying to solve this problem on programing.
Here is the question.
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
Now I've cooked up a c++ program, which tries to check it by brute force, however, while executing its stuck at 5. Here is the Program
#include <iostream>
#include <math.h>
using namespace std;
const long long no = 600851475143;
long long isprime(long long p)
{
long long reply = -1;
long long i = 2;
while (i < pow(p, 0.5)) {
if (i % p == 0)
reply = i;
}
if (reply == -1){
return 0;
cout<<" yup its prime "<<endl;
}
else
return reply;
}
long long factor(long long x)
{
for (long long i = 2; i < no; i++) {
cout<<"Trying "<<i<<endl;
if ((isprime(i) == 0)&& (no % i == 0)) {
return i;
cout<<"found "<<i<<endl;
break;
}
}
}
int main()
{
long long ans = no;
while (ans != 1) {
cout << factor(ans) << endl;
ans = ans / factor(ans);
}
}
and this is the output
~/Desktop/proj$ ./a.out
Trying 2
Trying 3
Trying 4
Trying 5
I really don't understand why its stuck at number 5, can someone help me out?
EDIT : Thanks b13rg , I realised my mistake . I now have a better algorithm , I have pasted it down for anybody needing it.
#include<iostream>
#include<math.h>
using namespace std;
long long fun (long long x)
{
for(long long i=2; i<sqrt(x);i++){
while (x%i==0){
cout<<i<<endl;
x=x/i;
}
}
}
int main(){
fun(600851475143);
return 0;}
You seem to never change the value of i or p in the while loop in the function isprime. It fails because sqrt(5) is larger than 2, and nothing in the while loop ever changes.
For the problem you're trying to solve:
You could first optimize the checking loop by only trying odd numbers, so first do 2, then 3, then 5 etc. To make it even faster you could hard code in the first few primes, but that might be beyond the scope of this project.
To find the largest prime factor, you would want to first find the smallest prime factor. For example, in the number above, the smallest is 5. The next step would be to divide 13195 by 5 to get 2369. Then start again to find the smallest prime factor of this number, and keep going until the dividing result is prime.
Number|Smallest prime
------|--------------
13169 | 5
2369 | 7
377 |13
29 |Largest prime factor of 13169

Memory + dynamic programming or recursion

Problem is that i have 64 megabytes on solution,so i can use only 16,777,216 int numbers.
But for answer i must use 33,333,333 numbers,so some answers will not be considered.
Actually, problem is this.
By the way, i had my own code instead:
#include <iostream>
using namespace std;
int sq(int x) {
return (long long)(x*x) %(1000000);
}
int func(int x) {
if (x==0)
return 3;
else {
return ( sq(func(x-1))+2)%(1000000);
}
}
int main()
{
/*const int num=16 777 216;
int* arr=new int [num];
arr[0]=3;
for (int i=1;i<num;i++)
arr[i]=((arr[i-1]%(1000000))*(arr[i-1])%(1000000)+2)%(1000000);*/
int t,rez;
int n;
cin>>t;
for (int p=0;p<t;p++) {
cin>>n;
if (n%3!=0) {
rez=0;
} else {
// rez=arr[n/3-1];
rez=func(n/3-1);
}
cout<<rez<<endl;
}
return 0;
}
In comments there is second solution.
I can do it with recursion, but i have limit in 1 second.
So what code would be OK?
You do not need anywhere near that many entries (10^9 / 3). Note that you need only the values mod 10^6. You have a recurrence relationship among these:
a[n] = a[n-1]^2 + 2
Each value depends only on the previous one, so there will be a simple sequence of numbers. The relation will have a period of no more than 10^6. Since they're all odd, the maximum length is cut in half.
As it turns out, the sequence repeats after 5003 terms, with a period of 5000: 3, 11, 123 do not appear later in the sequence.
So, forget that huge array. Compute the 5003 terms you need. Now for any input number N, you have 3 cases:
(1) N is not divisible by 3: return 0
else N is divisible by 3; call the quotient M
(2) M <= 3: return arr[M]
(3) else, get the needed subscript as m = ((M-3) mod 5000) + 3;
return arr[m]
You can now handle arbitrarily large input.

Output wrong Project Euler 7

So I'm trying out Problem 7 of Project Euler.
By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13.
What is the 10 001st prime number?
#include <iostream>
#include <cmath>
using namespace std;
bool isPrime(int a){
if (a==2||a==3){
return true;
}
if (a%2==0){
return false;
}
bool prime=true;
for (int b=2;b<sqrt(a);b++){
if (a%b==0)
prime=false;
}
if (prime==true)
return true;
else
return false;
}
int main(){
int infinite=0;
long long int primecounter=0;
for (int c=2;infinite==0;c++){
if (isPrime(c)==true){
primecounter++;
//cout<<c<<endl;
if (primecounter==10001)
{cout<<c;
break;}
}
}
return 0;}
This is what I've come up with so far. It works for the few numbers that I tested, like the 6th prime number etc. However, when I run it for the 10001st prime, it gives me 104021, and the answer is wrong. Can someone tell me what is wrong with my code?
Where you get it wrong is b < sqrt(a). Think of a=25, what happens in this case?
rest of answer already pointed by comments.
Although this is not required for this specific problem, you should take a look at Sieve of Eratosthenes algorithm. You will need it sooner or later to solve prime related problems.
You can solve it without getting help from 'cmath' too.Logic is like...
To check whether a number is prime, set a counter variable to 0; write a loop to divide the number by every number less than it till 1. If a number completely divides it, the counter will increase by one; the counetr will be exactly 2 for a prime number.
To calculate sucha big number u should choose a proper datatype too.I have used 'long long int' as a datatype.
My code for the project euler problem no 7 is as follows.Hope it helps you.Best wishes.Editions and improvements in this program are most welcome.Only bug is the time that it consumes,it takes more than an hour to reach the 10001th prime number.
#include<iostream.h>
#include<conio.h>
class prime
{
long long int a;
long long int j,i;
public:
void display();
};
void prime::display()
{
j=0;
long long int count=0;
long long int count1=0;
while(count1!=10001)
{
j=j+1;
i=j;
while(i!=0)
{
if(j%i==0)
{
count++;
}
i--;
}
if(count==2)
{
count1++;
cout<<count1<<"\t"; //The serial number of the prime number.
cout<<j<<"\t";// This will diaply all prime numbers till 10001.
}
if(count1==10001)
{
cout<<"\nThe 10001th prime number is:"<<j;
}
count=0;
}
}
void main()
{
prime k;
clrscr();
k.display();
getch();
}

Prime factors generation C++

Here is what I have so far:
//project Eular Problem 4: Prime Factors
#include<iostream>
#include<cmath>
typedef unsigned long long int uint_64;
using namespace std;
void storeFactors(uint_64 factors[], uint_64 num)
{
for(uint_64 i=0;i*i<num;i++
factors[i]=1; //assign 1 to all the values
for(uint_64 j=2; j*j<num;j++){
if(num%j!=0)
factors[j]=0; //assign 0 to non-factors
}
}
//Sieve of Eratosthenes to generate primes
void gen_primes(uint_64 arr[],uint_64 firstElement, uint_64 lastElement, uint_64 size)
{
for(uint_64 i=0;i<size;i++) //assigning 1 to all the values
arr[i]=1;
for(uint_64 i=2;i*i<=lastElement;i++){ //loop until the square-root of n
if(arr[i])
for(uint_64 j=i;j*i<=lastElement;j++) //eliminate multiples by assigning them 0
arr[j*i]=0;
if(firstElement==1)
arr[firstElement]=0;
}
}
void arrayComp(uint_64 factors[],uint_64 primeArray[], uint_64 size)
{
for(uint_64 i=2; i<=size; i++){
if(factors[i] && primeArray[i]){
cout<<i<<endl;
}
}
}
void processFactors(uint_64 num)
{
uint_64 size = sqrt(num);
uint_64 *factors = new uint_64[size];
uint_64 *primeArray = new uint_64[size];
storeFactors(factors, num);
gen_primes(primeArray, 2, num, size);
arrayComp(factors, primeArray,size);
delete [] factors;
delete [] primeArray;
}
int main()
{
uint_64 number;
cout<<"Enter a number: "<<endl;
cin>>number;
cout<<"The prime factors of "<<number<<" are: "<<endl;
processFactors(number);
return 0;
}
I tried taking the sieve approach to calculate the factors. All the non factors are assigned 0. ArrayComp displays the numbers if they are both factors of the input and also prime.
The problem I'm having is that the output is not complete and the programs runs into a segmentation fault. For example, factors for 10 are 5 and 2, but it shows the same answer for 100.
EDIT: Another thing I'm not too confident of is the size of the array. This program shows 3 as the prime factor of 21 and not 7, but if I increase the size by 1, it shows 3 and 5(incorrect)
The prime factors of 100 are the same as the prime factors of 10, only the multiplicity is different.
It appears that your representation doesn't have any way to store repeated factors.
uint_64 size = sqrt(num);
uint_64 *factors = new uint_64[size];
uint_64 *primeArray = new uint_64[size];
wrong reserve size.
ex.)
num = 10
size = 3
factor of 10 = 2, 5
if(factors[i] && primeArray[i]){
cout<<i<<endl;
}
factors[5] ? then array size is 3(0,1,2)