Prime factors generation C++ - 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)

Related

Find the minimum positive integer divisible by both 2 and N

I am still learning C++ and having an ECPC Competition tomorrow.
You are given a positive integer N. Find the minimum positive integer divisible by both 2 and N.
What should I do in the for loop? (still not completed)
#include <iostream>
using namespace std;
int main()
{
int n;
cin>> n;
for(int i; ???;i++)
return 0;
}
You don't need any loop.
There are two cases. Either N is not divisible by 2, then all integers divisible by N and 2 are of the form
x = N * 2 * y
The smallest of those x has y==1.
The second case is when N is divisible by 2, then all integers divisible by N and 2 are of the form
x = N * y
The smallest of those x has y==1.
TL;DR: Do the maths first!
The result is N if N is divisible by 2, otherwise it's N*2.
int result = (N%2 == 0) ? N : N*2;
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
int main()
{
int i,N;
scanf("%d",&N);
for(i=1;i<100;i++)
{
if(i%2==0&&i%N==0)
{
if(i<12)
{
printf("%d",i);
}
}
}
return 0;
}
you should try using
int i=0;
while(true)
{
i++;
if((i%2==0) && (i%n==0))
{
cout<<i;
break;
}
}

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!

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

#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)).

What variation of Sieve of Eratosthenes is this?

I am trying to solve a problem Prime Path on spoj, and I am trying to understand the solution I found on github. The broad logic to solve this problem is to generate all four digit primes and add an edge iff we can go from one prime to the next by changing a single digit. This solution I found uses sieve to generate all primes. The sieve of eratosthenes on wiki is different compared to the sieve function in this solution. Just need help on understanding the variation of sieve function in the following code:
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <cstring>
using namespace std;
#define MAX 10000
#define LMT 100
bool flag[MAX], visited[MAX];
int d[MAX];
void sieve()
{
register int i, j, k;
flag[0] = flag[1] = 1;
for(i=1000; i<MAX; i+=2)
flag[i] = 1;
for(i=3; i<LMT; i+=2)
if(!flag[i])
for(j=i*i, k=i<<1; j<MAX; j+=k)
flag[j] = 1;
}
int bfs(int start, int end)
{
queue< int > Q;
int i, u, v, t, j;
char temp[10], x;
Q.push(start);
memset(visited, 0, sizeof visited);
memset(d, -1, sizeof d);
d[start] = 0;
visited[start] = 1;
while(!Q.empty())
{
u = Q.front();
Q.pop();
sprintf(temp,"%d",u);
x = temp[0];
for(t=0;t<4;t++)
{
if(t==0 || t==3)
i=1;
else
i=0;
if(t==3)
j=2;
else
j=1;
x = temp[t];
for(;i<=9;i+=j)
{
temp[t] = i+'0';
v = atoi(temp);
if(v!=u && !visited[v] && !flag[v])
{
Q.push(v);
visited[v] = 1;
d[v] = d[u]+1;
if(v==end)
return d[end];
}
}
temp[t] = x;
}
}
return d[end];
}
int main()
{
int a, b, t, dist;
sieve();
scanf("%d", &t);
while(t--)
{
scanf("%d %d", &a, &b);
if(a==b)
{
printf("0\n");
continue;
}
dist = bfs(a,b);
if(dist==-1)
printf("impossible\n");
else
printf("%d\n", dist);
}
return 0;
}
What is the sieve function computing here? I am unable to understand why the author has listed only the odd numbers to calculate the primes, and why the loops run upto LMT, i.e 100? Appreciate your help.
I am unable to understand why the author has listed only the odd numbers to calculate the primes
Because the only even prime is 2, the rest are all odd. So you only need to check odd numbers.
and why the loops run upto LMT, i.e 100?
Because 100 * 100 = 10000, so you can sieve all 4 digit primes by doing the sieve up to 100. By marking off multiples of numbers <= 100, you will also take care of numbers x > 100 that are non-prime and therefore must have divisors below sqrt(x).
for(j=i*i, k=i<<1; j<MAX; j+=k)
flag[j] = 1;
Note that i << 1 is just 2*i. Why 2*i? Remember that we only care about the odd numbers. i*i + i = i*(i+1), which will be even, and so on, you will land on even numbers sometimes if you use + i. So the code uses + 2i to avoid landing on even numbers.
Also, we start from i*i because the previous numbers will have been been sieved by previous iterations of i, for the same reason: if a j < i*i was not prime, it must have had a factor at most sqrt(j), which would have been addressed previously.
You can optimize the code even more if you want, as exercises:
You only sieve the odd numbers, but you still alocate memory for the evens. Implement the sieve with half the memory;
You only need 1 bit for each number. Implement the sieve with 16 times less memory (8 times less for not using a bool for each number and 2 times less for not allocating memory for the even numbers).

Finding total number of unique factorization

I want to find total factors of any number.
In number theory, factorization is the breaking down of a composite number into smaller non-trivial divisors, which when multiplied together equal the original integer. Your job is to calculate number of unique factorization(containing at least two positive integers greater than one) of a number.
For example: 12 has 3 unique factorizations: 2*2*3, 2*6, 3*4 . Note:
3*4 and 4*3 are not considered different.
I have attempted to find that but not getting exact for all.
Here is my code :
#include<iostream>
using namespace std;
int count=0;
void factor(int n,int c,int n1)
{
for(int i=n1; i<n ; i++)
{
if(c*i==n)
{count++;
return;}
else
if(c*i>n)
return;
else
factor(n,c*i,i+1);
}
return;
}
int main()
{
int num,n;
cin>>num;
for(int i=0 ; i<num ; i++)
{
cin>>n;
count=0;
factor(n,1,1);
cout<<count<<endl;
}
return 0;
}
Input is number of test cases followed by test-cases(Numbers).
Example : Input: 3 12 36 3150
Output: 3 8 91
I think you are looking for number of factorizations of a number which are unique.
For this I think you need to find the count of number of prime factor of that number. Say for
12 = 2, 2, 3
Total count = 3;
For 2, 2, 3 we need
(2*2)*3 ~ 4*3
2*(2*3) ~ 2*6
2*2*3 ~ 2*2*3
To solve this we have idea found in Grimaldi, discrete and combinatorial mathematics.
To find number of ways of adding to a number(n) is 2^(n-1) -1. For 3 we have...
3 =
1+1+1
2+1
1+2
Total count = 2^(3-1) -1 = 4-1 = 3
We can use analogy to see that
1+1+1 is equivalent to 2*2*3
1+2 is equivalent to 2*(2*3)
2+1 is equivalent to (2*2)*3
Say number of prime factors = n
So we have number of factorizations = 2^(n-1)-1
The code:
#include <stdio.h>
int power(int x, int y)
{
int prod =1, i ;
for(i=1; i<=y;i++) prod *= x;
return prod;
}
int main()
{
int number,div;
int count = 0, ti, t;
printf("Input: ");
scanf("%d",&t);
for(ti=1; ti<=t;ti++)
{
scanf("%d", &number);
div = 2;count = 0;
while(number != 0)
{
if(number%div!=0) div = div + 1;
else
{
number = number / div;
//printf("%d ",div);
count++;
if(number==1) break;
}
}
printf("%d ", power(2,count-1)-1);
}
return 0;
}
Using mod is really useful in attempting to factor:
for(int i = 1; i <= fnum; ++i){ //where fnum is the number you wish to factor
if(!(fnum % i)) ++count;
}
return count;
Of cross this is the number of factors, not unique factors, if you want the number of unique factors, you have to do some additional work.
The solution is to realize that of all permutations, precisely one is sorted. 2 * 4 * 7 * 3 gives the same result as 2 * 3 * 4 * 7. That means that when you've found one factor, you should not check the remainder for lower factors. However, you should check if the same factor appears again: 12 = 2 * 2 * 3. The sequence 2 2 3 is also sorted.
BTW, you should give your variables clearer names, or at least add some comments describing them.