C program : Does not execute beyond 1000 or just hangs - c

This program is to find three four digit prime numbers, such that they are permutations of each other and have a difference of 3320 between them. Now the following program correctly produces the prime numbers but execution stops or just hangs after the value 1000. Why this happens and how can I correct it?
#include<stdlib.h>
#include<stdio.h>
#define LIMIT 1000000
long int arr[LIMIT];
int Bsearch(long int *primes,long int low,long int high,long int search)
{
while(low<=high)
{
long int mid=(low+high)/2;
if(search<primes[mid])
{
high=mid+1;
}
else if(search>primes[mid])
{
low=mid+1;
}
else if(search==primes[mid])
return 1;
}
return 0;
}
int checkPermu(long int *primes,long int i,long int j,long int k)
{
long int prod1=1;
long int prod2=1;
long int prod3=1;
for(int i=0;i<3;i++)
{
prod1*=primes[i%10];prod2*=primes[j%10];prod3*=primes[k%10];
i/=10;j/=10;k/=10;
}
prod1*=primes[i];prod2*=primes[j];prod3*=primes[k];
if(prod1==prod2==prod3)
return 1;
else
return 0;
}
int main()
{
for(long int i=1;i<LIMIT;i++)
{
arr[i]=1;
}
for(long int i=2;i<LIMIT;i++)
{
if(arr[i]==1)
{
for(long int j=2;i*j<LIMIT;j++)
{
arr[i*j]=0;
}
}
}
long int index=0;
long int count=0;
//count number of primes
for(long int i=1;i<LIMIT;i++)
{
if(arr[i]==1) count++;
}
long int primes[count];
for(long int i=2,index=1;i<LIMIT;i++)
{
if(arr[i]==1)
primes[index++]=i;
}
for(long int i=1000;i<9999;i++)
{
printf("\nCurrent num : %ld\n",i);
if(Bsearch(primes,1,count-1,i))
{
printf("Hello1!");
if(Bsearch(primes,1,count-1,i+3330))
{
printf("\nHello2!");
if(Bsearch(primes,1,count-1,i+3330+3330))
{
printf("\nHello3!");
if(checkPermu(primes,i,i+3330,i+3330+3330))
{
printf("\nFinal Hello!");
printf("required sequence : %ld%ld%ld",i,i+3330,i+3330+3330);
exit(0);
}
}
}
}
}
return 0;
}

There are many bugs in your code.
In the function Bsearch, you are searching for a value in the array. What if its not present? In your case, 1000 is not a prime number. So, you can't find that in the array. You are coming out of the loop only if the value matches exactly. which won't happen in this case ending up in an infinite loop
In the function, checkPermu, there are two variables declared as i. which means you are shadowing the i that is passed as parameter. To avoid it, give it some other name.
Now, to avoid the first case, you can use an inbuilt function in C++, lower_bound , or else modify the code correspondingly. Here is your edited code.
#include <stdlib.h>
#include <stdio.h>
#define LIMIT 1000000
long int arr[LIMIT];
int Binary_Search(long int a[], int low, int high, long int e)
{
if ( low < 0) return 0;
if (low>=high )
{
if ( e <= a[low] ) return low;
return low+1;
}
int mid=(low+high)/2;
if ( e> a[mid])
return Binary_Search(a,mid+1,high,e);
return Binary_Search(a,low,mid,e);
}
int Bsearch(long int *primes,long int low,long int high,long int search)
{
int idx = Binary_Search(primes, low, high+1,search);
if(primes[idx]==search)
return 1;
return 0;
}
int checkPermu(long int *primes,long int ii,long int j,long int k)
{
long int prod1=1;
long int prod2=1;
long int prod3=1;
for(int i=0;i<3;i++)
{
prod1*=primes[ii%10];prod2*=primes[j%10];prod3*=primes[k%10];
ii/=10;j/=10;k/=10;
}
prod1*=primes[ii];prod2*=primes[j];prod3*=primes[k];
if(prod1==prod2==prod3)
return 1;
else
return 0;
}
int main()
{
for(long int i=1;i<LIMIT;i++)
{
arr[i]=1;
}
for(long int i=2;i<LIMIT;i++)
{
if(arr[i]==1)
{
for(long int j=2;i*j<LIMIT;j++)
{
arr[i*j]=0;
}
}
}
long int index=0;
long int count=0;
//count number of primes
for(long int i=1;i<LIMIT;i++)
{
if(arr[i]==1) count++;
}
long int primes[count];
for(long int i=2,index=1;i<LIMIT;i++)
{
if(arr[i]==1)
primes[index++]=i;
}
//Bsearch(primes,1,count-1,1000);
for(long int i=1000;i<9999;i++)
{
printf("\nCurrent num : %ld\n",i);
if(Bsearch(primes,1,count-1,i))
{
printf("Hello1!\n");
if(Bsearch(primes,1,count-1,i+3330))
{
printf("\nHello2!\n");
if(Bsearch(primes,1,count-1,i+3330+3330))
{
printf("\nHello3!\n");
if(checkPermu(primes,i,i+3330,i+3330+3330))
{
printf("\nFinal Hello!\n");
printf("required sequence : %ld%ld%ld",i,i+3330,i+3330+3330);
exit(0);
}
}
}
}
}
return 0;
}

First, the reason for hang is probably due to this line:
long int primes[count];
count here is 78499 and you are allocating 313996 bytes on the stack. The stack size is probably smaller than this and the stack overflow seems to be causing problem with bash or cmd.exe in my case (blind guess, it's cmd.exe).
Changing that to
long int *primes = malloc(count * sizeof *primes);
resolves the issue.
The actual problem with your code however is that your binary search never terminates. So fixing the previous bug, your code is in an infinite loop, so you don't see any output. I recommend trying to figure out why your binary search doesn't terminate for practice, but in real life, use bsearch from the standard library.

Related

Overflow error in c to find prime factors of a twelve-digit number

I want to solve this problem: https://projecteuler.net/problem=3 by this program, but I'm not sure its true way to use long long int.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
long long int result = factors(6051475143);
printf("%lld", result);
return 0;
}
void factors(int number) {
int factor[100000];
int index = 0, i = 1;
for (; i < number; i++) {
if (number % i == 0) {
factor[index] = i;
index += 1;
}
}
findprime(factor, 100000);
}
int findprime(int prime[], int size) {
int i = 0, j;
long long int latestprime;
for(; i < size; i++) {
if (prime[i] == 0)
break;
int is_prime = 1;
for (j = 2; j < prime[i]; j++) {
if (prime[i] % j == 0 && prime[i] != j) {
is_prime = 0;
break;
}
}
if (is_prime == 1)
latestprime = prime[i];
}
return latestprime;
}
If I try 10-digit number it works but when I try a 12-digit number it returns zero.
To solve this problem, you indeed need a type that is large enough to represent the number. unsigned long long is specified as having at least 64 value bits, which is 18446744073709551615.
Your program has undefined behavior, even for small numbers: result = factors(6051475143) does not reliably store anything useful as factors is defined as a void function and does not even have a return statement. It works by chance because the last statement, findprime(factor, 100000); leaves the return value of findprime in the register where main retrieves what it expects to be the int result of factors(), an return type inferred by the compiler from the lack of prototype.
To find the largest prime factor, you should try factors and reduce the number whenever you find one that divides it evenly.
Here is a modified version:
#include <stdio.h>
unsigned long long largest_factor(unsigned long long number) {
unsigned long long p;
if (number < 2)
return number;
for (p = 2; p * p <= number; p++) {
while (number % p == 0) {
number /= p;
}
}
if (number == 1)
return p;
else
return number;
}
int main(int argc, char *argv[]) {
printf("%llu\n", largest_factor(6051475143));
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main() {
long long int result =factors(6051475143);
printf("%lld",result);
return 0;
}
factors(long long int number)
{
long int factor[1000000];
long long int x;
long int index=0,i=1;
for(;i<800000; i++)
{
if (number%i==0)
{
factor[index] = i;
index+=1;
}
}
x = findprime(factor,index);
return x;
}
int findprime(long int prime[],long int size)
{
long int i = 0,j;
long long int latestprime;
for(;i<size;i++)
{
if (prime[i] == 0)
break;
int is_prime=1;
for(j=2;j<prime[i];j++)
{
if (prime[i]%j==0 && prime[i]!=j)
{
is_prime=0;
break;
}
}
if (is_prime==1)
latestprime = prime[i];
}
return latestprime;
}

Why doesn't my code to find the length of an array work?

I'm trying to find the length of an array but my code doesn't work because "length" is undeclared. How do I declare length? Thanks in advance.
int main(void) {
int array1[10];
int length;
//Should print 10
printf("%d", array_length(array1, length));
return 0;
}
int array_length(int nums[], int length) {
int i = 0;
while (i < length) {
nums[i]++;
}
return i;
}
use this instead your code,you can't know length and determine at same time
int main()
{
int array1[10];
int length;
length=sizeof(array1)/sizeof(int);
return 0;
}
Your program doesn't work as you are not incrementing i variable in the while loop, hence the loop goes on infinitely.
int array_length(int nums[], int length) {
int i = 0;
while (i < length) {
nums[i]++;
i++;
}
return i;
}

how to find out if a number is sum of a number and its polindrom in a short time

I want to write a program to find all numbers less than an specific number that are equal to sum of a number and its polindrome.and this is my code, and it works correctly,but take too long time.what should I do to reduce it's time?
#include<stdio.h>
long long int isprime(long long int b)
{
long long int i,m;
for(i=2;i*i<=b;i++)
{
if(b%i==0)
{
return 0;
}
}
return 1;
}
long long int m(long long int a){
long long int l=0;
while (a>0){
l=l*10+(a%10);
a/=10;
}
return l;
}
int main(){
long long int i = 0,cnt = 0,a= 0,num;
scanf("%lld",&a);
for (i=2;i<=a; i++){
if (isprime(i) == 1){
for (num=1;num<i; num++){
if (num == m(i-num)){
cnt ++;
break;
//printf("%d\n",i);
}
}
}
}
printf("%lld", cnt);
}

Implementation of Radix sort

I have been trying to write the Radix sort algorithm in C.
When I run my code with base 10 it works fine for all inputs, however, with base 16 it sorts only the first 10 elements correctly. In addition, for any other base it is not working.
I would like to make an implementation that generalize for any base.
Here is the code a have so far, could you find any issues?
#include <stdio.h>
#include <stdlib.h>
int size=32;
int getMax(int arr[], int n) {
int mx = arr[0];
int i;
for (i = 1; i < n; i++)
if (arr[i] > mx)
mx = arr[i];
return mx;
}
void countSort(int arr[], int n, int exp, int base) {
int output[n];
int i;
int count[base];
memset(count,0,sizeof count);
for (i=0;i<n;i++)
count[(arr[i]/exp)%base]++;
for (i=1;i<base;i++)
count[i]=count[i]+count[i-1];
for (i=n-1;i>=0;i--) {
output[count[ (arr[i]/exp)%base ]-1]=arr[i];
count[ (arr[i]/exp)%base ]--;
}
for (i=0;i<n;i++)
arr[i]=output[i];
}
void radixsort(int arr[],int n,int base) {
int exp;
int m=getMax(arr,n);
for (exp=1;m/exp>0;exp=exp*10)
countSort(arr,n,exp,base);
}
int main(int argc,char *argv[]) {
int num,i=0,j,n,m;
int *arr,*newarr=NULL;
FILE *fp1;
FILE *fp2;
int base=atoi(argv[1]);
fp1=fopen(argv[2],"r");
if (fp1 == NULL) {
printf("Warning:File does not exists;please enter valid file name");
exit(0);
}
fp2=fopen(argv[3],"w");
if (fp2 == NULL) {
printf("Warning:File does not exists");
exit(0);
}
arr= malloc(sizeof(int)*size);
fprintf(fp2,"before sorting:");
while(fscanf(fp1,"%d",&num)==1) {
if(i<size) {
arr[i]=num;
i++;
fprintf(fp2,"%d ",num);
n=i;
} else {
newarr = malloc(sizeof(int)*2*size);
for(m=0;m<size;m++) {
newarr[m]=arr[m];
}
free(arr);
size=size*2;
arr=&newarr[0];
}
}
radixsort(arr,n,base);
fprintf(fp2,"\nAfter Sorting:");
for (j=0;j<n;j++)
fprintf(fp2,"%d ",arr[j]);
fclose(fp1);
fclose(fp2);
return 0;
}
Looks like for (exp=1;m/exp>0;exp=exp*10)is the problem. I think you need to use base instead of 10.
EDIT: I tried compiling and running this code and was not able to get it to work, even for base 10.

prime numbers in a given range

I have to find all the prime numbers between two numbers m and n. (1 <= m <= n <= 1000000000 and n-m <= 100000). I am using sieve of eratosthenes but getting wrong answer. Can anyone help me what is wrong with my code.
#include<stdio.h>
#include<math.h>
int S[100002];
void sieve(long long int m, long long int n)
{
long long int x=sqrt(n);
long long int i,j;
long long int a;
for(i=0;i<=n-m+2;i++)
S[i]=0;
if(m%2==0)
i=m;
else {
i=m+1;
}
for (;i<=n;i+=2){
S[i-m]=1;
}
for (i=3;i<=x;i+=2){
if(i>=m && S[i-m]) continue;
if(i*i>=m)j=i*i;
else {
a = (m-i*i)%(2*i);
if(a==0)j=m;
else
j=m+ (2*i -a);
}
for (;j<=n;j+=2*i){
S[j-m]=1;
}
}
if (m==1)i=1; else i=0;
for (;i<=n-m;i++)
if (!S[i]){
printf("%lld\n",i+m);
}
}
int main(){
int t;
long long int m,n;
scanf("%d\n",&t);
while(t--){
scanf("%lld %lld",&m,&n);
sieve(m,n);
printf("\n");
}
return(0);
}
if(m%2==0)
i=m;
else {
i=m+1;
}
for (;i<=n;i+=2){
S[i-m]=1;
}
Now, what happens if m <= 2? Will 2 be considered prime or not?
You should use loop in main and call prime function.
For performance, I recommend you to avoid using sqrt function because it requires a lot of CPU clocks.
bool isPrime(int number){
if(number < 2) return false;
if(number == 2) return true;
if(number % 2 == 0) return false;
for(int i=3; (i*i)<=number; i+=2){
if(number % i == 0 ) return false;
}
return true;
}
***Change datatype for the range of number (long, long long, etc).
It is the most efficient(Sieve method) way of finding prime number between a range.
Here 1 is not consider as a prime number as a conventionally way.
#include<stdio.h>
#include<string.h>
#define max 10000000
using namespace std;
int main()
{
unsigned long long int i, j, k, m, n;
unsigned long long int* a = new unsigned long long int[max];
scanf("%ul %ul",&m,&n);
for(i = 1;i<=n;i++)
a[i]=i;
a[1] = 0;
for(i=2;(i*i)<=n;i++)
if(a[i]!=0)
for(k=2*i;k<=n;k=k+i)
if(a[k]!=0)
a[k]=0;
for(i =m;i<=n;i++)
if(a[i]!=0)
printf("%ul ",a[i]);
memset(a, 0, sizeof(a));
return 0;
}
#include<stdio.h>
#include<stdlib.h>
void prime(int );
int main(){
int x, end;
printf("Enter end of the range:\n");
scanf("%d", &end);
for(x = 2;x <= end;x++){
prime(x);
}
return 0;
}
void prime(int x){
int j, count = 1;
for(j=2;j <= x;j++){
if(x % j == 0){
count += 1;
//printf("count = %d,x = %d", count, x);
}
}
if(count == 2){
printf("\n%d\n", x);
}
}

Resources