checking if a number is mirror of the other (its reverse) - c

given a function that takes two numbers: Mirror( num 1, num 2)
how do I check if num2 is the mirror of number 1? IN C
for example if num 1= 523 num2=325 return 1: it's its mirror otherwise returns 0
more examples
num1=566 num2:566 returns false
num1=500 num2=005 return true
the length of the two numbers is unknown

You can compute the reverse and then compare the result with your other number.
int mirror(int n,int m)
{
int rev=0;
while(n>0)
{
rev*=10;
rev+=n%10;
n/=10;
}
return rev==m ? 1 : 0;
}

Will Not work for input like 290 and 92. Here 290 reverse will be 92 which will make it mirror image if we check by just reversing the num. Which is wrong.
We can correct it by making sure that we reverse the smaller of these numbers and then checking e.g. for 29 and 920, 29 being smaller will give rev = 92 which is not same as 920 and hence the correct answer.
int mirror(int s, int l){
// swap the numbers so that s is always smaller than l
if (s > l) {
int temp = s;
s = l;
l = temp;
}
int rev=0;
while(s > 0){
rev*=10;
rev+=n%10;
n/=10;
}
return rev==l ? 1 : 0;
}

Related

Check if a number is a palindrome: if not sum the number and the number with reversed digits and continue checking

I´m learning C and doing the second task which is to check if an integer is a palindrome. If yes, I shall return the number; if not, I shall sum up the number and the number with reversed digits and check again.
Example:
Number: 195
195 + 591 = 786
786 + 687 = 1473
1473 + 3741 = 5214
5214 + 4125 = 9339 (is palindrome)
If the program has checked 20 times and it´s still not a palindrome, I shall return 0.
My program looks like this:
int addRev(int n) {
int count;
int reversed = 0;
int remain;
int original;
original = n;
while (n != 0) {
remain = n % 10;
reversed = reversed * 10 + remain;
n /= 10;
}
if (original==reversed){
return original;
}
else{
original+=reversed;
}
return original;
}
I have checked the program so far. If I test it with 191, it's a palindrome and returns it. If I test with 195, it is not a palindrome and the function returns 786.
But what is the next step? Do I need a second while() to continue with 786?
The key is a requrement to make up to 20 tests.
So the algorithm may look like this
for i = 1 up to 20
{
reversed = .......
if original == reversed
return original // it's a palindrome
original += reversed
}
return 0 // no palindrome after 20 iterations

Counting carry operations

Can anybody tell me why my program keeps getting wrong answer? It must count the number of carry operations in a sum. I tried every testcase came to my mind. I didn't get wrong output.
Problem Description:
Children are taught to add multi-digit numbers from right-to-left one digit at a time. Many find the "carry" operation - in which a 1 is carried from one digit position to be added to the next - to be a significant challenge. Your job is to count the number of carry operations for each of a set of addition problems so that educators may assess their difficulty.
Input
Each line of input contains two unsigned integers less than 10 digits. The last line of input contains 0 0.
Output
For each line of input except the last you should compute and print the number of carry operations that would result from adding the two numbers, in the format shown below.
Sample Input
123 456
555 555
123 594
0 0
Sample Output
No carry operation.
3 carry operations.
1 carry operation.
Here's my current code:
#include<stdio.h>
int main()
{
unsigned long long int a,b,m,n,rem_m,rem_n,judge=0,sum,count;
while((scanf("%llu%llu",&m,&n))==2)
{
if(m==0 && n==0)
{
break;
}
count=0;
while(m!=0 && n!=0)
{
rem_m=m%10;
rem_n=n%10;
if(judge==1)
{
rem_m++;
}
sum = rem_m+rem_n;
judge=0;
if(sum>=10)
{
count++;
judge++;
}
m=m/10;
n=n/10;
}
if(count==0)
{
printf("No carry operation.\n");
}
else
{
printf("%llu carry operations.\n",count);
}
}
return 0;
}
count the number of carry operations in a sum
Asserting a,b are >= 0:
Terse solution
For fun :)
"ds" stands for digit sum.
int ds(int n){return n == 0 ? 0 : n%10 + ds(n/10);}
int numberOfCarryOperations(int a,int b){return (ds(a) + ds(b) - ds(a+b)) / 9;}
Readable
Here is a more readable variation.
int digitSum(int n)
{
int sum;
for (sum=0; n > 0; sum+=n%10,n/=10);
return sum;
}
int numberOfCarryOperations(int a,int b){
// a, b >= 0
return (digitSum(a) + digitSum(b) - digitSum(a+b)) / 9;
}
You can prove mathematically: every time you have a carry, the digitSum decreases by 9.
9, because we are in number system 10, so we "lose 10" on one digit if we have carry, and we gain +1 as the carry.
Pythonic version
I do not know how to do this in C, but in python it is easy to write a better digitSum function. In python we can easily create the list of digits from a number, and then just use sum() on it to get digitSum of the given number.
Here is a terse python one-liner solution:
def numberOfCarryOperations(a, b):
# f is the digitSum function
f=lambda n:sum(map(int,str(n)));return(f(a)+f(b)-f(a+b))/9
The loop condition is wrong. You want while(m!=0 || n!=0) (i.e. while at least one of them is not zero) instead of while(m!=0 && n!=0), otherwise the answer will be wrong for things like 999 9, it will incorrectly stop after one iteration and report 1 carry operation whereas the correct answer should be 3. Think of it like this: you only want to stop when both of them are 0, so the loop must continue as long as at least one of the numbers is not 0.
Also, you forgot to clean up judge after printing output. You need to clear it before reading input again, or you could mistakenly have judge == 1 from a previous computation that ended with a carry (the name choice for this variable seems odd to me, you should rename it to something more meaningful like carry, but it's not the main issue here).
a and b are unused (you should enable compiler warnings).
The sample output shows the word operation (as in, singular) when the count is 1; your program always writes operations (plural). If you're submitting this to an automatic judge, the code will not pass because the output does not match exactly the expected output. To fix that small little detail, replace this:
else
{
printf("%llu carry operations.\n",count);
}
With:
else
{
printf("%llu carry operation%s.\n",count, count > 1 ? "s" : "");
}
Here's the fixed version:
#include <stdio.h>
int main(void)
{
unsigned long long int m,n,rem_m,rem_n,judge=0,sum,count;
while((scanf("%llu%llu",&m,&n))==2)
{
if(m==0 && n==0)
{
break;
}
count=0;
/* We want || here, not && */
while(m!=0 || n!=0)
{
rem_m=m%10;
rem_n=n%10;
if(judge==1)
{
rem_m++;
}
sum = rem_m+rem_n;
judge=0;
if(sum>=10)
{
count++;
judge++;
}
m=m/10;
n=n/10;
}
/* Clean up for next iteration */
judge = 0;
if(count==0)
{
printf("No carry operation.\n");
}
else
{
printf("%llu carry operations.\n",count);
}
}
return 0;
}
A ruby solution would be:
def count_carry_operations x, y
return 0 if x == 0 && y == 0
count = 0
carry = 0
while true
return count if x == 0 && y == 0
while x != 0 || y != 0
xr = x % 10
yr = y % 10
xr += 1 if carry == 1
sum = xr + yr
carry = 0
if sum >= 10
count += 1
carry += 1
end
x /= 10
y /= 10
end
carry = 0
end
count
end
A java solution would be:
public class Main {
public static int carry_count=0,carry_number=0;
public static void main(String[] args) {
System.out.println(Carry(99511,512));
}
private static int Carry(int num1,int num2){
if(num1/10==0 || num2/10==0){
int sum=num1%10+num2%10+carry_number;
if(sum>=10){
carry_number=1;
carry_count++;
return Carry(num1/10,num2/10);
}else{
return carry_count;}
}else {
int sum=num1%10+num2%10+carry_number;
if(sum>=10){
carry_number=1;
carry_count++;
}else {
carry_number=0;
}
return Carry(num1/10,num2/10);
}
}
}
Java program for people interested
static int numberOfCarryOperations(int num1, int num2) {
int counter = 0;
int result1 = 0;
int result2 = 0;
int carryNum = 0;
while( num1 != 0 || num2 != 0) {
result1 = num1%10;
result2 = num2%10;
if(num1 > 0 ) {
num1 = num1/10;
}
if( num2 > 0) {
num2 = num2/10;
}
if( (result1 + result2+carryNum) > 9 ) {
counter++;
carryNum = 1;
} else {
carryNum = 0;
}
}
return counter;
}
public static void main(String[] args) {
System.out.println(numberOfCarryOperations(123, 456)); // 0
System.out.println(numberOfCarryOperations(555, 555)); // 3
System.out.println(numberOfCarryOperations(900, 11)); // 0
System.out.println(numberOfCarryOperations(145, 55)); // 2
System.out.println(numberOfCarryOperations(0, 0));// 0
System.out.println(numberOfCarryOperations(1, 99999) );// 5
System.out.println(numberOfCarryOperations(999045, 1055) );// 5
System.out.println(numberOfCarryOperations(101, 809)); // 1
System.out.println(numberOfCarryOperations(189, 209) );// 1
}

Using the character array as integers

Hello Guys I am trying to solve one problem given on the Hacker Rank. Though the problem is quite simple, I was thinking to solve the problem using some other concepts.
The problem is
Desription
You are given an integer N. Find the digits in this number that exactly divide N (division that leaves 0 as remainder) and display their count. For N=24, there are 2 digits (2 & 4). Both of these digits exactly divide 24. So our answer is 2.
Input Format
The first line contains T (the number of test cases), followed by T lines (each containing an integer N).
Constraints
1≤T≤15
0
I solved the problem earlier by defining variable N as of type long long but that i guess will not be the efficient way to solve the problem.
So i thought why not declare the variable N as an character array. This way we can also use the program to store the number greater then the max limit of long long also rt?
Say i used the following code
#include <stdio.h>
#include <string.h>
int main()
{
int i,t;
char n[20];
scanf("%d",&t);
while(t--)
{
scanf("%s",n);
int len=strlen(n);
int f2,f3,f5,f7,f4,count;
f2=f3=f5=f7=f4=count=0;
for( i=0;i<len;++i)
{ int sum=0;
switch((int)n[i])
{
case 48: break;
case 49: ++count;break;
case 50: if((int)n[len-1]%2==0) // divisibility by 2
{
++count;f2=1;
}break;
case 51: for(i=0;n[i]!='\0';++i) // divisibility by 3
{
sum+=(int)n[i];
}
if(sum%3==0)
{
++count;
f3=1;
}break;
case 52: if(f2==1) // divisibility by 4
{
++count;
f4=1;
} break;
case 53: if(n[len-1]=='5' || n[len-1]=='0') // divisibility by 5
{
++count;
f5=1;
}break;
case 54: if(f2==1 && f3==1) // divisibility by 6
{
++count;
break;
}
case 55: // Code for divisibilty by 7
case 56: if(f2==1 && f4==1) // divisibility by 8
{ ++count;
break;
}
case 57: if(f3==1) // divisibility by 9
{
++count;
break;
}
}
}
printf("%d\n",count);
}
return 0;
}
The program is working fine but the only problem is I am not able to rt the code for divisibility by 7 anu suggestions will be helpful, And also which is the better way to solve the problem , This way in which the variable N is declared as the character array or by declaring the variable N as long long.
Any improvements for the above code would also be appreciated .....:)
Divisibility by 7 can be checked by this rule
Also you can use this mod() function to check divisibility by any number :
int mod(char *n, int val)
{
int sum = 0;
for(int i=0; n[i]; i++)
{
sum = sum*10 + (n[i]-'0');
if(sum >= val)
sum = sum % val;
}
return sum;
}
it will return 0, if the number n is divisible by number val :)
And you don't need to check for every redundant digit.
First check the available digit then check for divisibility once for each digit.
Here's what you can do -
#include <stdio.h>
#include <string.h>
int mod(char *n, int val)
{
int sum = 0;
for(int i=0; n[i]; i++)
{
sum = sum*10 + (n[i]-'0');
if(sum >= val)
sum = sum % val;
}
return sum;
}
int main()
{
int i,t;
int digit[10];
char n[20];
scanf("%d",&t);
while(t--)
{
scanf("%s",n);
int len=strlen(n);
int cnt=0;
memset(digit,0,sizeof(digit)); // setting all the digit to 0
for(i=0;i<len;i++)
digit[n[i]-'0']++;
for(i=1;i<10;i++)
{
if(digit[i]==0) // number doesn't contain any of this digit
continue;
if(mod(n,i)==0)
cnt+=digit[i]; // Adding the digit to the answer
}
printf("%d\n",cnt);
}
return 0;
}
How this works :
for n = 147 and val = 7
sum = 0
1st iter >> sum = 0*10 + 1 = 1
sum < val, so continue
2nd iter >> sum = 1*10 + 4 = 14
sum >= val, so sum = sum % val = 14 % 7 = 0
3rd iter >> sum = 0*10 + 7 = 7
sum >= val, so sum = sum % val = 7 % 7 = 0
as the final sum is 0, so we can say that n is divisible by val :)

Faster algorithm to find how many numbers are not divisible by a given set of numbers

I am trying to solve an online judge problem: http://opc.iarcs.org.in/index.php/problems/LEAFEAT
The problem in short:
If we are given an integer L and a set of N integers s1,s2,s3..sN, we have to find how many numbers there are from 0 to L-1 which are not divisible by any of the 'si's.
For example, if we are given, L = 20 and S = {3,2,5} then there are 6 numbers from 0 to 19 which are not divisible by 3,2 or 5.
L <= 1000000000 and N <= 20.
I used the Inclusion-Exclusion principle to solve this problem:
/*Let 'T' be the number of integers that are divisible by any of the 'si's in the
given range*/
for i in range 1 to N
for all subsets A of length i
if i is odd then:
T += 1 + (L-1)/lcm(all the elements of A)
else
T -= 1 + (L-1)/lcm(all the elements of A)
return T
Here is my code to solve this problem
#include <stdio.h>
int N;
long long int L;
int C[30];
typedef struct{int i, key;}subset_e;
subset_e A[30];
int k;
int gcd(a,b){
int t;
while(b != 0){
t = a%b;
a = b;
b = t;
}
return a;
}
long long int lcm(int a, int b){
return (a*b)/gcd(a,b);
}
long long int getlcm(int n){
if(n == 1){
return A[0].key;
}
int i;
long long int rlcm = lcm(A[0].key,A[1].key);
for(i = 2;i < n; i++){
rlcm = lcm(rlcm,A[i].key);
}
return rlcm;
}
int next_subset(int n){
if(k == n-1 && A[k].i == N-1){
if(k == 0){
return 0;
}
k--;
}
while(k < n-1 && A[k].i == A[k+1].i-1){
if(k <= 0){
return 0;
}
k--;
}
A[k].key = C[A[k].i+1];
A[k].i++;
return 1;
}
int main(){
int i,j,add;
long long int sum = 0,g,temp;
scanf("%lld%d",&L,&N);
for(i = 0;i < N; i++){
scanf("%d",&C[i]);
}
for(i = 1; i <= N; i++){
add = i%2;
for(j = 0;j < i; j++){
A[j].key = C[j];
A[j].i = j;
}
temp = getlcm(i);
g = 1 + (L-1)/temp;
if(add){
sum += g;
} else {
sum -= g;
}
k = i-1;
while(next_subset(i)){
temp = getlcm(i);
g = 1 + (L-1)/temp;
if(add){
sum += g;
} else {
sum -= g;
}
}
}
printf("%lld",L-sum);
return 0;
}
The next_subset(n) generates the next subset of size n in the array A, if there is no subset it returns 0 otherwise it returns 1. It is based on the algorithm described by the accepted answer in this stackoverflow question.
The lcm(a,b) function returns the lcm of a and b.
The get_lcm(n) function returns the lcm of all the elements in A.
It uses the property : LCM(a,b,c) = LCM(LCM(a,b),c)
When I submit the problem on the judge it gives my a 'Time Limit Exceeded'. If we solve this using brute force we get only 50% of the marks.
As there can be upto 2^20 subsets my algorithm might be slow, hence I need a better algorithm to solve this problem.
EDIT:
After editing my code and changing the function to the Euclidean algorithm, I am getting a wrong answer, but my code runs within the time limit. It gives me a correct answer to the example test but not to any other test cases; here is a link to ideone where I ran my code, the first output is correct but the second is not.
Is my approach to this problem correct? If it is then I have made a mistake in my code, and I'll find it; otherwise can anyone please explain what is wrong?
You could also try changing your lcm function to use the Euclidean algorithm.
int gcd(int a, int b) {
int t;
while (b != 0) {
t = b;
b = a % t;
a = t;
}
return a;
}
int lcm(int a, int b) {
return (a * b) / gcd(a, b);
}
At least with Python, the speed differences between the two are pretty large:
>>> %timeit lcm1(103, 2013)
100000 loops, best of 3: 9.21 us per loop
>>> %timeit lcm2(103, 2013)
1000000 loops, best of 3: 1.02 us per loop
Typically, the lowest common multiple of a subset of k of the s_i will exceed L for k much smaller than 20. So you need to stop early.
Probably, just inserting
if (temp >= L) {
break;
}
after
while(next_subset(i)){
temp = getlcm(i);
will be sufficient.
Also, shortcut if there are any 1s among the s_i, all numbers are divisible by 1.
I think the following will be faster:
unsigned gcd(unsigned a, unsigned b) {
unsigned r;
while(b) {
r = a%b;
a = b;
b = r;
}
return a;
}
unsigned recur(unsigned *arr, unsigned len, unsigned idx, unsigned cumul, unsigned bound) {
if (idx >= len || bound == 0) {
return bound;
}
unsigned i, g, s = arr[idx], result;
g = s/gcd(cumul,s);
result = bound/g;
for(i = idx+1; i < len; ++i) {
result -= recur(arr, len, i, cumul*g, bound/g);
}
return result;
}
unsigned inex(unsigned *arr, unsigned len, unsigned bound) {
unsigned i, result = bound, t;
for(i = 0; i < len; ++i) {
result -= recur(arr, len, i, 1, bound);
}
return result;
}
call it with
unsigned S[N] = {...};
inex(S, N, L-1);
You need not add the 1 for the 0 anywhere, since 0 is divisible by all numbers, compute the count of numbers 1 <= k < L which are not divisible by any s_i.
Create an array of flags with L entries. Then mark each touched leaf:
for(each size in list of sizes) {
length = 0;
while(length < L) {
array[length] = TOUCHED;
length += size;
}
}
Then find the untouched leaves:
for(length = 0; length < L; length++) {
if(array[length] != TOUCHED) { /* Untouched leaf! */ }
}
Note that there is no multiplication and no division involved; but you will need up to about 1 GiB of RAM. If RAM is a problem the you can use an array of bits (max. 120 MiB).
This is only a beginning though, as there are repeating patterns that can be copied instead of generated. The first pattern is from 0 to S1*S2, the next is from 0 to S1*S2*S3, the next is from 0 to S1*S2*S3*S4, etc.
Basically, you can set all values touched by S1 and then S2 from 0 to S1*S2; then copy the pattern from 0 to S1*S2 until you get to S1*S2*S3 and set all the S3's between S3 and S1*S2*S3; then copy that pattern until you get to S1*S2*S3*S4 and set all the S4's between S4 and S1*S2*S3*S4 and so on.
Next; if S1*S2*...Sn is smaller than L, you know the pattern will repeat and can generate the results for lengths from S1*S2*...Sn to L from the pattern. In this case the size of the array only needs to be S1*S2*...Sn and doesn't need to be L.
Finally, if S1*S2*...Sn is larger than L; then you could generate the pattern for S1*S2*...(Sn-1) and use that pattern to create the results from S1*S2*...(Sn-1) to S1*S2*...Sn. In this case if S1*S2*...(Sn-1) is smaller than L then the array doesn't need to be as large as L.
I'm afraid your problem understanding is maybe not correct.
You have L. You have a set S of K elements. You must count the sum of quotient of L / Si. For L = 20, K = 1, S = { 5 }, the answer is simply 16 (20 - 20 / 5). But K > 1, so you must consider the common multiples also.
Why loop through a list of subsets? It doesn't involve subset calculation, only division and multiple.
You have K distinct integers. Each number could be a prime number. You must consider common multiples. That's all.
EDIT
L = 20 and S = {3,2,5}
Leaves could be eaten by 3 = 6
Leaves could be eaten by 2 = 10
Leaves could be eaten by 5 = 4
Common multiples of S, less than L, not in S = 6, 10, 15
Actually eaten leaves = 20/3 + 20/2 + 20/5 - 20/6 - 20/10 - 20/15 = 6
You can keep track of the distance until then next touched leaf for each size. The distance to the next touched leaf will be whichever distance happens to be smallest, and you'd subtract this distance from all the others (and wrap whenever the distance is zero).
For example:
int sizes[4] = {2, 5, 7, 9};
int distances[4];
int currentLength = 0;
for(size = 0 to 3) {
distances[size] = sizes[size];
}
while(currentLength < L) {
smallest = INT_MAX;
for(size = 0 to 3) {
if(distances[size] < smallest) smallest = distances[size];
}
for(size = 0 to 3) {
distances[size] -= smallest;
if(distances[size] == 0) distances[size] = sizes[size];
}
while( (smallest > 1) && (currentLength < L) ) {
currentLength++;
printf("%d\n", currentLength;
smallest--;
}
}
#A.06: u r the one with username linkinmew on opc, rite?
Anyways, the answer just requires u to make all possible subsets, and then apply inclusion exclusion principle. This will fall well within the time bounds for the data given. For making all possible subsets, u can easily define a recursive function.
i don't know about programming but in math there is a single theorem which works on a set that has GCD 1
L=20, S=(3,2,5)
(1-1/p)(1-1/q)(1-1/r).....and so on
(1-1/3)(1-1/2)(1-1/5)=(2/3)(1/2)(4/5)=4/15
4/15 means there are 4 numbers in each set of 15 number which are not divisible by any number rest of it can be count manually eg.
16, 17, 18, 19, 20 (only 17 and 19 means there are only 2 numbers thatr can't be divided by any S)
4+2=6
6/20 means there are only 6 numbers in first 20 numbers that can't be divided by any s

Prime number in C

int prime(unsigned long long n){
unsigned val=1, divisor=7;
if(n==2 || n==3) return 1; //n=2, n=3 (special cases).
if(n<2 || !(n%2 && n%3)) return 0; //if(n<2 || n%2==0 || n%3==0) return 0;
for(; divisor<=n/divisor; val++, divisor=6*val+1) //all primes take the form 6*k(+ or -)1, k[1, n).
if(!(n%divisor && n%(divisor-2))) return 0; //if(n%divisor==0 || n%(divisor-2)==0) return 0;
return 1;
}
The code above is something a friend wrote up for getting a prime number. It seems to be using some sort of sieving, but I'm not sure how it exactly works. The code below is my less awesome version. I would use sqrt for my loop, but I saw him doing something else (probably sieving related) and so I didn't bother.
int prime( unsigned long long n ){
unsigned i=5;
if(n < 4 && n > 0)
return 1;
if(n<=0 || !(n%2 || n%3))
return 0;
for(;i<n; i+=2)
if(!(n%i)) return 0;
return 1;
}
My question is: what exactly is he doing?
Your friend's code is making use of the fact that for N > 3, all prime numbers take the form (6×M±1) for M = 1, 2, ... (so for M = 1, the prime candidates are N = 5 and N = 7, and both those are primes). Also, all prime pairs are like 5 and 7. This only checks 2 out of every 3 odd numbers, whereas your solution checks 3 out of 3 odd numbers.
Your friend's code is using division to achieve something akin to the square root. That is, the condition divisor <= n / divisor is more or less equivalent to, but slower and safer from overflow than, divisor * divisor <= n. It might be better to use unsigned long long max = sqrt(n); outside the loop. This reduces the amount of checking considerably compared with your proposed solution which searches through many more possible values. The square root check relies on the fact that if N is composite, then for a given pair of factors F and G (such that F×G = N), one of them will be less than or equal to the square root of N and the other will be greater than or equal to the square root of N.
As Michael Burr points out, the friend's prime function identifies 25 (5×5) and 35 (5×7) as prime, and generates 177 numbers under 1000 as prime whereas, I believe, there are just 168 primes in that range. Other misidentified composites are 121 (11×11), 143 (13×11), 289 (17×17), 323 (17×19), 841 (29×29), 899 (29×31).
Test code:
#include <stdio.h>
int main(void)
{
unsigned long long c;
if (prime(2ULL))
printf("2\n");
if (prime(3ULL))
printf("3\n");
for (c = 5; c < 1000; c += 2)
if (prime(c))
printf("%llu\n", c);
return 0;
}
Fixed code.
The trouble with the original code is that it stops checking too soon because divisor is set to the larger, rather than the smaller, of the two numbers to be checked.
static int prime(unsigned long long n)
{
unsigned long long val = 1;
unsigned long long divisor = 5;
if (n == 2 || n == 3)
return 1;
if (n < 2 || n%2 == 0 || n%3 == 0)
return 0;
for ( ; divisor<=n/divisor; val++, divisor=6*val-1)
{
if (n%divisor == 0 || n%(divisor+2) == 0)
return 0;
}
return 1;
}
Note that the revision is simpler to understand because it doesn't need to explain the shorthand negated conditions in tail comments. Note also the +2 instead of -2 in the body of the loop.
He's checking for the basis 6k+1/6k-1 as all primes can be expressed in that form (and all integers can be expressed in the form of 6k+n where -1 <= n <= 4). So yes it is a form of sieving.. but not in the strict sense.
For more:
http://en.wikipedia.org/wiki/Primality_test
In case the 6k+-1 portion is confusing, note that you can perform some factorization of most forms of 6k+n and some are obviously composite and some need to be tested.
Consider numbers:
6k + 0 -> composite
6k + 1 -> not obviously composite
6k + 2 -> 2(3k+1) --> composite
6k + 3 -> 3(2k+1) --> composite
6k + 4 -> 2(3k+2) --> composite
6k + 5 -> not obviously composite
I've not seen this little trick before, so it's neat, but of limited utility since a sieve of Eratosthenese is more efficient for finding many small prime numbers, and larger prime numbers benefit from faster, more intelligent, tests.
#include<stdio.h>
int main()
{
int i,j;
printf("enter the value :");
scanf("%d",&i);
for (j=2;j<i;j++)
{
if (i%2==0 || i%j==0)
{
printf("%d is not a prime number",i);
return 0;
}
else
{
if (j==i-1)
{
printf("%d is a prime number",i);
}
else
{
continue;
}
}
}
}
#include<stdio.h>
int main()
{
int n, i = 3, count, c;
printf("Enter the number of prime numbers required\n");
scanf("%d",&n);
if ( n >= 1 )
{
printf("First %d prime numbers are :\n",n);
printf("2\n");
}
for ( count = 2 ; count <= n ; )
{
for ( c = 2 ; c <= i - 1 ; c++ )
{
if ( i%c == 0 )
break;
}
if ( c == i )
{
printf("%d\n",i);
count++;
}
i++;
}
return 0;
}

Resources