Printing largest prime factor of a composite number - c

I want the output to be like this:
6857
1471
839
71
But I am getting the numbers that are not even the factors of 600851475143.
What is wrong with this code?
The output should be all prime numbers and their product must be equal to 600851475143.
#include <stdio.h>
#include <math.h>
#include <time.h>
int temp;
void fact(long a);
int prime(int a);
int main(){
fact(600851475143);
}
void fact(long num){
for(int i=2; i<sqrt(600851475143); i++){
if(num%i == 0){
if(prime(i)){
printf("%d\n", i);
temp=num/i;
fact(temp);
}
}
}
}
int prime(int num){
for(int i=2; i<num; i++){
if(num % i == 0){
break;
}else{
return i;
}
}
}

The number whose factor you are trying to find is out of the range of values that long can hold.Here you can see maximum size of values that data type in c can store.Also, I would recommend using long long at all places where the number to be stored is derived from the num i.e. in your program everywhere.Make sure not to change data types unless you are sure that it won't cross its maximum limit.
Also, how can you use
for(int i=2; i<sqrt(600851475143); i++)
in C code?Thats the C++ feature.
Also, there is no need for
#include <time.h>
so your code should look something like this:
#include <stdio.h>
#include <math.h>
//#include <time.h>
int temp;
void fact(long long a);
long long prime(long long a);
int main(){
fact(600851475143);
}
void fact(long long num){
long long i=2;
for(; i<sqrt(600851475143); i++){
if(num%i == 0){
if(prime(i)){
printf("%d\n", i);
}
}
}
}
long long prime(long long num){
long long i=2;
int k = 1;
for(; i<num; i++){
if(num % i == 0){
k=0;
break;
}
}
return k;
}
Hope it helps.

Related

Why does my code work without "void" in my main function?

I have to do a short assignment for my introductory C class, where I have to ask for a number "N" from the user and calculate it's factorial. The requirements were for me to create a function with the prototype long int factorial(int N). I managed to do it, but I'm confused as to why my code is working with a specific change I made. Here is my code:
#include <stdio.h>
long int factorial(int);
int main(void)
{
int N;
printf("Enter a number: ");
scanf("%d", &N);
printf("The factorial of %d is: %ld", N, factorial(N));
return 0;
}
long int factorial(int N)
{
long int result=1 ;
int i;
for(i=1; i<=N; i++)
result = result * i;
return result;
}
My code at this point didn't work, and would just return the result of N+1 (if I input 5 for example, it would output 6). I was tweaking random things at this point to see what was the problem, and the removal of "void" in my main function fixed it. The problem is, I don't understand why.
#include <stdio.h>
long int factorial(int);
int main()
{
int N;
printf("Enter a number: ");
scanf("%d", &N);
printf("The factorial of %d is: %ld", N, factorial(N));
return 0;
}
long int factorial(int N)
{
long int result=1 ;
int i;
for(i=1; i<=N; i++)
result = result * i;
return result;
}
Could anyone explain why the removal of void in my code fixed this?

The following program "Counting consecutive 1's of a binary no" shows different ans when input goes more than 8-digit value?

I have tried different inputs and when it exceeds a 7 or 8 digit value it just shows some wrong answers as outputs but it worked fine with most of my cases.
#include <stdio.h>
#include <stdlib.h>
int bin(unsigned long long int n){//gave function for binary convertion
if(n==0)
return 0;
else
return (n%2+10*bin(n/2));
}
int main()
{
unsigned long long int n,x;/*I even gave high digit data type*/
int i, v, count=0, max=0;
scanf("%llu",&n); /*if input is >8-digit output is wrong*/
x = bin(n);
v = floor(log10(x))+1; /*Its length*/
int a[v];
for(i = v-1; i >= 0; i--){ /*string it in array*/
a[i] = x%10;
x = x/10;
}
for(i = 0; i < v; i++){
if(a[i] == 0){
count = 0;}
else{
count++;}
if(max < count){
max = count;}
}
printf("%d",max);/*I gave 99999999 output is 8 but its shows 9*/
}
Your program has a number of problems. Here is one example:
int bin(unsigned long long int n){
^^^
The function returns an int so the calculation will overflow for even small numbers:
printf("%d\n", bin(1023)); // will print 1111111111 (fine)
printf("%d\n", bin(1024)); // will/may print 1410065408 (ups - very bad)
Even if you change to
unsigned long long int bin(unsigned long long int n){
overflow will happen soon.
In I'll recommend that you look directly into the binary pattern of the number using the & operator.
I'll not solve the complete task for you but here is some code that may help you.
#include <stdio.h>
#include <stdlib.h>
int main()
{
size_t t = 1;
size_t limit;
size_t n;
if (scanf("%zu", &n) != 1)
{
printf("Illegal input\n");
exit(1);
}
limit = 8 * sizeof n; // Assume 8 bit chars
for (size_t i = 0; i < limit; ++i)
{
if (n & t)
{
printf("Bit %zu is 1\n", i);
}
else
{
printf("Bit %zu is 0\n", i);
}
t = t << 1;
}
return 0;
}

Unexpectedly crash in program for finding prime numbers

I would like to write a program which can find all prime numbers between two numbers in t test cases. But my program had crashed when I run it.
Please, could anyone help me?
My code:
#include <stdio.h>
#include <malloc.h>
#include <math.h>
void print(int a,int b)
{
int *p,i;
int x;
p = (int *) malloc (sizeof(int)*(b-a));
for(i=0;i<(b-a);i++) p[i]=a+i;
for(i=0;i<(b-a)/2;i++)
{
if(p[i]!=0)
{
if(p[i]%i==0) p[i]=0;
}
}
for(i=0;i<=(b-a);i++) if(p[i]!=0) printf("%d ",p[i]);
free(p);
}
int main(void)
{
int t,i,m,n;
scanf("%d",&t);
for(i=0;i<t;i++)
{
scanf("%d %d",&m,&n);
print(m,n);
}
return 0;
}
The problem is stumbling on allocating memory in a range, allocating one element too few (should have been malloc (sizeof(int)*(b-a+1));) and then not sticking to indexing the memory allocated. This could be so much simpler: no arrays needed - if a number has a divisor, there is no need to check any other divisors.
Sometimes it is easier to side-step the problems than struggle with them.
#include <stdio.h>
#include <math.h>
int prime(int n)
{
int s, i;
if (n == 1 || n == 2)
return 1;
if (n % 2 == 0) // no even numbers
return 0;
s = (int)sqrt(n); // limit the loop
for (i=3; i<=s; i+=2) // odd numbers only
if (n % i == 0)
return 0;
return 1;
}
void print(int a, int b)
{
int n;
for (n=a; n<=b; n++)
if (prime (n))
printf("%d ", n);
printf("\n");
}
int main(void)
{
int t, i, m, n;
printf("Input number of ranges to test: ");
scanf("%d", &t);
for(i=0; i<t; i++)
{
printf("Input bottom and top of range: ");
scanf("%d %d", &m, &n);
print(m, n);
}
return 0;
}
You messed up the termination of the for-loops. You allocated b-a bytes but you are iterating over b-a+1 items...
for(i=0;i<=(b-a);i++) p[i]=a+i;
needs to be a i<(b-a) or else you have a segfault (in both loops).
Also as BLUEPIX pointed out:
for(i=0;i<b/2;i++)
needs to be i<(b-a)/2 for iterating over half the intervall.
p[i]%i
Division by zero in the first iteration i==0.
After this the programm should terminate without an error.

Find 10000th prime number [duplicate]

This question already has answers here:
Prime Number Algorithm
(7 answers)
Closed 8 years ago.
This is my code for finding 10000th prime number but it is really slow, it takes 7 seconds to calculate.
#include <stdio.h>
#include <stdlib.h>
long int prime (int n)
{
int i;
for(i=2;i<n;i++)
{
if(n%i==0)
return 0;
}
return 1;
}
int main()
{
int i=2,counter=0;
while(1)
{
if(prime(i))
counter++;
if(counter==10000)
break;
i++;
}
printf("10000th prime number is: %d",i);
}
It is brute force method so that's probably reason why it's so slow.
I think problem may be that it has to call function so many times. So what do you think can it be optimised or it's better to find some math formula for this.
You can reduce the time substantially by making the following changes to prime():
Stopping at sqrt(n).
Starting at i=3, and incrementing i by 2.
Here's a program that contains both versions and the time taken by each.
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <math.h>
int is_prime1 (int n)
{
int i;
for(i=2;i<n;i++)
{
if(n%i==0)
return 0;
}
return 1;
}
void do_it1(int max)
{
clock_t start = clock();
clock_t end;
int i=2,counter=0;
while(1)
{
if(is_prime1(i))
counter++;
if(counter==max)
break;
i++;
}
end = clock();
printf("%dth prime number is: %d\n", max, i);
printf("Time taken: %lf\n", 1.0*(end-start)/CLOCKS_PER_SEC);
}
int is_prime2 (int n)
{
int i;
int stop = sqrt(n);
for(i=3;i<=stop;i+=2)
{
if(n%i==0)
return 0;
}
return 1;
}
void do_it2(int max)
{
clock_t start = clock();
clock_t end;
int i=3,counter=1;
while(1)
{
if(is_prime2(i))
counter++;
if(counter==max)
break;
i += 2;
}
end = clock();
printf("%dth prime number is: %d\n", max, i);
printf("Time taken: %lf\n", 1.0*(end-start)/CLOCKS_PER_SEC);
}
int main(int argc, char** argv)
{
int max = atoi(argv[1]);
do_it1(max);
do_it2(max);
}
Sample execution:
./test 10000
Sample output:
10000th prime number is: 104729
Time taken: 9.469000
10000th prime number is: 104729
Time taken: 0.078000
To optimized your code a little bit (changes are made based on comments):
long int prime (int n)
{
int i;
int e = (int)sqrt(n);
for(i=2; i<=e;i++)
{
if(n%i==0)
return 0;
}
return 1;
}
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int *prime;
int prime_n;
void make_prime_table(int n){
prime = malloc(sizeof(int) * n / 2);
prime_n =0;
prime[prime_n++] = 2;
prime[prime_n++] = 3;
int i, j;
for(i = 5; i <= n; i +=2){
bool is_prime = true;
for(j = 1; j < prime_n ; ++j){
int t = prime[j];
if(t * t > i)
break;
if(i % t == 0){
is_prime = false;
break;
}
}
if(is_prime)
prime[prime_n++] = i;
}
}
int main(void){
int n = 105000;
make_prime_table(n);
if(prime_n >= 10000)
printf("10000th prime number is: %d\n", prime[9999]);
free(prime);
return 0;
}

first 50 positive numbers divisible by 4

This is the code I reached.
what I don't get is the condition where x should stop. I know what I wrote is wrong.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int x, i;
for(i=0; i<=50; i++)
{
for (x=0;x<=50 ;x++ )
{
if (x%4==0)
printf ("%d\n", x);
}
}
return 0;
}
The simplest solution, as suggested by Art in a comment above:
for(unsigned int c=1; c<=50; c++)
{
printf ("%d\n", c*4);
}
Original answer: One loop is enough. And increase by 4 (every 4th number is divisible by 4, and none else):
int curNum=4;
for (unsigned int c=1; c<=50; c++, curNum+=4)
{
printf ("%d\n", curNum);
}
So you see we have two variables, one counts the numbers we have printed already (c), and the other contains the current number to be printed (curNum).
With this code you are showing numbers less than 50 that are divisible by 4 & then you are printing it 50 times. Although your question has been answered but if you are hell bent on checking if a number is divisible by 4 & using two for loops, this might work.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int x=0, i;
for(i=0; i<=50; i++)
{
for(;;)
{
if(x%4==0)
{
printf("\n%d",x);
x++;
break;
}
x++;
}
}
return 0;
}
int main()
{
int x = 0;
int i = 0;
while(i<50)
{
if (x % 4==0)
{
printf ("(result %d) %d is divisible by 4\n", i, x);
i++;
}
x++;
}
return 0;
}
No need to use nested for loops. Try this
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i = 0, count = 1;
while(1)
{
if (i%4==0)
printf ("%d\n", i);
i++;
if (count++ == 50)
break;
}
return 0;
}
you just need one for
#include <stdio.h>
#include <stdlib.h>
int main()
{
unsigned int n = 0;
unsigned int i = 0;
while(n < 50)
{
if (i%4==0){
printf ("%d\n", i);
++n;
}
++i;
}
return 0;
}

Resources