Next Prime number function problem when I use a recursive function - c

I have a problem with a recursive function. The function must return the next prime number.
As parameter I give a number an it must return the number if is prime, or the next prime number.
The function works fine in almost cases, when I comment the recursion it shows a list of numbers from one to hundred and allocate the primes. The rest return O.
But when I insert the recursive in some cases shows a next prime that is not prime, case of 35 and 95 for example.
when I put 4 it show the next prime that is 7.
but when it reaches 32 it shows 35 that was not correct. It should shows 37.
I don't know were the problem is.
The code is:
#include <stdio.h>
#include <unistd.h>
int ft_find_next_prime(int nb)
{
int i;
int z;
i = nb - 1;
z = nb;
while (i > 1)
{
if ((z % i) == 0)
{
//return (0);
ft_find_next_prime(++z);
}
else
i--;
}
return (z);
}
int main(void)
{
int i;
i = 1;
printf("\n\tNUMERO\t---\tSIGIENTE PRIMO\n");
printf("-----------------------------------------------------\n");
while (i <= 100)
{
printf("\t%i\t---\t%i\n", i, ft_find_next_prime(i));
i++;
}
return (0);
}
Thanks so much in advance.

The only thing missing in the recursive code is the return keyword, or an assignment of the variable z. The reeason is that the z passed into parameter is a copy, not the original z variable.
int ft_find_next_prime(int nb)
{
int i;
int z;
i = nb - 1;
z = nb;
while (i > 1)
{
if ((z % i) == 0)
{
//return (0);
return ft_find_next_prime(++z);
// or : z = ft_find_next_prime(++z);
}
else
i--;
}
return (z);
}

Related

recursive Function, to find even or odd digits inside given number

Basically, its printing only one instance when it happens, and i don't understand why, maybe has something to do with the code reseting every time and starting the variable at 0 again, and i got another question if someone can help me with, i have to return both values when its odd and even, like how many digits are even and odd at the same time, i'm having a little trouble figuring out how to do it
#include <stdio.h>
int digits(int n)
// function that checks if the given value is odd or even, and then add
// + 1 if it's even, or odd, it's supposed to return the value of the quantity
// of digits of the number given by the main function
{
int r;
int odd = 0;
int even = 0;
r = n % 10;
if (r % 2 == 0) // check if given number is even
{
even = even + 1;
}
if (r % 2 != 0) // check if its odd
{
odd = odd + 1;
}
if (n != 0) {
digits(n / 10); // supposed to reset function if n!=0 dividing
// it by 10
}
if (n == 0) { return odd; }
}
int
main() // main function that sends a number to the recursive function
{
int n;
printf("type number in:\n ");
scanf("%d", &n);
printf("%d\n", digits(n));
}
odd and even variables are local in your code, so they are initialized by zero every time.
I think they should be declared at caller of the recursive function, or be declared as global variables.
#include <stdio.h>
void digits(int n, int *even, int *odd)//function
{
int r;
r = n % 10;
if (r % 2 == 0)//check if given number is even
{
*even = *even + 1;
}
else //otherwise, its odd
{
*odd = *odd + 1;
}
n /= 10;
if (n != 0)
{
digits(n, even, odd);//supposed to reset function if n!=0 dividing it by 10
}
}
int main()
{
int n, even = 0, odd = 0;
printf("type number in:\n ");
scanf("%d", &n);
digits(n, &even, &odd);
printf("even: %d\n", even);
printf("odd: %d\n", odd);
return 0;
}
Maybe I found the problem you are facing. You you initialized you odd and even variable as zero. every time you call the function it redeclares their value to zero again. You can use pointer caller or use those as your global variable so that every time they don't repeat their initial values again.
Implementing a function that counts the number of odd and even digits in a number, is not to be done using recursive. That is simply a wrong design choice.
But I assume that it's part of your assignment to use recursion so ... okay.
You want a function that can return two values. Well, in C you can't!! C only allows one return value. So you need another approach. The typical solution is to pass pointers to variables where the result is to be stored.
Here is the code:
void count_odd_even(const int n, int *even, int *odd)
{
if (n == 0) return;
if (((n % 10) % 2) == 1)
{
*odd += 1;
}
else
{
*even += 1;
}
count_odd_even(n/10, even, odd);
}
And call it like
int odd = 0;
int even = 0;
count_odd_even(1234567, &even, &odd);

using recursion to calculate total digits

I wrote this code that counts how many 1's there are in an integer using recursion. N has to be less than 9 digits. I can't seem to find what's wrong with my code and why it won't work. If anyone can give me a hint of where I went wrong I'd appreciate it.
#include <stdio.h>
#include <assert.h>
int count_ones(int n);
int main()
{
assert(count_ones(1001)==2);
}
int count_ones(int n)
{
int sum = 0;
int x;
if(n == 0)
{
return sum;
}
else if(n > 999999999)
{
return sum;
}
else if(n <= 999999999)
{
x == n%10;
if (x == 1)
{
sum = sum + 1;
count_ones(n/10);
}
else
{
count_ones(n/10);
}
}
return sum;
}
You're not combining the current sum with the result from the recursive call. So you're just counting the last digit, all the other counts are being discarded.
int count_ones(int n) {
if (n == 0 || n > 999999999) {
return 0;
} else if (n % 10 == 1) {
return 1 + count_ones(n / 10);
} else {
return count_ones(n / 10);
}
}
#Barmar's answer is giving you the idea of how to fix your approach. Here is an alternative one, which make the advantage of tail recursion which can be unrolled into a loop by the compiler. This approach is using accumulator (acc) to count the ones, and will only return it once.
int count_ones_rec(int n, int acc)
{
if (n == 0)
return acc;
return count_ones_rec(n / 10, acc + (n % 10 == 1));
}
This can be wrapped in a function like:
int count_ones(int n)
{
/* additional checks on `n` if needed */
return count_ones_rec(n, 0);
}
Way too complicated.
Here's how to do it right:
int count_ones(int n)
{
return n? (n%10 == 1) + count_ones(n/10) : 0;
}
For completeness, here's an iterative (non-recursive) solution.
int count_ones(int n)
{
int total=0;
for(;n; n/=10, total += (n%10==1));
return total;
}
For starters there is a typo
x == n%10;
You mean assignment instead of the comparison
x = n%10;
In these calls of the function
if (x == 1)
{
sum = sum + 1;
count_ones(n/10);
}
else
{
count_ones(n/10);
}
you are not using the returned values of the recursive calls
count_ones(n/10);
Moreover as the function parameter has the signed type int then the user can pass to the function a negative number. In this case the function will return a wrong result.
Pay attention to that such restriction
else if(n > 999999999)
does not make a sense. The user can enter any number of the acceptable range of values for objects of the type int.
The function can look the following way as it is shown in the demonstrative program below.
#include <stdio.h>
size_t count_ones( int n )
{
const int Base = 10;
return n == 0 ? 0 : ( n % Base == ( n < 0 ? -1 : 1 ) ) + count_ones( n / Base );
}
int main(void)
{
printf( "%zu\n", count_ones( -11 ) );
printf( "%zu\n", count_ones( 11 ) );
return 0;
}
The program output is
2
2

Need to generate 4 random numbers without repetition in C programming. 1 to 4

I want to generate numbers 1 to 4 in a random fashion using C programming.
I have made provision to print a[0] directly in a while loop and for any further element the program checks whether the new number from a[1] to a[3] is same as any of the previous elements. A function has been created for the same. int checkarray(int *x, int y).
The function checks current element with previous elements one by one by reducing the passed address. If it matches the value it exits the loop by assigning value zero to the condition variable (int apply).
return apply;
In the main program it matches with the int check if check==1, the number is printed or else the loop is repeated.
Problem faced: The number of random numbers generated is varying between 2 and 4.
e.g
2 4
2 4 3
1 3 3 4
etc
Also repetition is there sometimes.
#include <stdio.h>
#include <conio.h>
int checkarray(int *x, int y);
void main() {
int a[4], i = 0, check;
srand(time(0));
while (i < 4) {
a[i] = rand() % 4 + 1;
if (i == 0) {
printf("%d ", a[i]);
i++;
continue;
} else {
check = checkarray(&a[i], i);
}
if (check == 1) {
printf("\n%d ", a[i]);
} else {
continue;
}
i++;
}
getch();
}
int checkarray(int *x, int y) {
int arrcnt = y, apply = 1, r = 1;
while (arrcnt > 0) {
if (*x == *(x - 2 * r)) {
apply = 0;
exit(0);
} else {
arrcnt--;
r++;
continue;
}
}
return apply;
}
Let's look at the checkarray function, which is supposed to check if a number is already present in the array.
It is called this way:
check = checkarray(&a[i], i);
Where a is an array of 4 integers and i is the actual index, so it tries to scan the array backwards looking for any occurrences of a[i]
int checkarray(int *x,int y)
{
int arrcnt=y,apply=1,r=1;
while(arrcnt>0)
{
if(*x==*(x-2*r))
// ^^^ Why? This will cause an out of bounds access.
{
apply = 0;
exit(0); // <-- This ends the program. It should be a 'break;'
}
else
{
arrcnt--;
r++;
continue;
}
}
return apply;
}
Without changing the interface (which is error prone, in my opinion) it could be rewritten as
int check_array(int *x, int y)
{
while ( y )
{
if ( *x == *(x - y) )
return 0;
--y;
}
return 1;
}
Testable here.
There are many other issues which should be addressed, though, so please, take a look to these Q&A too.
Does "n * (rand() / RAND_MAX)" make a skewed random number distribution?
Why do people say there is modulo bias when using a random number generator?
Fisher Yates shuffling algorithm in C
int main() vs void main() in C
Why can't I find <conio.h> on Linux?
Your approach is tedious but can be made to work:
there is no need to special case the first number, just make checkarray() return not found for an empty array.
you should pass different arguments to checkarray(): a pointer to the array, the number of entries to check and the value to search.
you should not use exit(0) to return 0 from checkarray(): it causes the program to terminate immediately.
Here is a modified version:
#include <stdio.h>
#include <conio.h>
int checkarray(int *array, int len, int value) {
int i;
for (i = 0; i < len; i++) {
if (array[i] == value)
return 0;
}
return 1;
}
int main() {
int a[4], i = 0, value;
srand(time(0));
while (i < 4) {
value = rand() % 4 + 1;
if (checkarray(a, i, value)) {
printf("%d ", value);
a[i++] = value;
}
}
printf("\n");
getch();
return 0;
}

Finding the n-th prime number that is palindrome in base K

I recently asked a question about finding whether a number is palindrome in base K or not and I get my answer.
My Recent Question
Now I have a more complicated question, We will get two numbers n and k, and we must find the n-th prime number that is palindrome in base K.
For example if we get 8 and 10, we have 2 3 5 7 11 101 131 151 which are palindrome and prime and so the answer is 151. Another example is 4 2 we have 3 5 7 17 respectively 11 101 111 10001 in base 2 which are prime and palindrome in base so the answer is 17.
n and k are given such that the answer is at most, 1E7.
I submit my program in a judge system and It gave wrong answer in some cases and also Time Limit error in one case. I don't know which part of my algorithm is wrong and what part of it is not optimised.
Note that I am not allowed to use array,vector and strings and also I cannot use libraries more than stdio.h and math.h. It is my program, Can anyone find any problems in it: (I defined intPow because the pow function in math, gives a float and sometime it causes problems)
#include <stdio.h>
#include <math.h>
int primeCheck ( int n);
int palindrome ( int n,int base);
int digitCountBase (int n , int base);
int intPow (int a , int b);
int main()
{
int n;
int base;
scanf("%d %d",&n,&base);
int counter = 0;
int i =2;
int firstRound =1;
while (counter!=n)
{
if (primeCheck(i))
{
if (palindrome (i,base))
{
counter++;
}
}
if (counter ==n)
{
break;
}
if (firstRound)
{
i++;
firstRound=0;
}
else{i+=2;}
}
printf("%d",i);
return 0;
}
int primeCheck ( int n)
{
if (n<2)
{
return 0;
}
if (n==4)
{
return 0;
}
else if (n<=5)
{
return 1;
}
if (n%2 ==0 || n%3 ==0 || n% 5 ==0)
{
return 0;
}
int i =5;
int limit = sqrt(n)+2;
for (int i =5;i<=limit;i+=6)
{
if (n%i==0||n%(i+2)==0)
{
return 0;
}
}
return 1;
}
int palindrome ( int n,int base)
{
int isTrue = 1;
int digitCount = digitCountBase(n,base);
int power = intPow(base,digitCount-1);
while (n>0&& digitCount >0)
{
if (n%base != (n/power)&&digitCount!=1)
{
isTrue =0;
return 0;
}
n = n- power;
n=n/base;
power = power /base;
power = power /base;
digitCount=digitCount-2;
}
return isTrue;
}
int digitCountBase (int n , int base)
{
int digits=0;
while (n)
{
digits++;
n = n / base;
}
return digits;
}
int intPow (int a , int b)
{
int result = 1;
for (int i=1;i<=b;i++)
{
result = result * a;
}
return result;
}
Solution: change palindrome to
int palindrome ( int n,int base)
{
int isTrue = 1;
int digitCount = digitCountBase(n,base);
int power = intPow(base,digitCount-1);
int original = n;
while (n>0&& digitCount >0)
{
if (n%base != (original/power) % base &&digitCount!=1)
{
isTrue =0;
return 0;
}
n=n/base;
power = power /base;
digitCount=digitCount-2;
}
return isTrue;
}
How did I find the error:
You are doing only 2 things, primality testing and palindrome testing, so makes sense to check if these are working fine.
Primality testing is easy, count primes from 1 to 10^7 and compare to known values on google. In this case, this works
To test palindrome, pick a working solution from the internet (even if you canĀ“t submit their solution that uses arrays/strings, you can test with them!). Then iterate from 1 to 10^7 in a certain base and check that both functions return the same.
Testing with base 3, quickly saw that 56 was not giving same output. And the incorrect one was yours.
Then its a matter of fixing your function, which you now know which one is the problem and even have an example of where its not working

time limit exceeded error in a simple function C

I'm making a function that reverses numbers less than 100000000. For example, if the input is 1234 then it should return 4321. But I am getting time limit exceeded TLE, I have made break points of my for loops but don't know why. Can you tell me what's wrong with this code?
int reverse(int n){
int i, j=1, d[100000000]={0}, rev=0;
for(i=10; ;i*10){
if(n%i==n){
d[j]=(n%i)/(i/10);
break;
}
d[j++]=(n%i)/(i/10);
}
for(j=1; ;j++){
rev+=(d[j]*(i/10));
i/=10;
if(i==10)
break;
}
return rev;
}
int main(){
printf("%d",reverse(321));
return 0;
}
Use basic knowledge of how numbers work: place value. If you use the % operator to extract the least significant digit from the number, you can build up the reversed number. Try this:
int reverse(int n)
{
int result = 0;
while ( n > 0 )
{
result = result * 10 + (n % 10);
n /= 10;
}
return result;
}

Resources