final step: adding all the primes that the reverse are also primes - c

like 17, is a prime, when reversed, 71 is also a prime.
We manage to arrive at this code but we cant finish it.
#include <stdio.h>
main()
{
int i = 10, j, c, sum, b, x, d, e, z, f, g;
printf("\nPrime numbers from 10 to 99 are the follwing:\n");
while (i <= 99)
{
c=0;
for (j = 1; j <= i; j++)
{
if (i % j == 0) c++;
}
if (c == 2)
{
b = i;
d = b / 10;
e = b - (10 * d);
x = (e * 10) + d;
{
z = 0;
f = x;
for (j = 1; j <= f; j++)
{
if (f % j == 0) z++;
}
if (z == 2)
{
printf("%d %d\n", i, f);
}
}
}
i++;
}
getch();
}
my problem is how to add all the fs..
the answer should be 429.
how can i add all the f?

Why don't you break up the code into some functions:
bool isPrime(int number) that checks if a number is prime.
int reverse(int number) that reverses the number.
Then the algorithm would be:
sum = 0;
for (i = 2; i <= 99; ++i)
if (isPrime(i) && isPrime(reverse(i)))
sum += i;

At the beginning initialize sum = 0;. Then, next to your printf count the prime: sum += i;. you can then print it at the end.

If this is a basic programming class and you are just interested in the result then this will get you there, however if it is an algorithms class then you may want to look at the Sieve of Eratosthenes.
You may also want to think about what makes a 2 digit number the reverse of another 2 digit number and how you would express that.

There are many problems in your code. None of them will prevent compilation and none of them will cause problems in getting the output. I'll first tell you how to get the result you want and then highlight the problems.
Here is your code, modified to sum fs. You just need to add f to sum every time you print a prime satisfying the condition. Finally, you should print the sum of all fs.
#include <stdio.h>
//Use int as the return type explicitly!
int main()
{
int i=10,j,c,sum,b,x,d,e,z,f,g;
printf("\nPrime numbers from 10 to 99 are the follwing:\n");
//Set the sum of all primes whose reverse are also primes to zero
sum = 0;
while(i<=99)
{
//c is tyhe number of factors.
c=0;
for(j=1;j<=i;j++)
{
if(i%j==0)
c++;
}
//If there are only two factors.
//Two factors (1 and itself) => Prime
if(c==2)
{
//Reverse i and store it in x
b=i;
d=b/10;
e=b-(10*d);
x=(e*10)+d;
//Curly braces unnecessary
{
//Check if the reverse i.e. x is prime
//z is the number of factors
z=0;
//f is the number being tested for primality.
f=x;
for(j=1;j<=f;j++)
{
if(f%j==0)
z++;
}
//If f i.e. x i.e. the reverse has only two factors
//Two factors (1 and itself) => Prime
if(z==2)
{
//print the prime number.
printf("%d %d \n",i,f);
//Add f to the sum
sum += f;
}//if(z==2)
}//Unnecessary braces
}//if(c==2)
i++;
}//end while
//print the number of reversed primes!!
//That is sum of the reversed values of numbers satisfying the
//condition!
printf("\nThe sum is:%d\n", sum);
//getch() is non standard and needs conio.h
//Use getchar() instead.
//Better solution needed!!
getchar();
//Return 0 - Success
return 0;
}
Output
...#...-desktop:~$ gcc -o temp temp.c
...#...-desktop:~$ ./temp
Prime numbers from 10 to 99 are the follwing:
11 11
13 31
17 71
31 13
37 73
71 17
73 37
79 97
97 79
The sum is:429
...#...desktop:~$
Do take note of all the comments made in the code (above). In addition, consider doing the following:
Removing the unnecessary braces.
Using one variable for one thing. (x could have been used instead of f).
Using better variable names like number and numberOfFactors.
Breaking up your code into functions as Mehrdad Afshari has suggested.
Consider testing primality by checking if there is a divisor of the number (num) being tested up to sqrt(num) (Square root of the number).
Consider this:
For numbers upto 99, the reversed numbers are also 2 digit numbers.
If the number is in the set of primes already found, you can verify easily.
This will reduce the number of checks for primality. (which are expensive)
To do the above, maintain a list of primes that have been identified (primeList)
as well as a list of reversed primes (revList). Any item in revList that is also
in primeList satisfies your condition. You can then easily obtain the sum (429)
that you need.
Look at sweet61's answer, the use of the Sieve of Eratosthenes with my method will definitely be much more efficient. You can reverse primes at the end of the sieve and populate the revList (at the end).
On a personal level, I try to find the best solution. I hope you will also attempt to do the same. I have tried to help you out without giving it all away.
I hope this helps.
Note
I had suggested checking for divisors up to num/2. I fixed it to sqrt(num) on vartec's suggestion.

Related

Sum digits of number [duplicate]

This question already has answers here:
Find the sum of digits of a number(in c)
(6 answers)
Closed 2 years ago.
Hello i need problem with this task in C language. If anyone had a similar problem it would help me.
The task is:
Write a program that loads the numbers a and b (a <b), then finds and prints the numbers from the segment of [a, b] and prints the sum of the digits of each number.
I wrote for three issues, for example:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
int n1,n2,sum=0,a,b,k,n3;
scanf("%d",&a);
scanf("%d",&b);
for(k=a;k<=b;k++)
{
n1=k%10;
n2=(k/10)%10;
n3=k/100;
sum=n1+n2+n3;
printf("%d\n",sum);
}
}
The problem arises when I enter a larger than three-digit number, how to make for any number, no matter if it is two-digit, three-digit, four-digit ...
Well the way you solve this issue depends on the exact requirements. Given that you only have ints here I would use the following though it is by no meand production code
int main() {
int a = whatever;
int b = whatever;
char* a_as_s = itoa(a);
char* b_as_s = itoa(b);
int sum_of_a = 0;
int sum_of_b = 0;
for(int i = 0; a_as_s[i]; i++)
sum_of_a += atoi(a_as_s[i]);
for(int i = 0; b_as_s[i]; i++)
sum_of_b += atoi(b_as_s[i]);
}
That should calculate the sum of digits for arbirary lengths - the rest of your code seems fine
You've already solved the iterating part so as people have suggested in the comments all you need now is a way to sum the digits of an arbitrary integer. I've modified your solution with my take on the problem. I'm pretty sure there is a more elegant/efficient way to do this, so I'd suggest you also check out the links people have provided in the comments. Anyhow here is my take:
#include <stdio.h>
int maxPowOf10(int num)
{
int divisor = 1;
for(;;)
{
if(num / divisor == 0)
{
break;
}
divisor *= 10;
}
return divisor / 10;
}
int sumOfDigits(int num)
{
int sum = 0;
for(int divisor = maxPowOf10(num); divisor >= 1; divisor /= 10)
{
int tmp = num / divisor;
sum += tmp;
num -= tmp * divisor;
}
return sum;
}
int main()
{
int n1,n2,sum=0,a,b,k,n3;
printf("Insert a: ");
scanf("%d",&a);
printf("Insert b: ");
scanf("%d",&b);
printf("Result\n");
for(k=a;k<=b;k++)
{
sum = sumOfDigits(k);
printf("number: %d sum of its digits: %d\n", k, sum);
}
return 0;
}
The approach is fairly straightforward. To find the sum of the digits, first you determine what is the largest power of 10 that still features in the number. Once that is found we can just divide by the largest power of 10 and add the result to sum. The trick is that, after that, we have to remove the part of the number that is described by the decimal place we are at. So we don't count it again. Then, you keep repeating the process for ever decreasing powers of 10. In the end you have the complete sum.
To illustrate this on 152 for example:
a) The largest power of 10 in 152 is 100.
b1) We divide 152 by 100 and get 1. We add 1 to sum. We also decrease the number to 52 (152 - 100)
b2) We divide 52 by 10 and get 5. We add 5 to sum. We decrease the number to 2 (52 - 50).
b3) We divide 2 by 1 and get 2. We add 2 to sum. We decrease the number to 0 (2 - 2).
Point a describes the method maxPowOf10
Point b describes the method sumOfDigits

C - Find all amicable numbers between limits

First a definition: An amicable pair of numbers consists of two different integers where the
sum of the divisors of the first integer is equal to the second integer, and the
sum of the divisors of the second integer is equal to the first integer. A perfect number is a number that equals the sum of its own divisors.
What I want to do is make a program that asks the user for a lower limit, and an upper limit and then presents him/her with all the amicable pairs (one per line) between those two limits. If there's a perfect number only one number needs to be printed (not a pair in its case).
The whole idea is pretty confusing to me, so I'm looking for some assistance.
Here's what I have to start with, I know that sumDivisors() should be more or less correct, but main() is merely checking if the two inputted numbers are amicable or not - might have to do a complete overhaul of this since I want all the pairs between two given limits.
long sumDivisors(long a)
{
long s=0,i;
for(i=1;i<=a/2;i++)
{
if(a%i==0)
{
s+=i;
}
}
return s;
}
int main()
{
long t,n,s1;
scanf("%ld",&t);
while(t--)
{
scanf("%ld",&n);
s1=sumDivisors(n);
if(n==sumDivisors(s1))
{
printf("Yes\n");
}
else printf("No\n");
}
return 0;
}
You could write main() like this:
int main ()
{
// assumes 1 <= min <= max
long min = 1;
long max = 10000;
for (long a = min; a <= max; a++) {
long b = sum_of_proper_divisors (a);
if (a == b) {
printf ("perfect number:\t%ld\n", a);
}
if ((a < b) && (b <= max) && (sum_of_proper_divisors (b) == a)) {
printf ("amicable pair:\t(%ld, %ld)\n", a, b);
}
}
return 0;
}
The most easiest and understandable way of finding amicable pairs between a range is as follows:
find amicable pairs between 1 to 2000.if you want between 1 to 3000 , just bring changes in the checking condition of for loops( i and j <= 3000).
You can give whatever range you want (by changing the initialization and checking conditions of the loops(outer loop and inner loop) .
#include<stdio.h>
int main(){
int i,j;
//outer loop.
for (i=1;i<=2000;i++){
int d1=1;
int sum1=0;
while(d1<i){
if(i%d1==0){
sum1+=d1; //sum of divisors of i
d1++;
}else
d1++;
}
//inner loop
for(j=i+1;j<=2000;j++){
int d2=1;
int sum2=0;
while(d2<j){
if(j%d2==0){
sum2+=d2;//sum of divisors of j
d2++;
}else
d2++;
}
if(sum1==j && sum2==i)
//printing amicalbe pair.
printf("(%d , %d) \n",i,j);
}
}
return 0;
}
Most of you might face problem understanding what amicable pairs are, let me explain it through an example 220 & 284 are said to be amicable pairs because if we find the proper divisors of 220 we get (1, 2, 4, 5, 10, 11, 20, 22, 44, 55 & 110) summing up all of them we get 284. Now, the proper divisors of 284 are (1, 2, 4, 71 & 142) summing up all of them we get 220. Similarly, the sum of the divisors of 1184 is equal 1210 & the sum of the divisors of 1210 is equal to 1184. Now, we write a program in C to find all the amicable pairs within the range of 10000.
int main()
{
int n,k;
int i=1,s1=0,s2=0;
for(k=1;k<=10000;k++)
{
n=k;
while(i<n)
{
if(n%i==0)
s1=s1+i;
i++;
}
i=1;
if(s1==n)
continue;
while(i<s1)
{
if(s1%i==0)
s2=s2+i;
i++;
}
if(n==s2)
printf("%d \n",n);
s1=0;
s2=0;
}
}

Determine Prime Numbers using SINGLE do-while Loop

I wrote this program per my professor's instruction. Turns out he wanted us to use a SINGLE do-while loop. While I did technically do that... this won't fly. I can't figure out how to do it without using a for-loop or at least another loop of some other type. He said it could use continue or break statements--but that it might not be necessary.
I would appreciate not just re-writing my code--while this is handy, I don't learn from it well.
I appreciate any and all help.
int main() {
int max, x, n = 2; //init variables
//start n at 2 because 1 isn't prime ever
//asks user for max value
printf("Enter max number: ");
scanf("%i", &max);
/*prints prime numbers while the max value
is greater than the number being checked*/
do {
x = 0; //using x as a flag
for (int i = 2; i <= (n / 2); i++) {
if ((n % i) == 0) {
x = 1;
break;
}
}
if (x == 0) //if n is prime, print it!
printf("%i\n", n);
n++; //increase number to check for prime-ness
} while (n < max);
return 0;
}
This is definitely doable. The trick is to have a test variable, and each iteration through your while loop, check the test variable against your current number. Always start the test variable at 2 (every natural number > 0 is divisible by 1)
Cases to consider:
Our current number is divisible by the test variable -- number is NOT prime, increase the current number and reset the test variable.
Our test variable is greater than the square root of the current number. By definition, it CANNOT divide the current number, so the current number has to be prime (we have tried all numbers lower than the square root of the current number and none of them divide it). Increase the current number and reset the test variable.
Lastly, if either above case isn't true, we have to try the next number higher. Increment the test variable.
I have not provided the code as you asked to not have it re-written, but can provide if you would like.
EDIT
#include <stdio.h>
#include <math.h>
int main(void)
{
int max = 20;
int current = 4;
int checker = 2;
do{
if(checker > sqrt((double)current))
{
checker = 2;
printf("%d is prime\n",current);
current++;
}
else if(current % checker == 0)
{
checker = 2;
printf("%d is NOT prime\n",current);
current++;
}
else
checker++;
}while(current < max);
}
Output:
4 is NOT prime
5 is prime
6 is NOT prime
7 is prime
8 is NOT prime
9 is NOT prime
10 is NOT prime
11 is prime
12 is NOT prime
13 is prime
14 is NOT prime
15 is NOT prime
16 is NOT prime
17 is prime
18 is NOT prime
19 is prime
I won't give you the exact code, but two pointers that should help you:
First, a for loop can be written as a while loop (and, vice versa)
for (int i=0; i< 100; ++i)
...
would become:
int i=0;
while (i < 100)
{
...
++i;
}
Second, two nested loops can become a single one, in any number of ways:
for (int i=0; i< 100; ++i)
for (int j=0; j< 100; ++j)
...
Becomes
for (int z=0; z< 100*100; ++z)
{
i = z / 100;
j = z % 100;
}
The above shows two for loops, but you can perform similar transforms on other loops.
Think Eratosthenes sieve. In this method we strike composite numbers out of a table, so that in the end only primes remain. For simplicity, the table contains only odd numbers. You start pointing at 3, which is a prime. Strike out 3*3, 3*5... Finish your run over the table (it's finite), point at 5. It's not striked out, thus a prime. Strike out 15, 25... check 7, prime, strike 21, 35... check 9, already striked out, move on to 11...
Questions:
You have just checked a number, what is the next number to check?
How do you know you've ran out of numbers to check?
Write down answers to these questions, and you have a one-loop prime-finding algorithm.

Prime Generator Algorithm

I've been trying to solve the SPOJ problem of Prime number Generator Algorithm.
Here is the question
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.
It is very easy, but the online judge is showing error, I didn't get what the problem meant by 'test cases' and why that 1000000 range is necessary to use.
Here is my code.
#include<stdio.h>
main()
{
int i, num1, num2, j;
int div = 0;
scanf("%d %d", &num1, &num2);
for(i=num1; i<=num2; i++)
{
for(j=1; j<=i; j++)
{
if(i%j == 0)
{
div++;
}
}
if(div == 2)
{
printf("%d\n", i);
}
div = 0;
}
return 0;
}
I can't comment on the alogirthm and whether the 100000 number range allows optimisations but the reason that your code is invalid is because it doesn't seem to be parsing the input properly. The input will be something like:
2
123123123 123173123
987654321 987653321
That is the first line will give the number of sets of input you will get with each line then being a set of inputs. Your program, at a glance, looks like it is just reading the first line looking for two numbers.
I assume the online judge is just looking for the correct output (and possibly reasonable running time?) so if you correct for the right input it should work no matter what inefficiencies are in your algorithm (as others have started commenting on).
The input begins with the number t of test cases in a single line (t<=10)
you haven't got test cases in your programm.
Its wrong
And sorry for my English
2 - //the number of test cases
1 10 - // numbers n,m
3 5 - // numbers
Your programm will work only in first line.
#include <stdio.h>
#include <math.h>
int main()
{
int test;
scanf("%d",&test);
while(test--)
{
unsigned int low,high,i=0,j=2,k,x=0,y=0,z;
unsigned long int a[200000],b[200000];
scanf("%d",&low);
scanf("%d",&high);
for(i=low;i<=high;i++)
a[x++]=i;
for(i=2;i<=32000;i++)
b[y++]=i;
i=0;
while(b[i]*b[i]<=high)
{
if(b[i]!=0)
{
k=i;
for(;k<y;k+=j)
{
if(k!=i)
{
b[k]=0;
}
}
}
i+=1;j+=1;
}
for(i=0;i<y;i++)
{
if(b[i]!=0 && (b[i]>=low && b[i]<=sqrt(high)))
printf("%d\n",b[i]);
}
int c=0;
for(i=0;i<y;i++)
{
if(b[i]!=0 && (b[i]>=1 && b[i]<=sqrt(high)))
b[c++]=b[i];
}
int m=a[0];
for(i=0;i<c;i++)
{
z=(m/b[i])*b[i];k=z-m;
if(k!=0)
k += b[i];
for(;k<x;)
{
if(a[k]!=0)
{
a[k]=0;
}
k+=b[i];
}
}
for(i=0;i<x;i++)
{
if(a[i]!=0 && (a[i]>=2 && a[i]<=(high)))
printf("%d\n",a[i]);
}
printf("\n");
}
return 0;
}
To find primes between m,n where 1 <= m <= n <= 1000000000, n-m<=100000, you need first to prepare the core primes from 2 to sqrt(1000000000) < 32000. Simple contiguous sieve of Eratosthenes is more than adequate for this. (Having sieved the core bool sieve[] array (a related C code is here), do make a separate array int core_primes[] containing the core primes, condensed from the sieve array, in an easy to use form, since you have more than one offset segment to sieve by them.)
Then, for each given separate segment, just sieve it using the prepared core primes. 100,000 is short enough, and without evens it's only 50,000 odds. You can use one pre-allocated array and adjust the addressing scheme for each new pair m,n. The i-th entry in the array will represent the number o + 2i where o is an odd start of a given segment.
See also:
Is a Recursive-Iterative Method Better than a Purely Iterative Method to find out if a number is prime?
Find n primes after a given prime number, without using any function that checks for primality
offset sieve of Eratoshenes
A word about terminology: this is not a "segmented sieve". That refers to the sieving of successive segments, one after another, updating the core primes list as we go. Here the top limit is known in advance and its square root is very small.
The same core primes are used to sieve each separate offset segment, so this may be better described as an "offset" sieve of Eratosthenes. For each segment being sieved, only the core primes not greater than its top limit's square root need be used of course; but the core primes are not updated while each such offset segment is sieved (updating the core primes is the signature feature of the "segmented" sieve).
For such small numbers you can simply search for all primes between 1 and 1000000000.
Take 62.5 mByte of RAM to create a binary array (one bit for each odd number, because we already know that no even number (except of 2) is a prime).
Set all bits to 0 to indicate that they are primes, than use a Sieve of Eratosthenes to set bits to 1 of all number that are not primes.
Do the sieve once, store the resulting list of numbers.
int num;
bool singleArray[100000];
static unsigned long allArray[1000000];
unsigned long nums[10][2];
unsigned long s;
long n1, n2;
int count = 0;
long intermediate;
scanf("%d", &num);
for(int i = 0; i < num; ++i)
{
scanf("%lu", &n1);
scanf("%lu", &n2);
nums[i][0] = n1;
nums[i][1] = n2;
}
for(int i = 0; i < 100000; ++i)
{
singleArray[i] = true;
}
for(int i = 0; i < num; ++i)
{
s = sqrt(nums[i][1]);
for(unsigned long k = 2; k <= s; ++k)
{
for (unsigned long j = nums[i][0]; j <= nums[i][1]; ++j)
{
intermediate = j - nums[i][0];
if(!singleArray[intermediate])
{
continue;
}
if((j % k == 0 && k != j) || (j == 1))
{
singleArray[intermediate] = false;
}
}
}
for(unsigned long m = nums[i][0]; m <= nums[i][1]; ++m)
{
intermediate = m - nums[i][0];
if(singleArray[intermediate])
{
allArray[count++] = m;
}
}
for(int p = 0; p < (nums[i][1] - nums[i][0]); ++p)
{
singleArray[p] = true;
}
}
for(int n = 0; n < count; ++n)
{
printf("%lu\n", allArray[n]);
}
}
Your upper bound is 10^9. The Sieve of Eratosthenes is O(N loglogN) which is too much for that bound.
Here are a few ideas:
Faster primality tests
The problem with a naive solution where you loop over the range [i, j] and check whether each number is prime is that it takes O(sqrt(N)) to test whether a number is prime which is too much if you deal with several cases.
However, you could try a smarter primality testing algorithm. Miller-Rabin is polynomial in the number of bits of N, and for N <= 10^9, you only need to check a = 2, 7 and 61.
Note that I haven't actually tried this, so I can't guarantee it would work.
Segmented sieve
As #KaustavRay mentioned, you could use a segmented sieve. The underlying idea is that if a number N is composite, then it has a prime divisor that is at most sqrt(N).
We use the Sieve of Eratosthenes algorithm to find the prime numbers below 32,000 (roughly sqrt(10^9)), and then for each number in the range [i, j] check whether there is any prime below 32,000 that divides it.
By the prime number theorem about one in log(N) numbers are prime which is small enough to squeeze in the time limit.
#include <iostream>
using namespace std;
int main() {
// your code here
unsigned long int m,n,i,j;int N;
cin>>N;
for(;N>0;N--)
{
cin>>m>>n;
if(m<3)
switch (n)
{
case 1: cout<<endl;continue;
case 2: cout<<2<<endl;
continue;
default:cout<<2<<endl;m=3;
}
if(m%2==0) m++;
for(i=m;i<=n;i+=2)
{
for(j=3;j<=i/j;j+=2)
if(i%j==0)
{j=0;break;}
if(j)
cout<<i<<endl;
}
cout<<endl;
}return 0;}

Write a program with a loop that sums all odd digits of an input

Hi I'm currently in school for Computer science and I'm having problems with two of my codes, the first one pertains to the title. I have to create a program that takes only the odd digits of an input and sums them. I honestly have no idea how to approach this, this is all I have
Scanner in = new Scanner(System.in);
int a;
int b;
System.out.println("Enter a number: ");
a = in.nextInt();
while (a > 0) {
if (a.charAt(0) % 2 != 0) {
}
}
the second problem I have trouble with is write program with loops that computes the sum of all square between 1 and 100 (inclusive) This is the code i have
int i=1;
int j=0;
while (i<101){
i = (i * i);
j= (j+i);
i++;
}
System.out.println(j);
Thanks, I've been searching through this book back and forth and found no ideas.
I will not solve your home-work problem directly.
But it will give you an idea what to do
Sum of all Odd numbers in given numbers
int sum = 0;
while(numbers are still there){
if(presentNumber % 2 == 1){
sum += presentNumber;
}
}
and for second problem, if I understood correctly, Sum of Square Numbers which lies in 1 to 100
Logically, square root of 100 is 10. so all the square numbers which lies in 1 to 100 are 1 to 10 inclusive.
That's sum of squares of 1 to 10 numbers (1^2+2^2+3^2+...+10^2)
int sum = 0;
for(int I=0;i<=10;i++){
sum += (i*i);
}
There are multiple way to approach the first option(odd / even numbers):
if ( x & 1 == 0 ) { even... } else { odd... } //This is because the low bit will always be set on an odd number.
or you can do something like:
boolean isEven(double num) { return (num % 2 == 0) }
Check Check whether number is even or odd for more option.
Now about the squares check out Fastest way to determine if an integer's square root is an integer for your answer

Resources