C++ Program hangs when calling a function - c++

I have written a code which checks whether a integer is prime or not,whenever i am calling that function the command line just hangs.
I am using MingW in Windows 7
#include<iostream>
#include<math.h>
using namespace std;
bool checkPrime(int n);
int main()
{
int t,tempstart;
cout<<checkPrime(6);
return 0;
}
bool checkPrime(int n)
{
bool check=true;
for (int i = 0; i <(int) sqrt(n) ; i++)
{
if(n%i==0)
{
check=false;
cout<<"asas";
break;
}
}
return check;
}

it should not hang-up at least not for n=6
1.try this
instead of:
if(n%i==0)
write:
if((n%i)==0)
some compilers do a mess with multi operation conditions so bracketing usually helps
2.as mentioned i should go from 2
n%0 is division by zero maybe your code thrown hidden exception and that is what is wrong
3.have you try to debug it ?
get a breakpoint inside for loop and step it and see why it is not stopping when i==2,3
Tips for speeding it up a little (just few thousand times for bigger n)
1.i=2,3,5,7,9,11,13,...
as mentioned in comments do i=2 separately (by (n&1)==0 instead of (n%2)==0)
and the rest:
for (nn=sqrt(n),i=3;i<=nn;i+=2) ...
2.instead of sqrt(n) use number with the half of bits
3.do not compute sqrt inside for (some compilers do not pre-compute)
4.use sieve of Aristoteles
create one or more arrays which will eliminate few divisions from you
do not forget to use array size as common multiply of dividers inside it
this is what can speed up things considerably
because it can eliminate many for cycles with a single array access
but it need initialization of arrays prior to their use
for example array
BYTE sieve[4106301>>1]; //only odd numbers are important so the size is half and each bit hold one sieve value so the size is really 4106301*8 which is divided by:
can hold sieves for dividers:
3,5,7,11,13,17,19,23,137,131,127,113,83,61,107,101,
103,67,37,41,43,53,59,97,89,109,79,73,71,31,29
5.divide by primes
you can remember first M primes in some array (for example first 100 primes)
and divide by them
and the use
for (nn=sqrt(n),i=last prime+2;i<=nn;i++) ...
also you can remember all primes computed on runtime in some list and use them
6.you can combine all above all together
7.there are many other ways to improve performance of is_prime(n) ?
so study if you need more speed

According to the operator precedence in C++
% has more priority than ==
so you should be using
if((n%i)==0)
good luck!

Related

Can you suggest me ways to optimize this code?

Below is the problem question.
https://leetcode.com/problems/four-divisors/
I need a more optimized code.The below code exceeds the time limit.Please suggest me some edits to make this code more optimized.
My solution:
class Solution {
public:
int sumFourDivisors(vector<int>& nums) {
vector<int> ans;
int x=0;
for(int i=0;i<nums.size();i++){
int j=1;
while(j!=nums[i]+1){
if(nums[i]%j==0){
ans.push_back(j);
}
j++;
}
if(ans.size()==4){
x=accumulate(ans.begin(),ans.end(),x);
ans.clear();
}
else
ans.clear();
}
return x;
}
};
The trick to questions like this one is to find ways to do much less work than the obvious brute-force approach. For each number nums[i] in nums, you're doing nums[i] modulo operations. There are ways that you could cut that number down significantly. When you're trying to speed up code that does the same thing repeatedly, you've got two options: 1) speed up each iteration; 2) reduce the number of iterations needed. If you can't make much headway with one approach, try the other.
Since the point of doing problems like this is to get better at problem solving, I don't think telling you the answer to the problem is the right thing to do. Even so, it's not giving too much away to give an example of what I'm talking about.
Let's say one of the numbers in nums is 24. Right now, your program calculates nums[i]%j for all j from 1 to 24. But you know 1 and nums[i] are always divisors, so once you find that 24 % 2 == 0 and 24 % 3 == 0, you've got four divisors already. By the time you get to 24 % 4 == 0 you've already got 5 divisors, so you know that you can skip 24 because it has more than 4 divisors. Bailing out as soon as you can saves a lot of wasted work.
So, use what you know to reduce the amount of work that your code does. There are several other ways to do that in this problem, and in fact an optimal solution won't even need the explicit check above. Even for large numbers, the number of mod operations needed to check each number will be much smaller than the number itself.

Prime number (SIGSEGV)

This is a very famous problem on SPOJ where you need to find prime numbers in a given range so the thing is the range lies from 1 to 1000000000.But every time i allocate an array of 1000000000 size it will give me a sigsegv error or a sigabrt error how do i overcome this problem of assigning very large values to an array
Apart from that i am using the sieve of ertosthenes algorithm to solve the problem.I have given the code below please help me resolve the problem by telling me what i need to change in my code so i don't get a sigsegv and sigabrt error.
#include<iostream>
#include<stdlib.h>
using namespace std;
int main()
{
int t,j;
long long int x,y;
cin>>t;
int i=0;
while(i<t)
{
cin>>x>>y;
long long int *a=new long long int[y];
for(int k=0;k<=y;k++)
a[k]=1;
a[0]=0;
a[1]=0;
for(int k=2;k<=y;k++)
{
if(a[k]==1)
{
for(j=2;k*j<=y;j++)
a[k*j]=0;
}
}
for(int k=x;k<=y;k++)
{
if(a[k]==1)
cout<<k;
}
delete []a;
i++;
}
return 0;
}
please help me resolve the problem by telling me what i need to change in my code so i don't get a sigsegv and sigabrt error.
Change:
long long int *a=new long long int[y];
to:
std::vector<bool> a=std::vector<bool>(y);
std::vector<bool> will allocate 1 bit for each 0/1 value, instead of the 64 bits that you are probably allocating for each.
It looks like you're using something similar to the Sieve of Eratosthenes. The algorithm looks like:
bool composite[N] := {false, ..., false}
composite[0] := true
composite[1] := true
for (i from 2 to N)
if (not composite[i])
for (j = 2i to N skipping by i)
composite[j] := true
For ranges like [1, 10^9], a nice option to cut memory usage is to use bit masking instead of booleans. This way, you use ~128MB instead of ~1GB of memory for the sieve. Edit: I forgot to mention that std::vector<bool> is actually internally a std::bitset, so you don't actually have to do any explicit bit twiddling.
A better option in terms of memory is to use the fact that a number is composite iff it has a non-trivial factor less than or equal to its square root, and combine that with a sieve. Of course, you have to augment the sieve with a list of primes. It will be empty initially, and you must append a prime each time you find one.
Sieve all of the primes up to 32,000 (A little more than the square root of 1,000,000,000). The result is a sorted sequence of prime numbers.
For each integer k, iterate over the primes less than or equal to the square root of k. If it's divisible by one of them, it's not prime. Otherwise, if the loop terminates, it's prime. When k < 32,000, you can avoid this entirely and just use the flag set in the sieve array.
This gives you O(sqrt(N) log log sqrt(N)) complexity for the sieve, and checking if an integer k is prime takes time O(sqrt(k) / log sqrt(k)) by the Prime Number Theorem.

How to calculate the sum of the bitwise xor values of all the distinct combination of the given numbers efficiently?

Given n(n<=1000000) positive integer numbers (each number is smaller than 1000000). The task is to calculate the sum of the bitwise xor ( ^ in c/c++) value of all the distinct combination of the given numbers.
Time limit is 1 second.
For example, if 3 integers are given as 7, 3 and 5, answer should be 7^3 + 7^5 + 3^5 = 12.
My approach is:
#include <bits/stdc++.h>
using namespace std;
int num[1000001];
int main()
{
int n, i, sum, j;
scanf("%d", &n);
sum=0;
for(i=0;i<n;i++)
scanf("%d", &num[i]);
for(i=0;i<n-1;i++)
{
for(j=i+1;j<n;j++)
{
sum+=(num[i]^num[j]);
}
}
printf("%d\n", sum);
return 0;
}
But my code failed to run in 1 second. How can I write my code in a faster way, which can run in 1 second ?
Edit: Actually this is an Online Judge problem and I am getting Cpu Limit Exceeded with my above code.
You need to compute around 1e12 xors in order to brute force this. Modern processors can do around 1e10 such operations per second. So brute force cannot work; therefore they are looking for you to figure out a better algorithm.
So you need to find a way to determine the answer without computing all those xors.
Hint: can you think of a way to do it if all the input numbers were either zero or one (one bit)? And then extend it to numbers of two bits, three bits, and so on?
When optimising your code you can go 3 different routes:
Optimising the algorithm.
Optimising the calls to language and library functions.
Optimising for the particular architecture.
There may very well be a quicker mathematical way of xoring every pair combination and then summing them up, but I know it not. In any case, on the contemporary processors you'll be shaving off microseconds at best; that is because you are doing basic operations (xor and sum).
Optimising for the architecture also makes little sense. It normally becomes important in repetitive branching, you have nothing like that here.
The biggest problem in your algorithm is reading from the standard input. Despite the fact that "scanf" takes only 5 characters in your computer code, in machine language this is the bulk of your program. Unfortunately, if the data will actually change each time your run your code, there is no way around the requirement of reading from stdin, and there will be no difference whether you use scanf, std::cin >>, or even will attempt to implement your own method to read characters from input and convert them into ints.
All this assumes that you don't expect a human being to enter thousands of numbers in less than one second. I guess you can be running your code via: myprogram < data.
This function grows quadratically (thanks #rici). At around 25,000 positive integers with each being 999,999 (worst case) the for loop calculation alone can finish in approximately a second. Trying to make this work with input as you have specified and for 1 million positive integers just doesn't seem possible.
With the hint in Alan Stokes's answer, you may have a linear complexity instead of quadratic with the following:
std::size_t xor_sum(const std::vector<std::uint32_t>& v)
{
std::size_t res = 0;
for (std::size_t b = 0; b != 32; ++b) {
const std::size_t count_0 =
std::count_if(v.begin(), v.end(),
[b](std::uint32_t n) { return (n >> b) & 0x01; });
const std::size_t count_1 = v.size() - count_0;
res += count_0 * count_1 << b;
}
return res;
}
Live Demo.
Explanation:
x^y = Sum_b((x&b)^(y&b)) where b is a single bit mask (from 1<<0 to 1<<32).
For a given bit, with count_0 and count_1 the respective number of count of number with bit set to 0 or 1, we have count_0 * (count_0 - 1) 0^0, count_0 * count_1 0^1 and count_1 * (count_1 - 1) 1^1 (and 0^0 and 1^1 are 0).

Segmentation Fault C++ (array too large?)

I'm working on the Project Euler Problem 14, where I need to find the longest collatz sequence under 1,000,000. I've come up with an algorithm that works for smaller numbers (say, 100) that stores each collatz number from 1 - 100 into an array and uses that array as a reference to speed up the computations for higher numbers.
My code is as follows:
#include <iostream>
using namespace std;
long even(long n){ //the even-collatz function
n=n/2;
return n;
}
long odd(long n){ //the odd collatz function
n=3*n+1;
return n;
}
int main(){
long x, c=0, y[1000000]; // x= the number we are finding the collatz number of, c a counter that keeps track of how many steps we've taken in the sequence, y is an array to store the collatz numbers.
for (x=1; x<1000000; x++){ //iterates from x=1 to 1 million
long a = x; //sets a number a equal to the number we are currently trying to find the collatz number of
long b = a;
c=0; //intializes counter at 0
while (a!=0){ //loops infinitely; the only way to exit is through a break.
if (a%2==0){ // detects if the number is even
a=even(a); //applies the even-collatz function if so; sets x=x/2
c=c+1;
if (y[a]!=0){ // checks if the collatz number of x is already discovered
y[b]=c+y[a]; //adds the current number of steps to the collatz number of x and
break; //exits the while loop
}
}
else if (a==1){ //checks if the new x is equal to one and
y[b]=c; //if it is, it writes the current value of c to y[b] and
break; // exits the loop
}
else if (a%2==1){ //same as the "even" block, except for odd numbers
a=odd(a);
c=c+1;
if( y[a]!=0){
y[b]=c+y[a];
break;
}
}
//this is the end of the while loop; we've applied the collatz function as many times as we've needed to to x, and incremented the counter each time
}
}
long z;
for (int n=0;n!=100;n++){
if (y[n+1]>y[n]){
z=y[n+1];
}
}
cout << z << "\n";
}
The issue I'm having is that I get a segfault after x=1818 in the for loop. Through debugging, I've found that how quickly the segfault occurs depends on the size of array y, so I'm assuming that the array is just too big. From my (basic) understanding of segfaults, I think I'm just accessing memory that I'm "not allowed". Is there any way for me to circumvent this, or should I just start working towards another solution to this problem? I'm compiling using g++ on Ubuntu studio.
This array is probably too big for your system's default stack size; the simplest fix is to change its definition to:
std::vector<long> y(1000000);
and everything else can stay the same. You could use y.size() instead of the magic number 1000000 later in your loop.
For a starting number under N collatz sequence can go way beyond N. For N == 1000000 consider x == 333335.
I would suggest you to make y a vector<int> and expand it dynamically, or just make it unordered_map<int, int>.
If y was too big for your stack, you would get a stack overflow exception as soon as main tried to run.
Your problem is more likely that a gets bigger than the size of y.
When I ran it through the debugger, a was 1417174 when x was 4255, so you might have a problem with your algorithm.
That said, you should either allocate it yourself, or make it static, as there is no guarantee that whatever compiler Project Euler uses will allow such a large stack size.

Need a way to make this code run faster

I'm trying to solve Project Euler problem 401. They only way I could find a way to solve it was brute-force. I've been running this code for like 10 mins without any answer. Can anyone help me with ideas improve it.
Code:
#include <iostream>
#include <cmath>
#define ull unsigned long long
using namespace std;
ull sigma2(ull n);
ull SIGMA2(ull n);
int main()
{
ull ans = SIGMA2(1000000000000000) % 1000000000;
cout << "Answer: " << ans << endl;
cin.get();
cin.ignore();
return 0;
}
ull sigma2(ull n)
{
ull sum = 0;
for(ull i = 1; i<=floor(sqrt(n)); i++)
{
if(n%i == 0)
{
sum += (i*i)+((n/i)*(n/i));
}
if(i*i == n)
{
sum -= n;
}
}
return sum;
}
ull SIGMA2(ull n)
{
ull sum = 0;
for(ull i = 1; i<=n; i++)
{
sum+=sigma2(i);
}
return sum;
}
You're missing some dividers, if a/b=c, and b is a divider of a then c will also be a divider of a but cmight be greater than floor(sqrt(a)), for example 3 > floor(sqrt(6)) but divides 6.
Then you should put your floor(sqrt(n)) in a variable and use the variable in the for, otherwise you recalculate it a every operation which is very expensive.
You can do some straightforward optimizations:
inline sigma2,
calculate floor(sqrt(n)) before the loop (but compiler may be doing it anyway, though),
precalculate squares of all ints from 1 to n and then use array lookup instead of multiplication
You will gain more by changing your approach. Think what you are trying to do - summing squares of all divisors of all integers from 1 to n. You grouped divisors by what they divide, but you can regroup terms in this sum. Let's group divisors by their value:
1 divides everything so it will appear n times in the sum, bringing 1*1*n total,
2 divides evens and will appear n/2 (integer division!) times, bringing 2*2*(n/2) total,
k ... will bring k*k*(n/k) total.
So we should just add up k*k*(n/k) for k from 1 to n.
Think about the problem.
Bruteforce the way you tried is obviously not a good idea.
You should come up with something better...
Isn't there any method how to use some nice prime factorization method to speed up the computation? Isn't there any recursion pattern? Try to find something...
One simple optimization that you can carry out is that there will be many repeated factors in the numbers.
So first estimate in how many numbers would 1 be a factor ( all N numbers ).
In how many numbers would 2 be a factor ( N/2 ).
...
Similarly for others.
Just multiply their squares with their frequency.
Time complexity shall then straight-away reduce to O(N)
There are obvious microoptimizations such as ++i rather than i++ or getting floor(sqrt(n)) out of the loop (these are two floating point operations which are really expensive compared to other integer operation in the loop), and calculting n/i only once (use a dummy variable for it and then calculate the square of the dummy).
There are also rather obvious simplifications in the algorithm. For example SIGMA2(i) = SIGMA2(i-1) + sigma2(i). But do not use recursion since you need a really huge number, this would not work and your stack memory would be exhausted. Use loop instead of recursion. There is a huge potential for improvement.
And well, there is a bigger problem - 10^15 has 15 digits. This number squared has 30 digits. There is no way you can store this into unsigned long long, which has I think about 20 digits. So you need to employ somehow the modulo 10^9 (the end of the assignment) and get additional space for your calculations...
And when using brute force, print out the temporary result every milion number for example to give you idea how fast you are approaching to the final result. Waiting 10 minutes blindly is not a good idea.