Following the answer from #neal aise here to get prime factors:
I did:
/*neal aise's code*/
printPrimeFactors(int num) {
int i;
for (i = 2; i < sqrt(num); i=next_prime(i)) {
if (num %i){
printf("%d", i);
}
}
}
/*my code*/
int next_prime(int p){
int prime_found = 0;
while (!prime_found){
if (p <= 1)/* if low number comes in, then */
p = 2; /* next prime is always 2 (first prime) */
else
if ((p % 2) == 0) /* no even primes */
p++; /* make the number odd before test */
else
p += 2; /* get next odd numero to test */
prime_found = is_prime(p); /*check if number is prime*/
}
return (p);
}
int is_prime(int p){
int curr_num = 2; /* start divisor at 2 */
float stop_num = sqrt((float) p); /* no divisor > sqrt of number needed */
while(curr_num <= stop_num){
if ((p % curr_num) == 0) /* not prime if evenly divisible */
return (0);
else
curr_num++; /* increment divisor */
}
return(1); /* not evenly divisible, return prime */
}
How do I moddify the code in function
printPrimeFactors()
so it works as desired?
If you want "prime number generator", interfaces is ok to me. But your code limit the number of prime numbers.
meaningless interfaces is not valuable. it can write more simply.
#include <stdio.h>
int main() {
int n, m;
for (n = 1; n < 1000 /* specify your max */; n++) {
for (m = n-1; m > 1; m--)
if (n % m == 0) break;
if (m == 1)
printf("%d\n", n);
}
return 0;
}
There are a couple of logic errors:
if (num%i) // Change this to...
if ((num%i)==0) // num%i == 0 when i divides num, this 'i' is a prime factor.
Also, you will only print out roughly half of the prime factors by stopping at <sqrt(num). Either change the exit condition of the for loop to be i <= num:
for (i = 2; i <= num; i=next_prime(i)) { // note the <=
if (num %i){
printf("%d ", i);
}
}
Or the alternative, more efficient method. Note the factors will not be in order:
for (i = 2; i <= sqrt(num); i=next_prime(i)) {
if (num %i){
printf("%d %d ", i, num/i); // Print out the pair, since we stop at i<=sqrt(num)
}
}
Instead of x = sqrt(n_limit) and if(n < x), you can do it like if(n*n < n_limit). No need for expensive sqrt(), floats or casts.
Related
I really tried but still don't know what's wrong with my code.
#include <stdio.h>
int main()
{
int n;
scanf("%d", &n);
int minus, i, judge;
for (minus = 0, judge = 1; judge == 1; minus++, n -= minus) {
for (i = 2; i * i < n; i++) {
if (n % i == 0)
judge = 1;
else judge = 0;
}
if (judge == 1)
continue;
else break;
}
printf("%d\n", n);
return 0;
}
When I input 143, the output is 143 not 139.
However, when I input 11, the output is the correct answer 11.
The loop test is incorrect: for (i = 2; i * i < n; i++)
If n is the square of a prime number, the loop will stop just before finding the factor.
You should either use i * i <= n or i <= n / i.
Furthermore, you do not enumerate all numbers as you decrement n by an increasing value at each iteration.
Note also that the loop would not find the closest prime to n, but the greatest prime smaller than n, which is not exactly the same thing.
Here is a modified version:
#include <limits.h>
#include <stdio.h>
int isPrime(int n) {
if (n <= 2 || n % 2 == 0)
return n == 2;
for (int i = 3; i <= n / i; i += 2) {
if (n % i == 0)
return 0;
}
return 1;
}
int main() {
int n;
if (scanf("%d", &n) != 1)
return 1;
if (n <= 2) {
printf("2\n");
} else {
for (i = 0;; i++) {
if (isPrime(n - i))
printf("%d\n", n - i);
break;
}
if (n <= INT_MAX - i && isPrime(n + i))
printf("%d\n", n + i);
break;
}
}
}
return 0;
}
I wrote this program to find prime numbers between 1 and 50000, and I still need to find how many prime numbers there is (I tried a lot of tricks but I did not succeed)
#include <stdio.h>
//int getValueFromUser();
void PrintListOfPrime(int value);
int main() {
int value = 23;
PrintListOfPrime(value);
return 0;
}
void PrintListOfPrime(int value) {
int ValueIsPrime; //ValueIsPrime is used as flag variable
printf("The list of primes: ");
for (int i = 2; i <= value; i++) {
ValueIsPrime = 1;
/* Check if the current number i is prime or not */
for (int j = 2; j <= i / 2; j++) {
/*
* If the number is divisible by any number
* other than 1 and self then it is not prime
*/
if (i % j == 0) {
ValueIsPrime = 0;
break;
}
}
/* If the number is prime then print */
if (ValueIsPrime == 1)
printf("%d, ", i);
}
printf("\n");
}
I tried a lot of tricks but I did not succeed
If OP's code takes too long to ran, iterate to the square root of i, not up to i/2.
j <= i / 2 is very slow. Use j <= i / j instead.
Form a count and increment with every prime. #gspr
if (ValueIsPrime == 1) {
printf("%d, ", i);
prime_count++;
}
Bigger change yet even faster to "find prime numbers between 1 and 50000", research Sieve of Eratosthenes
Hello fast answer is to create a variable in main, int totaleOfPrimes = 0; for example.
then send it by reference to the fucntion :
Function declaration : void PrintListOfPrime(int value,int* counter);
Function call : void PrintListOfPrime(value,&totaleOfPrimes);
then Increment counter befor printing :
if (ValueIsPrime == 1){
(*counter)++;
printf("%d, ", i);
}
There is no need to iterate the loops for all numbers between 2 and value. You should consider only 2 and odd numbers.
The function can look the following way as it is shown in the demonstrative program below.
#include <stdio.h>
static inline size_t PrintListOfPrime( unsigned int n )
{
size_t count = 0;
printf( "The list of primes:\n" );
for ( unsigned int i = 2; i <= n; i = i != 2 ? i + 2 : i + 1 )
{
int isPrime = 1;
/* Check if the current number i is prime or not */
for ( unsigned int j = 3; isPrime && j <= i / j; j += 2 )
{
/*
* If the number is divisible by any number
* other than 1 and self then it is not prime
*/
isPrime = i % j != 0;
}
/* If the number is prime then print */
if ( isPrime )
{
if ( ++count % 14 == 0 ) putchar( '\n' );
printf( "%u ", i );
}
}
return count;
}
int main(void)
{
unsigned int n = 50000;
size_t count = PrintListOfPrime( n );
printf( "\n\nThere are %zu prime numbers up to %u\n", count, n );
return 0;
}
Run this code in C. It will return the value of a pi(x) function. It is basically the Prime counting function:
#include <stdio.h>
#define LEAST_PRIME 2
#include <math.h>
int main() //works for first 10000 primes.
{
int lower_limit = 2, no_of_sets;
// printf("NUMBER OF SETS: ");
// scanf("%d", &no_of_sets);
int remainder, divisor = 2, remainder_dump, upper_limit; //upper limit to be specified
//by user.
int i = 1;
// printf("SPECIFY LOWER LIMIT: ");
// scanf("%d", &lower_limit);
int number_to_be_checked = lower_limit;
printf("SPECIFY UPPER LIMIT: ");
scanf("%d", &upper_limit);
printf("2\t\t\t\t", number_to_be_checked);
//PRINTS 2.*/
do
{
remainder_dump = 1;
divisor = 2;
do
{
remainder = number_to_be_checked % divisor;
if (remainder == 0)
{
remainder_dump = remainder_dump * remainder; // dumping 0 for rejection.
break;
}
++divisor;
} while (divisor <= number_to_be_checked / divisor); // upto here we know number
is prime or not.
if (remainder_dump != 0)
{
++i;
printf("%d.\t\t\t\t", number_to_be_checked); //print if prime.
};
number_to_be_checked = number_to_be_checked + 1;
} while (number_to_be_checked <= upper_limit);
printf("\n pi(x) = %d \n", i);
//printf("pi function value is %f.", (i - 1) / (log(i - 1)));
float app;
app = upper_limit / (log(upper_limit));
float plot_value;
plot_value = (i) / app;
printf(" BETA FUNCTION VALUE ~ %f", plot_value);
return 0;
}
I am trying to find prime nos up to 1000, but I am only getting 2 and 3.
void main()
{
int i = 1, j, n = 1000;
while (n != 0)
{
j = 2;
i++;
if (i % j != 0)
{
j++;
}
if (i == j)
{
printf("%d\n", i);
n--;
}
}
}
There are problems in your code:
you should #include <stdio.h>
the prototype for main is incorrect, it should return int.
you should initialize j outside the loop and run the tests in a slightly different order.
the code is not designed to find prime numbers up to 1000, but to find the first 1000 prime numbers.
Here is a corrected version:
#include <stdio.h>
// print the first 1000 prime numbers
int main() {
int i = 2, j = 2, n = 1000;
while (n != 0) {
if (i % j == 0) {
if (i == j) {
printf("%d\n", i);
n--;
}
j = 2;
i++;
} else {
j++;
}
}
return 0;
}
Note however that your algorithm is confusing and inefficient:
you combine in a single loop what should really be expressed as 2 nested loops.
you test all divisors up to i, whereas you could stop when j * j > i, reducing the time complexity from O(N2) to O(N1.5).
you could also special case 2 and only test odd numbers and divisors, further reducing the number of divisions by another factor.
Here is an alternative:
#include <stdio.h>
// print the first 1000 prime numbers
int main() {
int i, j, n = 1000;
if (n > 0) {
printf("%d\n", 2);
n--;
}
i = 3;
while (n > 0) {
for (j = 3;; j += 2) {
if (j * j > i) {
printf("%d\n", i);
n--;
break;
}
if (i % j == 0)
break;
}
i += 2;
}
return 0;
}
Your code has been implemented with a wrong logic. It doesn't look for the first divisor without remainder for each n.
To search primes you have to individuate each number that hasn't an integer divisor smaller than the given number, in other words: If the given number divided for all the possible divisors (smaller than it) generates a remainder (the remainder is not 0) it's a prime.
Try this way:
#include <stdio.h>
#include <math.h>
/* Computes all primes from 1 to 1000 */
int main(void)
{
int i,j,n=3; /* n=3 3 is the first odd number to test */
/* 2 is the only even prime number */
printf("%4d ",2);
while(n<1000) {
/* j=max usefull divisor */
j=(int)sqrt(n);
/* scanning divisors (i is the divisor)*/
for(i=3;i<=j && (n%i);i+=2);
/* if no divisor found print the number */
if (i>j) {
printf("%4d ",n);
}
/* Test the next odd number */
n+=2;
}
puts("");
return 0;
}
This code contains 3 tricks:
2 is the only even prime number.
If a number haven't a divisor within its square root it's a prime number.
We test only odd numbers (n=3; ... n+=2;) then the divisors may be only an odd number (i=3; ... i+=2).
Following your intent and what #Chqrlie said I made this other version:
#include <stdio.h>
/* Computes first 1000 primes */
int main(void)
{
int i,n=3, cnt = 1000; /* n=3 3 is the first odd number to test */
/* 2 is the only even prime number */
printf("%4d ",2);
cnt--; /* 2 was already written */
while(cnt) {
/* scanning divisors (i is the divisor)*/
for(i=3;i*i<n && (n%i);i+=2);
/* if no divisor found print the number */
if (i*i>n) {
printf("%4d ",n);
cnt--;
}
/* Test the next odd number */
n+=2;
}
puts("");
return 0;
}
The code above (as "indicate" #Chqrlie) avoids the square root and computes the first 1000 primes (as you expected from your code).
This is the Link to the problem: http://www.spoj.com/problems/PRIME1/
Basically we get two limits and we have to print out all the primes between them...
Here is my Code (Language == C) :
#include <stdio.h>
void IsPrime(int test){
for(int i= 2; i<test; i++){
if(test%i==0){
return;
}
}
printf("%d\n",test);
}
int main(){
int T,lower,upper;
scanf("%d",&T);
while(T--){
scanf("%d",&lower);
scanf("%d",&upper);
for(int i = lower;i<=upper;i++){
if(i>1){
IsPrime(i);
}
}
}
return 0;
}
On my local machine I ran this and it works for the simple test cases... My message from the website is timeout error so I was wondering if there is a more efficient way to solve this problem because apparently I am not solving it fast enough?
To begin with, you don't have to go checking every number up to n to determine if n is prime, only to its square root (there is a mathematical proof, not going to give it now). So:
void IsPrime(int test){
// i <= sqrt(test)
// but to avoid sqrt you can do i * i <= test
for(int i= 2; i * i <= test; i++){
if(test%i==0){
return;
}
}
printf("%d\n",test);
}
Next, we know that after 2, all other prime numbers are odd, so we can loop by 2 if we treat 2 as special case:
// Do greater than one check only once
if (lower > 1) {
// Special case - lower is 2
if (lower == 2) {
printf("%d\n", 2);
++lower;
}
for(int i = lower; i <= upper; i += 2){
IsPrime(i);
}
}
However since you have to do it T times, you will end up doing the checks a lot more than needed. Also, the problem has limits on n and m so it's basically perfect for a sieve, as #HennoBrandsma said.
Using these optimizations, you should go find all prime numbers to the limit, and store them in a container. Then, when prompted with a range, simply traverse the sieve and print out the numbers.
(That will require you to change up the IsPrime function a bit more - instead of printing the number right away, let it return true or false, and then based on that, add the number to the container)
You can try the following which has a slight optimization on the number of tests as well as skipping any even values greater than 2:
int isprime (int v)
{
int i;
if (v < 0) v = -v; /* insure v non-negative */
if (v < 2 || !((unsigned)v & 1)) /* 0, 1 + even > 2 are not prime */
return 0;
if (v == 2) return 1;
for (i = 3; i * i <= v; i+=2)
if (v % i == 0)
return 0;
return 1;
}
If you can use the math library and math.h, the following may be faster:
int isprime (int v)
{
int i;
if (v < 0) v = -v; /* insure v non-negative */
if (v < 2 || !((unsigned)v & 1)) /* 0, 1 + even > 2 are not prime */
return 0;
if (v == 2) return 1;
for (i = 3; i <= sqrt (v); i+=2)
if (v % i == 0)
return 0;
return 1;
}
I timed both versions over the int range for values between 1-2 million and they are close.
Note: In actual testing with repetitive calls, the version with i * i <= v (isprime2 below) is consistently faster than the call with i <= sqrt (v) (isprime3 below). e.g.:
$ ./bin/isprimetst2
isprime (1.650138 sec) - 78497 primes
isprime2 (0.805816 sec) - 78497 primes
isprime3 (0.983928 sec) - 78497 primes
The short driver iterated over all primes from 0-2000000, e.g.:
r = 0;
t1 = clock ();
for (v = 0; v < 2000000 - 1; v++) r += isprime2 (v);
t2 = clock ();
printf (" isprime2 (%lf sec) - %u primes\n", (t2-t1)/CLOCKS_PER_SEC, r);
r = 0;
t1 = clock ();
for (v = 0; v < 2000000 - 1; v++) r += isprime3 (v);
t2 = clock ();
printf (" isprime3 (%lf sec) - %u primes\n", (t2-t1)/CLOCKS_PER_SEC, r);
You can use a library maths.h in C and use sqrt function to calculate the square root of given number. So the program might be like this:
#include <stdio.h>
#include <maths.h>
int isPrime(int number){
int i;
if(number % 2 == 0){
return;
}
for(i=3; i<=sqrt(number); i++){
if(number % i == 0){
return;
}
printf("%d\n",number);
}
int main(){
int lower,upper,i;
if(lower >1){
if(lower == 2){
printf("2\n");
}
for(i=lower; i<=upper; i++){
isPrime(i);
}
return 0;
}
In short you can use some extra checks (like if(number % 2 == 0)) using if-else condition to decrease the time complexity of the program.For example a new if condition may be if(number % 5 ==0) etc. ,so with the help of these conditions check won't go in for loop in many of the cases, and that would decrease the time of the program.
#include<stdio.h>
int main()
{
int low,high,j;
int prime(int);
int t;
scanf("%d",&t);
while (t>0)
{
scanf("%d %d",&low,&high);
while (low<=1)
{
low++;
continue;
}
for (j=low;j<=high;j++)
{
if (prime(j)){
printf("%d\n",j);
}
}
printf("\n");
t--;
}
return 0;
}
int prime(int n)
{
int i;
for (i=2;i*i<=n;i++)
{
if (n%i==0){
return 0;
}
}
return 1;
}
I've been doing a few of the challenges on the Sphere Online Judge (SPOJ), but I can't seem to get the second problem (the prime generator) to run within the time limit. How can the speed of the following code be increased?
#include <stdio.h>
#include <math.h>
int is_prime(int n);
void make_sieve();
void fast_prime(int n);
int primes[16000];
int main()
{
int nlines;
int m, n;
make_sieve();
scanf("%d", &nlines);
for (; nlines >= 1; nlines--) {
scanf("%d %d", &m, &n);
if (!(m % 2)) {
m++;
}
for ( ; m < n; m+=2) {
fast_prime(m);
}
printf("\n");
}
return 0;
}
/* Prints a number if it's prime. */
inline void fast_prime(int n)
{
int j;
for (int i = 0; ((j = primes[i]) > -1); i++) {
if (!(n % j)) {
return;
}
}
printf("%d\n", n);
}
/* Create an array listing prime numbers. */
void make_sieve()
{
int j = 0;
for (int i = 0; i < 16000; i++) {
primes[i] = -1;
}
for (int i = 2; i < 32000; i++) {
if (i % 2) {
if (is_prime(i)) {
primes[j] = i;
j++;
}
}
}
return;
}
/* Test if a number is prime. Return 1 if prime. Return 0 if not. */
int is_prime(int n)
{
int rootofn;
rootofn = sqrt(n);
if ((n <= 2) || (n == 3) || (n == 5) || (n == 7)) {
return 1;
}
if (((n % 2) == 0) || ((n % 3) == 0) || ((n % 5) == 0) || ((n % 7) == 0)) {
return 0;
}
for (int i = 11; i < rootofn; i += 2) {
if ((n % i) == 0) {
return 0;
}
}
return 1;
}
isprime() does not make use of the prime number table primes[].
Plus, implement a search of the primes array that will complete quickly using a binary search algorithm. The standard library has one.
To see where your time is spent in code you can use profiling
gcc example
gcc -p -g - o mycode mycode.c
===run the code--
gprof mycode
Currently, your problem isn't time limit. Its the fact that your program never print any numbers.
The most obvious error is that in fast_prime you are checking if n is divisible by prime[0], prime[1],... up to prime[k]. Even if n is prime, you won't print it, because n is somewhere in primes[], and so you'll get that n is divisible by some number...
To correct this, you need to check that n is divisible by some prime number up to the square root of n (this will also have the side effect of speeding up the code, as less numbers will be checked before deciding some number is a prime)
change fast_prime to
inline void fast_prime(int n)
{
int j;
int rootofn;
rootofn = sqrt(n);
for (int i = 0; ((j = primes[i]) > -1) && (j<rootofn); i++) {
if (!(n % j)) {
return;
}
}
printf("%d\n", n);
}