Prime Generator PRIME1 on SPOJ - c++

Peter wants to generate some prime numbers for his cryptosystem. Help him! Your task is to generate all prime numbers between two given numbers!
Input
The input begins with the number t of test cases in a single line (t<=10). In each of the next t lines there are two numbers m and n (1 <= m <= n <= 1000000000, n-m<=100000) separated by a space.
Output
For every test case print all prime numbers p such that m <= p <= n, one number per line, test cases separated by an empty line.
Can anyone help me optimize my code as it is showing Time limit exceeded even after i am using sieve. Here is the link to the problem
https://www.spoj.com/problems/PRIME1/
Here is my code:
#include <iostream>
#include <math.h>
using namespace std;
int is_prime(int m)
{
int i,c=0;
for(i=2;i<=sqrt(m);i++)
{
if(m%i==0)
c++;
}
if(c==0)
return 1;
else
return 0;
}
int main()
{
int n,m,i,j,k,num;
cin>>num;
for(i=1;i<=num;i++)
{
cin>>m>>n;
int a[n];
for(j=0;j<=n;j++)
a[j]=1;
for(j=m;j<sqrt(n);j++)
{
if(is_prime(j)==1)
{
for(k=j*j;k<=n;k=k+j)
{
a[k]=0;
}
}
}
for(j=m;j<=n;j++)
{
if(a[j]==1)
cout<<j<<endl;
}
cout<<endl;
}
enter code here
return 0;
}

Your code has few issues:
You cannot create 10^9 (int a[n] ) array in given time constraint!
The nested for loops are taking too long almost O(sqrt(n-m)^2)
To optimise use https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes and https://www.geeksforgeeks.org/segmented-sieve/

Related

Trying out a problem but code I had written is not giving output for large numbers. why?

I was trying this question.
The prime factors of 13195 are 5, 7, 13 and 29.What is the largest prime factor of the number 600851475143 ?
And I had written the following code:
#include<iostream>
#define num 600851475143
using namespace std;
int isprime(unsigned long long int n)
{
unsigned long long int c=0;
for(unsigned long long int i=2;i<n;i++)
{
if(n%i==0)
{
c++;
break;
}
}
if(c==0)
{
return 1;
}
else
{
return 0;
}
}
int main()
{
unsigned long long int a,i,n=num;
while(n-- && n>1)
{
if(isprime(n)==1 && num%n==0)
{
cout<<n;
break;
}
}
return 0;
}
The problem occurring with the code is it is working for 13195 and other small values. But not getting any output for 600851475143. Can anyone explain why it is not working for large value and also tell the changes that should be made in these to get the correct output.
The below code snippets are from c (but should run quite nice with c++ as well):
#include <stdio.h>
#define uIntPrime unsigned long long int
#define uIntPrimeFormat "llu"
uIntPrime findSmallestPrimeFactor(uIntPrime num)
{
uIntPrime limit = num / 2 + 1;
for(uIntPrime i=2; i<limit; i++)
{
if((num % i) == 0)
{
return i;
}
}
return num;
}
uIntPrime findLargestPrimeFactor(uIntPrime num)
{
uIntPrime largestPrimeFactor = 1; // start with the smallest possible value
while (num > 1) {
uIntPrime primeFactor = findSmallestPrimeFactor(num);
if (primeFactor > largestPrimeFactor) largestPrimeFactor = primeFactor;
num = num / primeFactor;
}
return largestPrimeFactor;
}
How can this work?
(first function:) Counting the numbers up from 2 means you are starting with prime factors on the lower end. (Numbers that are non-prime when counting are just not working out as fraction-less divisors and at the same time their prime number factor components were already probed because they are lower.)
(second function:) If a valid factor is found then the factor is pulled out from the number in question. Thus the search for the now smallest prime in the pulled-out number can repeat. (The conditional might probably be superfluous due to lower numbers are found first anyway - but it might resemble a search pattern you are familiar with - like in a minimum/maximum/other-criteria search. I am now leaving it up to you to proof it right or wrong with testing with your own main routine.)
The stop condition is about having the last factor extracted means dividing the value by itself and getting a value of 1 for num.
(There is for sure still much space for speeding this up!)

hackerrank Ramanujan’s Prime Substrings 1 problem

The question is:
Ramanujan is so fond of playing number games. One day Ramanujan and Anish played a game. Ramanujan gave Anish a number string and asked him to find all the distinct substrings of size at most six that are prime. Anish being good at maths takes up the game and if he can give solutions to all the input sets Ramanujan provides him, Anish wins the game. Your task is to help Anish win the game.
Input Format
First line contains T, The number of test cases. Each test case contains a string of size N containing only integers.
Constraints
1 <= Number of Test Cases <= 10 1 <= N <= 10^7
Output Format
For Each Test case, print the total number of distinct prime substrings of length at most 6.
My code is in c++:
I had created a vector and map of all the prime number which is less than square root of 10^7 and had intialised map with 1(1 indicates prime number,0 indicates composite number).
Even for checking whether the number is prime or not ,I am dividing it with only prime number less than its square root.
But even doing all this ,I am unable to pass 2nd testcase(showing terminated due to timeout).I am only able to pass 1st test case.I think my program is taking a lot of time to create substrings(using substr() function).Is there any way to reduce time complexity ?plz answer.
map<long int,int>mp{{2,1},{3,1},{5,1},............................,{3121,1},{3137,1}};
map<long int,int>p;
vector<long int>v{2,3,5,..............3137};
long int c=0;
void check_prime(long int n)
{
long int i;
int flag=-1;
for(i=0;v[i]*v[i]<=n;i++)
{
if(n%v[i]==0)
{
flag=1;
break;
}
}
if(flag==-1)
{
++c;
mp.insert(pair<long int,int>(n,1));
p.insert(pair<long int,int>(n,1));
}
else
{
mp.insert(pair<long int,int>(n,0));
p.insert(pair<long int,int>(n,1));
}
}
int main() {
int t;
string s;
long int n,n1,i,j;
cin>>t;
while(t--)
{
long int i,j;
cin>>s;
for(i=0;i<s.length();i++)
{
int l=s.length()-i;
for(j=1;j<=min(6,l);j++)
{
n=stoi(s.substr(i,j));
if(p.count(n)==0)
{
if(mp.count(n)==1 )
{
if(mp[n]==1 )
{
++c;
p.insert(pair<long int,int>(n,1));
}
else
{
p.insert(pair<long int,int>(n,1));
}
}
else
{
if(n<3162 || n%2==0 || n%5==0)
{
mp.insert(pair<long int,int>(n,0));
p.insert(pair<long int,int>(n,1));
}
else
{
check_prime(n);
}
}
}
}
}
cout<<c<<endl;
p.clear();
c=0;
}
return 0;
}
You don't need call check_prime() every time in the loop.
Instead, call it once to save result and use it later on.
Consider Sieve of Eratosthenes:
int np[1000000]; // not prime
int main(void)
{
np[1] = 1;
for (int i = 2; i*i < 1000000; i++)
for (int j = 2; i*j < 1000000; j++)
np[i*j] = 1;
// use np[n].
return 0;
}
Using np[n] will take O(1) as oppose to O(sqrt(n)) before.

Could anyone help me with what is wrong in the below piece of c++ code? The program doesn't give any output

The below code has been written aiming to generate all the armstrong* numbers below 1000.
*armstrong numbers:An Armstrong number of three digits is an integer such that the sum of the cubes of its digits is equal to the number itself. For example, 371 is an Armstrong number since 3^3 + 7^3 + 1^3 = 371.
#include<iostream>
using namespace std;
int main()
{
int n,sum=0,digit,a,b;
for(n;n<1000;n++)
{
a=n;
b=n;
for(b;b>=0;b/10)
{
digit=b%10;
sum+=(digit*digit*digit);
}
(sum==a)?cout<<a:cout<<" ";
}
return 0;
}
n is initially an undefined value. You'll need to set it to 0 before the for loop.
Also, b isn't being changed. Did you mean b /= 10 rather than b / 10?
I'd suggest to structure the code to make it easier to read, e.g. by introducing a function bool isArmstrong(int number); distinguish logic from using the logic; never let variables be uninitialised; introduce variables right there where they are used; give variables a meaning by using names other than a,b;
Then things like not initialized variables or infinite loops become much more apparent:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
bool isArmstrong(int number) {
int cubeSum = 0;
for (int remainingPortion = number; remainingPortion > 0; remainingPortion/=10) {
int digit = remainingPortion % 10;
cubeSum += digit*digit*digit;
}
return (cubeSum == number);
}
int main() {
for (int number = 0; number < 1000; number++)
{
if (isArmstrong(number))
printf("%d is an armstrong number\n", number);
}
return 0;
}

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.

Greatest Common Divisor using Euclidian Algorithm?

So I'm having a problem with my code here.
I am coding a Greatest Common Divisor using the Euclidian Algorithm and I can't seem to utilize the loop in order to keep the division to keep repeating until I get the greatest common divisor. So for now, I am able to get the remainder but do not know how to go on from there basically.
Any help will be greatly appreciated!
Here is what I have so far
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
int a;//Holds the first number
int b;//Holds the second number
int temp;//Assign to greatest number
int hold;//Assign to smaller number
float euclid;//soon to be function?
int leftover;
float gcd;
int main ()
{
cout<<"Welcome to Brian Garnadi's Version of GCD!\n"<<endl;
cout<<"Enter the first integer to be calculated: ";
cin>> a;
cout<<"Now enter the second integer: ";
cin>>b;
if (a>b)//Determines bigger number
{temp=a;
hold=b;
}
if (a<b)//Determines smaller number
{
temp=b;
hold=a;
}
leftover= temp%hold;
cout<<"\nThe remainder of the two numbers divided is "<<leftover<<".\n"<<endl;
}
Actually there is no need to calculate bigger number the euclid's algorithm manages itself.
Here's the working code :
#include <iostream>
using namespace std;
int gcd(int m,int n)
{
if(n == 0)
return m;
return gcd(n, m % n);
}
int main()
{
int a,b,answer;
cout<<"Welcome to Brian Garnadi's Version of GCD!\n"<<endl;
cout<<"Enter the first integer to be calculated: ";
cin>> a;
cout<<"Now enter the second integer: ";
cin>>b;
answer = gcd(a,b);
cout << "The GCD of the two numbers is : " << answer << endl;
return 0;
}
Do not forget to handle negative numbers in algorithm.
gcd(m, n) = gcd(n, m%n) when n != 0
= m when n = 0
function:
int gcd(int m, int n) {
if(m == 0 && n == 0)
return -1;
if(m < 0) m = -m;
if(n < 0) n = -n;
int r;
while(n) {
r = m % n;
m = n;
n = r;
}
return m;
}