My code stops at a certain condition - c++

In this code I input a test case number t and then input t numbers (n). Then my code prints the nth prime number. In the 1st line of the function, prime(), if I write if(a > 43000) return; Then the code works perfectly. But if I write if(a >= 165000) return; in the same place, codeblocks says the program has stopped working. But I can't understand why.
#include <iostream>
#include <cmath>
using namespace std;
int p[15000];
void prime(int a, int i)
{
if(a >= 165000) return;
else {
int q = 0;
int s=sqrt(a), d=3;
while(d<=s){
if(a % d == 0) {
q = 1;
}
d += 2;
}
if(q == 0) {
p[i] = a;
i++;
a += 2;
prime(a, i);
}
else {
a += 2;
prime(a, i);
}
}
}
int main()
{
p[0]=2;
prime(3, 1);
int k, T;
cin >> T;
for(int i = 1; i <= T; i++){
cin >> k;
cout << p[k - 1] << endl;
}
return 0;
}

First, I'll point out that your array p has only 15000 elements and that the 15001-th prime number is 163,847. This means that if you do a check for a >= 165000 before quiting you'll end up trying to fill indices of your array that are outside the bounds of your array.
Second, everyone is quite right that you should be careful when doing recursion. With each run of prime() you're allocating space for 5 new integer variables a, i, q, s, and d. This means you're allocating memory for tens of thousands of integers when (from the looks of your method) all you really need is 5.
Since it looks like these values are independent of all other iterations, you can employ a couple tricks. First, for q, s, and d by declaring them as globals they will only be allocated once. Secondly, by changing prime(int a, int i) to prime(int &a, int &i) you wont be allocating memory for a and i with each loop. This changes your code to look like the following:
#include <iostream>
#include <cmath>
using namespace std;
const int max_size = 15000 ;
int p[max_size];
int q ;
int s ;
int d ;
void prime(int &a, int &i)
{
if (i>=max_size) return ;
q = 0;
s=sqrt(a) ;
d=3;
while(d<=s){
if(a % d == 0) {
q = 1;
}
d += 2;
}
if(q == 0) {
p[i] = a;
i++;
a += 2;
prime(a, i);
}
else {
a += 2;
prime(a, i);
}
}
int main()
{
p[0]=2;
int a(3), i(1) ;
prime(a, i);
int k, T;
cin >> T;
for(int i = 1; i <= T; i++){
cin >> k;
// You should do a check of whether k is larger than
// the size of your array, otherwise the check on p[k-1]
// will cause a seg fault.
if (k>max_size) {
std::cout << "That value is too large, try a number <= " << max_size << "." << std::endl;
} else {
cout << p[k - 1] << endl;
}
}
return 0;
}
A couple of other changes:
instead of filling the array until you reach a specific prime number, I've changed your check so that it will fill the array until it hits the maximum number of entries.
I've also included a check as to whether the user has passed an index number outside the range of the "p" array. Otherwise it will produce a segmentation fault.
Now compiling this and running gives:
$ g++ prime_calc.cpp -o prime_calc
$ ./prime_calc
3
1500
12553
15000
163841
15001
That value is too large, try a number <= 15000.

Related

Breaking out of loop from function after printing the last prime number of a given range

I'm writing a code to find the last prime number of a given range. Suppose the range is 1 to 50. Then the last prime no. I want to print must be 47. My idea was to maybe reverse the order of prime numbers in the range and then try printing only the first value. Again kinda like if my order was 1 to 50 then I would start printing from 47, 43 and so on and only print 47. But I'm stuck and not getting ideas on how I could do this. here's my code
int prime_bef(int n)
{
int check = 0;
for (int i = 1; i <= n; i++)
{
if (n % i == 0)
{
check++;
}
}
if (check == 2)
{
cout << n << " ";
}
return 0;
}
int main ()
{
int l;
int u;
cin >> l >> u;
for (int i = u; i >= l; i--)
{
prime_bef(i);
}
return 0;
}
You can just use exit() in the place you want to end the program, and it works fine in your case. But by far the best approach is returning a value to test for continuation, it is the most readable.
#include<iostream>
#include <stdlib.h>
using namespace std;
int prime_bef(int n)
{
int check = 0;
for (int i = 1; i <= n; i++)
{
if (n % i == 0)
{
check++;
}
}
if (check == 2)
{
cout << n << " ";
exit(0);
}
return 0;
}
int main ()
{
int l;
int u;
cin >> l >> u;
for (int i = u; i >= l; i--)
{
prime_bef(i);
}
return 0;
}
Same code using bool return type:
#include<iostream>
using namespace std;
bool prime_bef(int n)
{
int check = 0;
for (int i = 1; i <= n; i++)
{
if (n % i == 0)
{
check++;
}
}
if (check == 2)
{
cout << n << " ";
return true;
}
return false;
}
int main ()
{
int l;
int u;
cin >> l >> u;
for (int i = u; i >= l; i--)
{
if(prime_bef(i))
break;
}
return 0;
}
Here is a simple and efficient way to check if the number is prime. I am checking if the number is prime and when it is true I am printing the number and breaking the loop so that only 1 number is printed. You can always remove the break statement and print all prime numbers in range.
#include<iostream>
using namespace std;
bool isPrime(int n){
if(n==2)return true;
if(n%2==0 || n==1)return false;
for(int i=3; i*i<=n; ++i){
if(n%i==0){
return false;
}
}
return true;
}
int main (){
int l, u;
cin>>l>>u;
for (int i = u; i >= l; i--){
if(isPrime(i)){
cout<<i<<"\n";
break;
}
}
return 0;
}
I'll give you a hint... while you are iteratively checking for the prime nature of the number, also check whether the last prime number calculated in the loop is greater than the max term of the range and break the loop when the condition becomes false.
Here a C++17 approach :
#include <cmath>
#include <iostream>
#include <vector>
// type to use for storing primes
using prime_t = unsigned long;
// there is a way to determine an upper bound to the number of primes smaller then a maximum number.
// See : https://primes.utm.edu/howmany.html
// this can be used to estimate the size of the output buffer (vector)
prime_t pi_n(const prime_t max)
{
prime_t pi_n{ max };
if (max > 10)
{
auto ln_n = std::log(static_cast<double>(max));
auto value = static_cast<double>(max) / (ln_n - 1.0);
pi_n = static_cast<prime_t>(value + 0.5);
}
return pi_n;
}
// Calculate prime numbers smaller then max
// https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
auto calculate_primes(const prime_t max)
{
std::vector<bool> is_primes(max, true);
// 0, 1 are not primes
is_primes[0] = false;
is_primes[1] = false;
// sieve
for (prime_t n = prime_t{ 2 }; n < prime_t{ max }; ++n)
{
if (is_primes[n])
{
auto n2 = n * n;
for (prime_t m = n2; m < max; m += n)
{
is_primes[m] = false;
}
}
}
// avoid unnecessary resizes of vector by pre-allocating enough entries to hold result
prime_t n{ 0 };
std::vector<prime_t> primes;
primes.reserve(pi_n(max));
// add all prime numbers found by the sieve
for (const auto is_prime : is_primes)
{
if (is_prime) primes.push_back(n);
n++;
}
return primes;
}
int main()
{
const prime_t max{ 50 };
auto primes = calculate_primes(max);
// max prime is last one in container
auto max_prime = primes.back();
std::cout << "maximum prime number smaller then " << max << ", is " << max_prime << std::endl;
}

highest power of 2 behind a number

I am writing a code to give numbers in a line and the inputs finish with zero then wirtes the highest power of 2 smaller or equal the inputs in a line.
it doesn't work.
#include<iostream>
#include<stdio.h>
using namespace std;
int highestPowerof2( int n)
{
static int result = 0;
for (static int i=n; i>=1; i--)
{
if ((i & (i-1)) == 0)
{
result = i;
break;
}
}
return result;
}
int main() {
static int num ;
do{
cin>>num ;
}
while(num=!0);
cout<<highestPowerof2(num)<<"\n";
return 0;
}
The most surprising thing in your code is this:
do{
cin>>num ;
}
while(num=!0);
You keep reading num from user input until num == 0. I have to admit that I dont really understand the rest of your code, but for num == 0 calling the function highestPowerof2(num) will always result in 0.
Perhaps you wanted to repeat the program until the user decides to quit, that could be
do{
cin>>num ;
cout<<highestPowerof2(num)<<"\n";
} while(num=!0);
PS: the other "surprising" thing is that you use static in places where it does not really make sense. Better simply remove it.
Here is another approach that is a little bit faster for large n. For example if n = 2^31 - 1, then the original loop would need to iterate 2^30 - 1 = 1,073,741,823 times, whereas this loop only needs a single iteration (provided sizeof(int) == 4):
#include <iostream>
#include <stdio.h>
using namespace std;
int highestPowerof2( int n)
{
if (n < 0) return 0;
int result = 0;
int num_bits = sizeof(int) * 8;
unsigned int i = 1 << (num_bits - 1);
while(i > 0) {
if (n >= i) return i;
i >>= 1;
}
return 0;
}
int main() {
int num ;
while (1) {
cin >> num;
cout << highestPowerof2(num) << "\n";
if (num == 0) break;
}
return 0;
}

code not executing due to huge time taken

Inputs n,m
I wrote this code which will find smallest number such that
no. will be divisible by n
and sum of its digits = m
but its not executing, its taking too much time and not showing any output
I tried to run i from n+1 to INT_MAX but its not making any difference
#include <iostream>
#include<climits>
#include<stdio.h>
using namespace std;
int main()
{
int n, m, a;
cin >> n >> m;
for (int i = n + 1; i < INT_MAX; i++)
{
a = 0;
if (i % n == 0)
{
while (i > 0)
{
a += i % 10;
i = i / 10;
}
if (a == m)
{
cout << a;
break;
}
}
if (a == m)
break;
}
}
I expect output to be some number but its showing nothing
Don't use i in while loop as you are using i in for loop already. Using i in while loop decremented its value by i/10 time, every time while loop is executed. Instead use any other local variable.
#include <iostream>
#include<climits>
#include<stdio.h>
using namespace std;
int main()
{
int n, m, a;
cin >> n >> m;
for (int i = n + 1; i < INT_MAX; i++)
{
a = 0;
if (i % n == 0)
{
int temp = i;
while (temp > 0)
{
a += temp % 10;
temp = temp / 10;
}
if (a == m)
{
cout << a;
break;
}
}
if (a == m)
break;
}
return 0;
}
**** EDIT
in your loop i is being incremented by 1 in each loop and then divided by 10 , therefore it is never truly increasing and neither is a, so it never reaches a hit and is stuck in a loop approaching positive 0

Console Application is not running and shows nothing

The problem is to solve this.
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
I wrote this code
#include <iostream>
#include <math.h>
using namespace std;
bool prime(long int a);
int main()
{
long int b = 600851475143/2;
long int k;
for(long int i = 1; i <= b ; i++)
{
if(b % i == 0 && prime(i) == true)
{
k = i;
}
}
cout << k << endl;
return 0;
}
bool prime(long int a)
{
bool p = true;
for(long int i = 2; i <= sqrt(a) && p == true ; i++)
if(a % i == 0) p = false;
return p;
}
and when I execute after a build, it opens a console , and shows nothing
Add a cout statement inside the for loop in main. Your program is running, it's just taking a long time.
The code is fine. 600851475143/2 is just a large number, so you have to wait some minutes till the result will be printed.
Further you're testing kind of twice if it a prime which makes the complexity unnecessarily much higher.
Try this:
long int b = 600851475143/2;
long int k = b;
for(long int i = 2; i < b ; i++)
{
if(b % i == 0)
{
k = i;
break;
}
}
cout << k << endl;

Fibonacci series

I am trying to do an exercise with the Fibonacci series.
I have to implement with a recursive function, a succession of the prime n number of Fibonacci and print them
in the same function. The problem is that my function print also the intermediate number.
The results, for example, for n = 6, should be : 1 1 2 3 5 8.
Any solutions?
Thanks
#include<iostream>
using namespace std;
int rec(int n)
{
int a, b;
if (n == 0 || n == 1)
{
return n;
}
else
{
a = rec(n - 1);
b = rec(n - 2);
cout << a + b << endl;
return a + b;
}
}
int main()
{
int n = 6;
rec(n);
return 0;
}
I have taken help of static int. That worked the way you wanted.
void rec(int n)
{
static int a=0,b=1,sum;
if(n>0)
{
sum = a+b;
a=b;
b= sum;
cout<<sum<<" ";
rec(n-1);
}
}
Though you have to print the first Fibonacci number yourself in main().
cout<<"0 ";
rec(n);
You can use this:
#include<iostream>
using namespace std;
#define MAXN 100
int visited[MAXN];
int rec(int n)
{
if(visited[n])
{
return visited[n];
}
int a, b;
if (n == 0|| n==1)
{
return n;
}
else
{
a = rec(n - 1);
b = rec(n - 2);
cout << " " <<a + b;
return visited[n] = a + b;
}
}
int main()
{
int n = 6;
cout<< "1";
rec(n);
cout<<endl;
return 0;
}
This implementation uses dynamic programming. So it reduces the computation time :)
Because you are printing in rec, its printing multiple times because of recursion. No need to print in the recursive function. Instead print the result in main
#include<iostream>
using namespace std;
int rec(int n)
{
int a, b;
if (n == 0 || n == 1)
{
return n;
}
else
{
a = rec(n - 1);
b = rec(n - 2);
//cout << a + b << endl;
return a + b;
}
}
int main()
{
int n = 6;
for (int i = 1; i <= n; i++)
{
cout << rec(i) << endl;
}
system("pause");
return 0;
}
I'm pretty sure you have gotten working solutions but I have a slightly different approach that doesn't require you to use data structures:
/* Author: Eric Gitangu
Date: 07/29/2015
This program spits out the fibionacci sequence for the range of 32-bit numbers
Assumption: all values are +ve ; thus unsigned int works here
*/
#include <iostream>
#include <math.h>
#define N pow(2.0,31.0)
using namespace std;
void fibionacci(unsigned int &fib, unsigned int &prevfib){
unsigned int temp = prevfib;
prevfib = fib;
fib += temp;
}
void main(){
int count = 0;
unsigned int fib = 0u, prev = 1u;
while(fib < N){
if( fib ==0 ){
fib = 0;
cout<<" "<< fib++ <<" \n ";
continue;
}
if( fib == 1 && count++ < 2 ){
fib = 1;
cout<< fib <<" \n ";
continue;
}
fibionacci(fib, prev);
cout<< fib <<" \n ";
}
}
Try this recursive function.
int fib(int n)
return n<=2 ? n : fib(n-1) + fib(n-2);
It is the most elegant solution I know.