Prime numbers in C - c

ok i have a very easy problem.we must find all the prime numbers that have at least 2 digits (11 is the first prime number).We must define the maxnumb.what the professor did .
#include <stdio.h>
#define MAXNUMB 100
int main (void)
{
int i,j;
for (i=11 ; i<MAXNUMB; i+=2)
{
for (j=3;j*j<=i;j+=2)
{
if (i%j==0)
{
break;
}
}
if (j*j>i)
printf(''%d is prime\n'',i);
}
}`
so I have 3 questions
we use "i=11" because we want only the two digits primes but why j=3 and not j=11
8th line "j*j<=i; why he did that?what we gain?
why we have this if (j*j>i) and not something (j==i)

why j=3 and not j=11
Because j is your candidate divisor. You need to try all divisors up to square root except 2, which has been eliminated by construction of the algorithm (you start with 11 and go up by 2, so you see only odd numbers; no need to check divisibility by 2).
8th line j*j<=i; Why he did that? What we gain?
If you tried all numbers up to and including the square root of the candidate prime, and found no divisors, then there would be no divisors above the square root as well. This saves you a lot of unnecessary iteration.
why we have this if (j*j>i) and not something (j==i)
The loop terminates under two conditions: (a) you reach a break, or (b) j goes past the square root of i. If you reached break, it means you found a divisor; if you reached past the square root, you didn't.

First of all, the theory behind it:
is a prime number if there is no other factor like in , which .
In your code, you are following the same path. The inner loop is trying all possible less than or equal to .
we use "i=11" because we want only the two digits primes but why j=3 and not j=11
Based on what I just said, you should ask why ! not ? The answer is simple! j is a factor in i (e.g. 3 a factor in 12=3*2*2) In this code in order to make it even faster, you just skipped all even numbers (i+=2), then you don't need j=2 to check if 'i' is dividable by j.
8th line "j*j<=i" why he did that?what we gain?
why we have this if (j*j>i) and not something (j==i)
Both questions are related to this part: .

Trial Division Theorem:
The most basic method of checking the primality of a given integer n is called trial division. This routine consists of dividing n by each integer m that is greater than 1 and less than or equal to the square root of n.
Hence, lets check primality of 37.
floor(sqrt(37)) = 6
So, check from 2 to 6, weather 37 is divisible by any of number in between. If 37 is not divisible by any number, then number is prime.
So, in your example:
floor(sqrt(11)) = 3 that's why started j = 3,
Also, instead of performing sqrt on i, we have considered square of j i.e. j*j <= i;
And, for last question answer by #dasblinkenlight is best.

we use "i=11" because we want only the two digits primes but why j=3 and not j=11
i is the number which is to be checked whether it is prime or not (since you need 2 digit numbers only so initially i=11) and your code is doing that by checking divisibility of i with j. So j should start from 2 but as your code neglects all even number due to i+=2 (initially i=11 so due to i+=2 increment in loop we have values of i=11, 13, 15,.. only odd numbers) so there is no need to check divisibility of i with 2. Therefore initial value of j is 3.
8th line "j*j<=i; why he did that?what we gain?
It could be written as j<=sqrt(i) also. Assume i=N^2 so if N is divisible by j then N^2 is also divisible by j. So instead of checking divisibility of i or N^2 with j till j<i or j<N^2 we are limiting it to j<=sqrt(i) or j<=N which decrease the number of operations of divisibility check and hence decrease the execution time of program.
Assume i=21 then is j=sqrt(i) evaluates j to be 4 (note j is int value so sqrt(21) result to be 4 instead of a float value 4.58). So program will check divisibility of i=21 with j<=sqrt(i) that is j=3(initial value) and 4(4<=sqrt(21)) instead with j<i that is j=3(initial value), 4, 5,... 20(20<21) which results in fasting the program.
We can also use j<=pow(i,(1/3 or 1/4 or 1/n)) but this would be better after extremely high values of i (like >10^6) and would not work for smaller values.
why we have this if (j*j>i) and not something (j==i)
It is because of the previous point.
Instead of checking divisibility of i or N^2 with j till j<=i or j<=N^2 we are limiting it to j<=sqrt(i) or j<=N which decrease the number of operations of divisibility check and hence decrease the execution time of program.
Hence if divisibility checking crosses the value j*j>i or j>sqrt(i) without having remainder equals to 0 or i%j==0 to be false then i is proved to be prime and gets printed.

Related

A probability theory problem in skiplist's C implement

These days I am looking at skiplist code in Algorithms in C, Parts 1-4, and when insert a new value into skiplist is more complex than I think. During insert, code should ensure that the new value insert into level i with the probability of 1/2^i, and this implement by below code:
static int Rand()
{
int i, j = 0;
uint32_t t = rand();
for (i = 1, j = 2; i < lg_n_max; i ++, j += j)
if (t > RANDMAX / j)
break;
if (i > lg_n)
lg_n = i;
return i;
}
I don't know how the Rand function ensure this, can you explain this for me, thank you.
Presumably RANDMAX is intended to be RAND_MAX.
Neglecting rounding issues, half the return values of rand are above RAND_MAX / 2, and therefore half the time, the loop exits with i = 1.
If the loop continues, it updates i to 2 and j to 4. Then half the remaining return values (¾ of the total) are above RAND_MAX / 4, so, one-quarter of the time, the loop exits with i = 2.
Further iterations continue in the same manner, each iteration exiting with a portion of return values that is half the previous, until the lg_n_max limit is reached.
Thus, neglecting rounding issues and the final limit, the routine returns 1 half the time, 2 one-quarter of the time, 3 one-eighth the time, and so on.
lg_n is not defined in the routine. It appears to be a record of the greatest value returned by the routine so far.
Thanks Eric Postpischil very much for his answer, I have understand how to ensure the probability. And I have a more understood answer:
The t is a random value between 0 and RANDMAX, and we assume that the loop will run 2 times. In the first loop, value of t is smaller than RANDMAX/2^1, means that value of t fall into the range from 0 to RANDMAX/2 , the probability of this is 1/2. In the second loop, remember the fact that value of t is in the range of (0, RANDMAX/2^i), value of t is smaller that RANDMAX/2^2, means that value of t fall into the range from 0 to RANDMAX/2^2, the probability of this is also 1/2, because the range of (0, RANDMAX/2^2) is only 1/2 of the range in first loop, and the first loop show value of t is in the range of (0, RANDMAX/2^1). And notice that the probability of second loop is conditional probability,it‘s based on the probability of first loop, so the probability of second loop is 1/2*1/2=1/4.
In a short, every loop will bring a * 1/2 to last loop's probability.

I wonder what's the explanation of the for loop for(i=2; i<=Number/2; i++)

Hi I have a code for getting prime numbers from a specific range, I'm analyzing it since its from the internet, I just wonder what the for loop for(i=2; i<=number/2; i++);. Why does it start with two and what's the reason behind why i<=number/2 is the condition. Here is the full code below, I hope you can help me.
#include <stdio.h>
int main()
{
int i, Number, count, Minimum, Maximum;
printf("\n Please Enter the Minimum & Maximum Values\n");
scanf("%d %d", &Minimum, &Maximum);
printf("Prime Numbers Between %d and %d are:\n", Minimum, Maximum);
for(Number = Minimum; Number <= Maximum; Number++)
{
count = 0;
for (i = 2; i <= Number/2; i++)
{
if(Number%i == 0)
{
count++;
break;
}
}
if(count == 0 && Number != 1 )
{
printf(" %d ", Number);
}
}
return 0;
}
2 is the lowest possible factor of a composite (1 is a factor of primes, remember).
Number/2 is an upper bound for the smallest factor. I say an upper bound, because a better bound would be sqrt(Number). Reasoning: any factor p that's greater than √N must have a corresponding factor q = N/p which must be less than √N.
Why does it start with two and what's the reason behind why
i<=number/2
That lower and upper bound is about performance i.e., reducing the number of iterations that you need to compute.
It starts in 2 because:
A prime number (or a prime) is a natural number greater than 1
It ends in Number/2 because if Number is a prime number until Number/2 then after that will still be a prime number.
The reason is as follows, "If a number n is not a prime, it can be factored into two factors" so that Number = a * b. So either a or b has to be at least 2 or larger. Therefore, you can set the upper bound to Number/2.
From prime number theory we know that actually if Number is a prime number until sqrt(Number) then it will still be a prime number after. From source one can read:
If a number n is not a prime, it can be factored into two factors
a and b:
n = a * b
Now a and b can't be both greater than the square root of n,
since then the product a * b would be greater than sqrt(n) * sqrt(n) = n. So in any factorization of n, at least one of the
factors must be smaller than the square root of n, and if we can't
find any factors less than or equal to the square root, n must be a
prime.
for (Number = Minimum; Number <= Maximum; Number++)
# This for loop is traversing all numbers in the range of the minimum and maximum number
for (i = 2; i <= Number / 2; i++)
# This for loop is checking if the number is divisible by any number starting from 2
For example, this can be used checking if number is prime number.
Take i <= Number / 2 as the loop condition.
If Number = 11 then this for loop will begin diving the number starting from 2. So the value of i will go from 2 to Number / 2, which is 5.
This improves the performance of the loop by reducing the amount of required iterations.
for loops must follow a specific structure.
The first statement (i=2) states that the counter must start at 2. The second statement (i <= Number/2) means the loop will continue whilst that statement is true. The final statement (i++) increments the variables i by 1 each time the loop runs.
So in this example, i starts at 2, then will increase by 1 each time until i is greater than Number before continuing to the remainder of the program.
First, 2 is the lowest factor of a composite while Number/2 is the highest limit in the condition starting from 2 to Number/2. We can stop at Number/2 because if Number is prime until then it will still remain prime after Number/2 to Number as well.
The point of using such limits is to improve performance by reducing loop count.

Find the worst case running time of this algorithm for checking if a number is divisible by 3

I wrote this algorithm for checking a number's divisibility by 3. It works by first checking if the input N is a single digit number. If N is not a single digit number, the sum of its digits is calculated and assigned to N. The outer while loop iterates until the number of digits n is equal to 1. Then the program checks if the final value of N is equal to 0, 3, 6 or 9, in which case N is divisible by 3.
e.g. When N=5432157 and n=7, then N=5+4+3+2+1+5+7=27 and n=2, then N=2+7=9 and n=1. Thus, the outer while loop iterates 3 times.
#include <stdio.h>
main(){
int N,n=0,rN,sum=0;
printf("Enter the number: ");
scanf("%d",&N);
rN=N;
while(n!=1){
n=0;
sum=0;
while(N>0){
sum+=N%10;
N/=10;
n++;
}
N=sum;
}
if(N==0||N==3||N==6||N==9){
printf("\n%d is divisible by 3.",rN);
}
else{
printf("\n%d is not divisible by 3.",rN);
}
}
For the worst case analysis, I have assumed that all the digits of N are equal to 9. What I have observed is that for number of digits n less than 11, the outer while loop iterates a maximum of 3 times. For n greater than or equal to 11 but less than 10^11, the loop iterates a maximum of 4 times. I tried out a few cases for n greater than or equal to 10^11, and saw that outer loop iterates 5 times. I have not been able to find a general formula for this case. Also, for the inner while loop, which iterates n(number of digits in current value of N) times for each iteration of the outer while loop, how does n decrease with each iteration of the outer while loop?
If you observe carefully, each of your (outer) iteration takes log(N_current) steps. With each step your number also becomes log(N) (or 9*log(N) to be precise).
The outer iterations will go on till the N_current has 1 digit.
So your total complexity will be -
log(N) + log(log(N)) + log(log(log(N))) + ... + 1 ; (1)
The number of iterations would be log*N.
Now, I do not know how to reduce (1) but if you over approximate and consider each step to be log(N), you can write the complexity as
O(log(N) * log*(N))
(Mind the capital O)

Can I make this C program any faster?

I need to make a program which prints all the prime numbers, here is that I have done:
#include <stdio.h>
int main(void) {
long long t,m,n,i,i2,i3,found;
float p;
scanf ("%lld" , &t);
for (i=1;i<=t;i++) {
scanf ("%lld%lld" , &m ,&n);
for (i2=m;i2<=n;i2++) {
found=0;
for (i3=2;i3<=i2/2;i3++) {
p=(float)i2/i3;
p=p-i2/i3;
if (p==0) {
found=1;
}
}
if ((found==0) && (i2!=1)) {
printf ("%lld\n" , i2);
}
}
printf ("\n");
}
return 0;
}
my time limit is 6 seconds, and with this code it's impossible, also the difference between m and n is 100000 maximum, and 1<=n<=m<=1000000000
There are complicated mathematical algorithms, like the Sieve of Atkin, that can find primes very quickly, but for your purposes, consider:
Every non-prime number is factorable by primes, if factored far enough.
If you've reached the sqrt(n) and still haven't found it to be factorable, then it won't be factorable, because any number larger than sqrt(n) must be factored alongside a number smaller than sqrt(n) to achieve the number you're looking for.
So test every prime number from 2 to sqrt(n) to see if your n is a prime. If none of the primes between 2 and sqrt(n) are factors of n, then n must be prime.
This should meet with the speed requirements of your assignment.
For this problem the constraints (ranges) are very large so better to use Miller–Rabin primality test method.
I changed my mind. You can use Sieve of Eratosthenes algorithm.
Here are the steps to find all prime numbers less than or equal to a given integer n by Sieve of Eratosthenes method:
First create an array of consecutive integers from 2 to n: (2, 3, 4, ..., n).
let p be an integer variable, initialize it with 2, the first prime number.
Starting from p, count up in increments of p and cross out all the multiples of p less than or equal to n (2p, 3p, 4p .... kp <= n).
Take the first number greater than p in the array that is uncrossed. If there is no such number <= n,then stop. Otherwise, assign this new number in p (which is the next prime), and start from step 3.

How does this Codechef Factorial Solution in C work?

I'm trying to understand how this code:
#include<stdio.h>
int main()
{
int j,p,k;
long long int n,i;
scanf("%lld",&n);
for(k=n;k>=1;k--)
{
p=0;
scanf("%lld",&i);
for (j=5;j<=i;j*=5)
{
p=p+i/j;
}
printf("%d\n",p);
}
return 0;
}
solves this Codechef problem: http://www.codechef.com/problems/FCTRL
What I'm having troubles understanding is how this loop works:
for (j=5;j<=i;j*=5)
{
p=p+i/j;
}
Why is the j variable set to 5 and could someone walk me trough this loop if I would give the value of 60 to the i variable?
Thanks so much!
In short the problem is to find the number of zeroes of a factorial of number between 1 to 1000000000.
Now take a pencil and a paper. Start with 1. From 1 to 4 there is no 0. First 0 occurs at 5!. The next is at 10! and then at 15!, 20!, ...... This means that number of zeroes increases at the interval of 5.
Coming to the loop
for (j=5;j<=i;j*=5)
{
p=p+i/j;
}
See the i is stand for N here (see the question). Since number of zeroes increases at the interval of 5, j is initialized to 5 and j will be incremented as a multiple of 5 .
Now the simple rule is that the number of trailing zeros in the decimal representation of N! is simply the multiplicity of the prime factor 5 in N!.
In the statement p=p+i/j;, same rule is followed. The author of the program incremented j by 5 till N/j >= 5 leaving N (i.e i) here as it is.
N = i = 30
p = 30/5 + 30/(5*5) = 6 // 30/25 is 1 and does not satisfying the condition N/j >= 5
This algorithm makes more sense if you understand the method they are using to find the number of trailing zeros of a factorial which is outlined in Trailing zero Factorial and in Factorials and Trailing Zeroes. Basically relies on the insight that you need to account for all the products of 5 and 2 in the factorial expansion to discover how many zeros there will be in the end.
The algorithm to finding the number of trailing zeros in x! boils down to to:
Finding successive powers of 5
Dividing x by the result add the truncated result to the total
Stop when the result of division is less than 1 or in this specific case we know this will happen when the result is greater than x
So if go back to the code we can find the following steps:
step 3
| step 1
V V
for (j=5;j<=i;j*=5)
{
p=p+i/j; // step 2
}
This piece of code:
p=0;
scanf("%lld",&i);
for (j=5;j<=i;j*=5)
{
p=p+i/j;
}
counts the number of factor 5 in all the integers in [1, i] and stores the result in p.
Loop 1: j=5, p+=i/5 counts numbers that are divisible by 5 in the range [1, i]
Loop 2: j=25, p+=i/25 counts numbers that are divisible by 25 in the range [1, i] (notice that such numbers have been already counted once in loop 1)
Loop 3: j=125, p+=i/125 counts numbers that are divisible by 125 in the range [1, i] (notice that such numbers have been already counted twice in loop 1 and 2)
....

Resources