how to list all pairs of sexy primes - c

How can i write a program that lists all sexy prime pairs that exist in n numbers.
For example if n = 10 the output should be (5, 11) and (7, 13)
My idea was to generate all primes within n and then add 6 to each and check if the i + 6 is a prime. But it doesnt work, there's no output and the program ends.
#include <stdio.h>
int main() {
int i, j, n, k, isprime = 1, prime2, flag = 0;
scanf("%d", &n);
for (i = 3; i <= n; i++){
for (j = 2; j <= i; j++){
if (i % j == 0)
break;
}
if (i == j){
prime2 = i + 6;
for (k = 3; k <= prime2; k++){
if (prime2 % k == 0){
flag++;
break;
}
}
if (flag == 0){
printf("%d %d\n", i, prime2);
}
}
}
return 0;
}
Any ideas of what im doing wrong or any tips on how to solve it? (with loops only)

As there're a lot of resources about finding a prime number, I'm not going to discuss that. Rather I'll try to point out the bug in your code.
First problem:
for (k = 3; k <= prime2; k++)
Here you need to run the loop till prime2 - 1. Also you should start checking from 2 rather than 3, just like you did previously. That means,
for (k = 2; k < prime2; k++)
or
for (k = 2; k <= prime2 - 1; k++)
Reason: when k = prime2, prime2 % k will be 0. For finding out whether a number is prime we don't need to check if that number is divisible by 1 and that number itself.
Note: Now you might think why the first prime number loop for (j = 2; j <= i; j++) is working .
It's working because you've given an additional condition if (i == j) after it.
Second problem:
You need to declare the flag variable within the first loop.
for (i = 2; i <= n; i++)
{
int flag = 0;
.... (rest of the code)
....
}
Reason: Basically with the flag value, you're trying to find out whether prime2 is a prime number.
Every time you'll get a prime number from the first loop, you'll have a new value of prime2. In your code, once you're incrementing the value of flag, you're never resetting the flag value.
That's why once your code detects a prime2 which is not a prime, it'll never detect the second prime number again (prime2 which is actually prime).
Overall code:
#include <stdio.h>
int main()
{
int i, j, n, k, isprime = 1, prime2;
scanf("%d", &n);
for (i = 3; i <= n; i++)
{
int flag = 0; // changing point
for (j = 2; j <= i; j++)
{
if (i % j == 0)
break;
}
if (i == j)
{
prime2 = i + 6;
for (k = 2; k < prime2; k++) // changing point
{
if (prime2 % k == 0)
{
flag++;
break;
}
}
if (flag == 0)
{
printf("%d %d\n", i, prime2);
}
}
}
return 0;
}
Few resources to know more about finding out prime numbers:
Prime Numbers
C Program to Check Whether a Number is Prime or not
Sieve of Eratosthenes

You can use Sieve to speed up the program. It can generate all pairs in O(N log N) time. Here's the Algorithm.
Now, you have a boolean array, is_prime where is_prime[i] is true if i is a prime, false otherwise.
Now, iterate from i = 1 to i = N and check if is_prime[i] && is_prime[i + 6], if the condition is true, output the pair.

Related

C - Print all prime numbers from 1 to 100 using arrays

OK so I got this challenge where I have to print all the primes from 1 to 100... However there is an error in my code that I am unable to find. Here is how I thought the problem should be done:
For any number from 3 to 100 check if there is any other number in the primes array that divides it. If there is the number is not prime. If there is not the number is prime and should be added to the array. Pretty simple, right ?
However it is not working.
Here is my code :
#include <stdio.h>
int main() {
int Primes[50] = {0};
int i, j, k;
Primes[0] = 2;
Primes[1] = 3;
for (i = 3; i < 101; i++) {
for (j = 2; j < 100; j++) {
if (i % Primes[j] != 0 && Primes[j] != 0) {
Primes[j] = i;
}
}
}
printf("Primes array : \n");
for (k = 0; k < 51; k++) {
printf("%d ", Primes[k]);
}
return 0;
}
instead of assuming the magic number as 25... that is k!=25, we can
replace it with i<=100.
#include <stdio.h>
#include <stdlib.h>
int main(void){
int Primes[50] = {0};
int i,j,k = 0;
Primes[0]=2;
Primes[1]=3;
for(i=0; i<=100; i++) {
for(j = 2; j<=i; j++) {
if(i % j == 0 ){
if(i == j)
Primes[k++]=i;
break;
}
}
}
printf("Primes array : \n");
for(int index = 0;index < k; index++) {
printf("%d\n", Primes[index]);
}
return 0;
}
When you do this:
if(i % Primes[j] != 0 && Primes[j] !=0)
{
Primes[j]=i;
}
You're saying "if the current number is not divisible by the given prime number, replace the given prime number with the current number". This is not what you want.
You need to check if the current number is not divisible by any prime number. So you need to loop though the list of primes to make sure your number isn't divisible by any of them, and if so add the number to the end of the list. You can do that as follows:
int num_primes = 0;
for (i=2;i<101;i++)
{
int is_prime = 1;
for(j=0; j<num_primes && is_prime; j++)
{
if(i % Primes[j] == 0)
{
is_prime = 0;
}
}
if (is_prime) {
Primes[num_primes++] = i;
}
}
In the above code, we use num_primes to count the number of primes we have so far, and is_prime to see if we found a prime that divides the current number. As you divide each number by a prime, if the remainder is 0 you know the number is not prime and set is_prime to 0. This also causes the inner loop to exit right away. Then if is_prime is still set at the end of the inner loop, you have a prime and you add it to the end of the list.
You also have an off-by-one error in the printing loop:
for(k=0;k<51;k++)
Since Primes has size 50, the largest valid index is 49. So change it to:
for(k=0;k<50;k++)
There are lot of issues in the algorithm you used. Use this simple version with issues addressed in the code.
int main(void){
int Primes[50] = {0};
int i,j,k = 0 /* use for prime count purpose */;
Primes[0]=2;
Primes[1]=3;
for(i=4 /* 3 is already stored */; k != 48; i++) { /* rotate loop until prime count doesn't reaches 48 */
for(j = 2; j<=i; j++) { /* i is the number you want to check whether its prime or not. SO rotate loop from 2 to "i" */
if(i % j == 0){ /* use i%j not i % Primes[j] as you want to check whether i is prime or not */
if(i == j) /* if its a prime numbur j reaches upto i */
Primes[k++]=i; /* store it */
break; /* comes out of inner loop */
}
}
}
printf("Primes array : \n");
for(int index = 0;index < k; index++) { /* rotate k times not some random 51 times */
printf("%d ", Primes[index]);
}
return 0;
}
The code above doesn't actually give what we want, but beautiful code nonetheless. Here is the edited code that gives the prime numbers from 1 to 100
int main(void){
int Primes[50] = {0};
int i,j,k = 0 /* use for prime count purpose */;
Primes[0]=2;
Primes[1]=3;
for(i=0 /* 3 is already stored */; k != 25; i++) { /* rotate loop until prime count doesn't reaches 48 */
for(j = 2; j<=i; j++) { /* i is the number you want to check whether its prime or not. SO rotate loop from 2 to "i" */
if(i % j == 0){ /* use i%j not i % Primes[j] as you want to check whether i is prime or not */
if(i == j) /* if its a prime numbur j reaches upto i */
Primes[k++]=i; /* store it */
break; /* comes out of inner loop */
}
}
}
printf("Primes array : \n");
for(int index = 0;index < k; index++) { /* rotate k times not some random 51 times */
printf("%d\n", Primes[index]);
}
return 0;
}

Why is my code not able to print Prime Numbers within the given range?

I'm trying to print the Prime numbers between a given range but I get blank output. Where have I gone wrong? Is it a logic mistake or implementation mistake?
#include <stdio.h>
int isPrime(int i)
{
int j;
for(j=2; j<=i; j++)
{
if(i%j==0)
{
return 0;
}
}
return 1;
}
int main()
{
int cases, n1, n2, i;
scanf("%d", &cases);
while(cases>0)
{
scanf("%d%d", &n1, &n2);
for(i=n1; i<=n2; i++)
{
if(isPrime(i))
{
printf("%d\t", i);
}
}
cases--;
}
return 0;
}
You must stop the loop in isPrime before i because all non zero numbers are divisible by themselves:
int isPrime(int i) {
int j;
for (j = 2; j < i; j++) {
if (i % j == 0) {
return 0;
}
}
return 1;
}
Note that you should also return 0 for numbers below 2. Furthermore, you can improve performance dramatically by stopping at the square root of i and by testing only odd numbers above 2.
int isPrime(int i) {
if (i <= 2) {
return i == 2;
}
for (int j = 3; j * j <= i; j += 2) {
if (i % j == 0) {
return 0;
}
}
return 1;
}
i%i==0 will be always true unless i is zero, so isPrime will return 0 for whatever i which is 2 or greater.
You can use j<i instead of j<=i, for example.
Another point is that your isPrime will mistakenly judge all integers that is 1 or less as primes, so you should check for them before the loop.
Apart from being sub-optimal, your code goes all the way to i when trying to find the divisor. This means that all checks will eventually succeed when i == j, so i%j is zero.
A better stopping condition for the loop is
for( j=2 ; j*j <= i ; j++)
In other words, stop upon passing the square root of i. This is valid, because if you have not found proper divisors smaller than the square root, then it is guaranteed that there are also no divisors larger than the square root.
If you know the upper limit for n2, you could make your solution even faster by pre-computing all primes up to sqrt(n2), and using them to test whether other numbers are prime or not.
For starters 2 is a prime number. And every number is divisible by itself. So this condition
if(i%j==0)
will be always equal to true when j is equal to i.
The function can be written the following way
int isPrime( unsigned int x )
{
int prime = ( x == 2 ) || ( x % 2 != 0 && x > 2 );
for ( unsigned int i = 3; prime && i * i <= x; i += 2 )
{
prime = x % i != 0;
}
return prime;
}

I'm using the sieve of Eratosthenes as a primality test. Why am I getting that 2297 is composite?

I am using the Sieve of Eratosthenes to calculate the first 500 prime numbers. What the program does is evauate n % p where n is the user input and p is between 2 and sqrt(n).
I'm testing my program for the case n = 2297, which is a prime. Why does my program say it's composite?
bool primalityTestSieve(int n){
if(n == 2) return true; //tiny complication due to ceil(sqrt(2))
//Sieve with first MAX
bool arr[MAX - 1];
int i, j, s = ceil(sqrt(n));
for(i = 2; i < MAX; i++){
arr[i - 2] = true; //fill arr[] with true
}
for(i = 2; i < (int) sqrt(MAX); i++){
if(arr[i - 2]){
for(j = i*i; j < MAX; j+= i)
arr[j - 2] = false;
}
}
//Array storing the primes
int primes[MAX];
j = 0; //Counter for the index of the primes
for(i = 0; i < MAX; i++)
if(arr[i]){
primes[j] = i + 2;
j++;
}
//Prime test, first using sieve
for(i = 0; primes[i] <= s; i++)
if(n % primes[i] == 0) return false;
//Naive prime test for larger divisors
for (i = primes[j]; i <= s/2; i++)
if(((n % 2) == 0)||((n % (2*i + 1)) == 0)) return false;
return true;
}
Note that MAX is a parameterised macro and is equal to 500.
Your code uses the sieve to find the primes between 2 and 500. (Not the first 500 primes as you seem to say in your text).
Then you copy those primes into the primes[] array with j as the count of how many items are in the array. So at this point primes[] contains some numbers less than 500 followed by a bunch of junk.
Then you have the code:
for(i = 0; primes[i] <= s; i++)
s would be 48 for n == 2297. This loop will then check for n being divisible by any of the primes up to 48 , which would fail. (This loop should also have i < j as a condition so it does not read into the junk if you enter a large n).
However you then write:
for (i = primes[j]; i <= s/2; i++)
Remmeber that j currently holds the prime count, and the primes are in primes[0] through primes[j-1]. This means primes[j] is a junk value; so you set i to junk causing undefined behaviour.
(I'm not sure what you were actually trying to do in that last loop, it's unclear where you want to start and finish, or why you test n%2 every loop iteration, etc. - if you can describe what you are trying to do there then I'll suggest some code).

find the prime numbers in C

I have this code for prime numbers..it gives me the prime numbers up to 103.Maybe my first break statement is wrong? I did it this way because i want to skip as much numbers as possible.i want only the primes that have at least two digits(that is why i started from 11)
#include <stdio.h>
#define MAXNUMB 100000000
int main (void)
{
int i, j;
for (i = 11 ; i < MAXNUMB ; i += 2)
{
if ((i % 3 == 0) && (i % 5 == 0) && (i % 7 == 0))
break;
for (j = 3 ; j * j <= i ; j += 2)
{
if (i % j == 0)
break;
}
if (j * j > i)
printf ("%d \n", i);
}
}
Use continue rather then break; Here you want to skip much number ( As if there are many ways to find the prime numbers in small complexity like much popular Sieve of Eratosthenes) but it breaks. So change a little..
if((i%3==0)&& ( i%5==0) && (i%7==0))
continue;// here
it works..
#include <stdio.h>
#include <string.h>
#define MAXNUMB 100000000
int main (void)
{
int i, j, P[MAXNUMB];
memset(P, 0, sizeof(P));
for(i = 2; i < MAXNUMB; ++i)
{
if(P[i] == 0){
printf("%d\n", i);
if(i < MAXNUMB / i)
for(j = i*i; j < MAXNUMB; j += i)
P[j] = 1;
}
}
return 0;
}
As it would be obvious using a debugger, that statement is wrong. First, you check for numbers that are divisible by 3 and 5 and 7. 105 is divisible by all. Then you break, which means "exit this for loop", so the program will end. You need to just continue the looping and not report this number as a prime.
You want to change the loop to use or instead of and. Also the next for loop doesn't need to start from 3 then, since you already tried 3, 5, 7. But is there a reason for that since you could just use the for loop?
My suggestion would be to just forget the first if altogether since it will not make it any faster.
#include <stdio.h>
#define MAXNUMB 100000000
int main (void)
{
int i, j, f;
for (i = 11; i < MAXNUMB; i += 2)
{
for (j = 2, f = 1; f && j * j < i; ++j)
{
f = (i % j != 0);
}
if (f) printf("%d\n", i);
}
return 0;
}

Prime numbers in C and is_prime

I'm writing a program to find all of the prime numbers contained within a user input n. I am having trouble with the is_prime function.
#include <stdio.h>
#include <math.h>
main() {
int n;
int k;
// gets user input for length of string
// and stores it as n
printf("Enter the value of n:");
scanf("%d", &n);
for (k = 2; k <= n; k++) {
if (is_Prime(k) == 1) {
printf("Printing primes less than or equal to %d: /n %d, &n, &k");
}
}
I want the output to look like this, but I am not sure how to print the list without using different variables for each prime number.
Printing primes less than or equal to 30:
2, 3, 5, 7, 11, 13, 17, 19, 23, 29.
//here is the is_Prime function
is_Prime (int n)
{
for(j = 2; j <= n/2; j++)
{
if(n%j != 0)
{
return 1;
break;
}
}
if(n%j == 0 )
return 0;
}
I am not sure how to call the is_prime subroutine? Any help?
printf("Printing primes less than or equal to %d:\n", n);
for(k = 2; k <= n; k++)
{
if(is_Prime(k) == 1)
{
printf("%d, ", k);
}
}
printf("Printing primes less than or equal to %d:\n%s", n, (n >= 2 ? "2" : ""));
for (k = 3; k <= n; ++k)
if (is_Prime(k))
printf(", %d", k);
printf("%s\n", (n >= 2 ? "." : ""));
Here's a slightly cleaner version of your is_Prime function:
int is_Prime(int n)
{
if (n < 2)
return 0;
int last = (int) sqrt(n) + 1; /* conservatively safe */
for (int j = 2; j <= last; ++j)
if (0 == n % j)
return 0;
return 1;
}
Note that you only really need to check up to the sqrt() of a number to find all its potential factors.
Also note that this is not a great way to find all the primes less than n, which is the prime purpose of your program, especially when you will repeatedly call this function incrementing n by 1 each time. I recommend trying to implement the Sieve of Eratosthenes or the Sieve of Sundaram instead -- so long as n isn't too large.

Resources