I am currently working on a project for college, first year computing class. With that being said, I am not asking for the answer, but I am asking more for some advice. In order to begin the project, I have decided to create a function called collatzSequencer that takes one argument type int.
Here is my function prototype:
int collatzSequencer(int);
Here is my function definition:
int collatzSequencer(int n) {
int stepCounter = 0;
if (n % 2 == 0) {
stepCounter += 1;
collatzSequencer(n / 2);
}
else if (n % 2 == 1) {
stepCounter += 1;
collatzSequencer((3 * n) + 1);
}
else if (n == 1) {
printf("%d\n", n);
printf("%d\n", stepCounter);
return 0;
Here is where I call the function within my main function:
int main(int argc, char* argv[]) {
int num = 5;
collatzSequencer(num);
return 0;
}
When I run my program, nothing happens and I exit with code 0. I have tried debugging my program, and I see that for some reason my IDE doesn't even run the collatzSequencer function when it is called. Although I am a beginner, I feel like I have enough knowledge to be able to find problems within only 48 lines of code, however I cannot find the issue here. Anyone have any ideas?
You are checking for three cases:
n % 2 == 0 (eg. n is Even)
n % 2 == 1 (eg. n is Odd)
n == 1 (eg. n is exactly ONE; this is also the only if-statement with a return)
Except: value 1 is an ODD number, which is captured by the second case.
Your code will never reach the n==1 case, because when n is 1, it will always get captured by the Odd-value if-statement first.
The function has undefined behavior because it does not return anything when n % 2 is equal 0 or 1 and the last else-if statement is not reached by the function control.
Moreover the variable stepCounter can have the maximum value of 1 because it is a local variable of the function that in each recursive call of the function is initialized by zero.
int stepCounter = 0;
The function can be defined the following way as it is shown in the demonstrative program
#include <stdio.h>
size_t collatzSequencer( unsigned int n )
{
return n < 2 ? 0 : 1 + collatzSequencer( n % 2 == 0 ? n / 2 : 3 * n + 1 );
}
int main(void)
{
printf( "%zu\n", collatzSequencer( 27 ) );
return 0;
}
Its output is
111
as it is written in https://en.wikipedia.org/wiki/Collatz_conjecture
Related
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);
I think the problem is with the for-loop but I cannot understand it. This is an assignment in school that I only should use for-loops and if statements to solve!
#include <stdio.h>
int is_prime(int n){
for (int i=2;i<n;i++){
if (n%i!=0){
return 1;
}
else{
return 0;
};
};
}
int main(void){
printf("%d\n", is_prime(11)); // 11 is a prime. Should print 1.
printf("%d\n", is_prime(383)); // 383 is a prime. Should print 1.
printf("%d\n", is_prime(987)); // 987 is not a prime. Should print 0.
}
For starters the null statement after the if statement and the for loop itself
for (int i=2;i<n;i++){
if (n%i!=0){
return 1;
}
else{
return 0;
};
^^^
};
^^^
is redundant.
Due to the if statement the for loop is interrupted as soon as either n % i is not equal to 0 or is equal to 0. So in general the behavior of the function does not depend on whether the passed number is prime or not prime.
If you will move the return statement
return 1;
outside the loop as others advised nevertheless the function will be still incorrect. It will show that 0 and 1 are prime numbers while they are not.
Also the condition of the loop makes the loop inefficient at least because it is clear before entering the loop that any even number except 2 is not a prime number.
Pay attention to that the function parameter should have unsigned integer type.
The function can be defined the following way
#include <stdio.h>
int is_prime( unsigned long long int n )
{
int prime = n % 2 == 0 ? n == 2 : n != 1;
for ( unsigned long long int i = 3; prime && i <= n / i; i += 2 )
{
prime = n % i != 0;
}
return prime;
}
int main(void)
{
printf( "%d\n", is_prime( 11 ) );
printf( "%d\n", is_prime( 383 ) );
printf( "%d\n", is_prime( 987 ) );
return 0;
}
The program output is
1
1
0
The problem is return 1 inside the loop. When you find one i that is not a factor of n, you assume n to be prime. But you have to ensure that all i are not a factor of prime, so the return 1 must be placed after the loop. However, that would cause numbers < 2 to be considered prime, as they do not enter the loop at all. Therefore, you also have to add an additional if at the beginning.
By the way: Every divisor of n (expect n itself) must be <= sqrt(n), therefore you can speed up your function quite a bit.
#include <math.h>
int is_prime(int n) {
if (n < 2)
return 0;
int max_divisor = sqrt(n);
for (int i = 2; i <= max_divisor; i++) {
if (n % i == 0)
return 0;
}
return 1;
}
Problem: return statement
return 1;
}
else{
return 0;
It causes the loop to exit then and there. In your case too, it exits as soon as the first '1' is achieved.
Solution: Instead you should try to store the values in a variable and compare with '1' or '0' at the end of loop
I'm trying to write the function void fib(int arr[], int n), which would fill the array with Fibonacci numbers until index n.
I've tried to find base cases, and chose these:
void fib(int arr[], int num){
int arrLength = num + 1;
if(num<0){
return;
}else if(num == 0){
arr[num] = 1;
}else if(num == 1){
arr[num-1] = 1;
arr[num] = 1;
}
}
But, as you can see, I did not find recursive method itself.
Here's sample output, for example, for call fib(arr, 5):
0 1 2 3 4 5
1 1 2 3 5 8
My main function for testing case:
int main(){
int n = 10, i;
int arr[n+1];
fib(arr, n);
for(i=0;i<=10;i++){
printf("%i ", arr[i]);
}
return 0;
}
Is there any other way to make base cases more "elegant"? Also, I would truly appreciate hints using which I could fill the array with numbers starting from 2 with recursive option.
You question is asking for recursion but the program you write is just using function, because of this reason I am writing very basic code for your better understanding, you can improve this after understanding the flow and functionality or ask new question with some work.
Below one is a working code tested on TurboC, I am sharing complete test code.
#include <stdio.h>
#include<conio.h>
#define MAX 100
void fib(int *arr, int num, int a, int b, int term){
if(term == 0 && term <= num){
arr[term] = 1;
term++;
fib(arr,num,a,b,term);
}else if(term ==1 && term <= num){
arr[term] = 1;
term++;
fib(arr,num,a,b,term);
}else if(term <= num){
arr[term] = a+b;
term++;
fib(arr,num,b,a+b,term);
}
}
void main()
{
int firstTerm = 1;//First term of fibbo series
int secondTerm = 1;//Second term of fibbo series
int tracker = 0; // Tracker to track how much term we printed
int i;//To run loop here to check array after recursive function
int ar[MAX],n=5;// n is number of term we want to print
clrscr();
fib(ar,n,firstTerm,secondTerm,tracker);//recursive function call
// below is printing array to check
for(i=0;i<=n;i++){
printf("%d\t",ar[i]);
}
getch();
}
One thing I have to suggest is, if n is 5 then you just get 1 1 2 3 5, In code I did according to your requirement, so here it will print 1 1 2 3 5 8
I'd state that the "elegant" solution should be a simple loop, without any recursion, but let's see how it could be done in the less efficient and more error prone way.
// I'll assume that the function signature can't be changed
void fib(int arr[], int num)
{
// In the general case, use the well known recurrence relation.
if ( num > 1 )
{
// Use recursion here to calculate the previous elements of the array.
fib(arr, /* ... */);
// ^^^^^^^^^ Can you figure out what index should be passed here?
// Then, calculate the element at index num using the recurrence relation.
arr[num] = arr[num - 1] + arr[num - 2];
// ^^^^^^^ ^^^^^^^ Note the indices.
// Are those values alredy known?
}
// When num is 0 or 1, we can't use the general formula. Can you tell why?
else if ( num >= 0 )
{
fib(arr, /* ... */);
// ^^^^^^^^^ Same as before.
arr[num] = 1;
}
// If num is less than 0, it just do nothing.
}
I was asked to calculate the following nested root expression using recursion only.
I wrote the code below that works, but they allowed us to use only one function and 1 input n for the purpose and not 2 like I used.
Can someone help me transform this code into one function that will calculate the expression? cant use any library except functions from <math.h>.
output for n=10: 1.757932
double rec_sqrt_series(int n, int m) {
if (n <= 0)
return 0;
if (m > n)
return 0;
return sqrt(m + rec_sqrt_series(n, m + 1));
}
double helper(int n) {
return rec_sqrt_series(n, 1);
}
Use the upper bits of n as a counter:
double rec_sqrt_series(int n)
{
static const int R = 0x10000;
return n/R < n%R ? sqrt(n/R+1 + rec_sqrt_series(n+R)) : 0;
}
Naturally, that malfunctions when the initial n is R or greater. Here is a more complicated version that works for any positive value of n. It works:
When n is negative, it works like the above version, using the upper bits to count.
When n is positive, if it is less than R, it calls itself with -n to evaluate the function as above. Otherwise, it calls itself with R-1 negated. This evaluates the function as if it were called with R-1. This produces the correct result because the series stops changing in the floating-point format after just a few dozen iterations—the square roots of the deeper numbers get so diluted they have no effect. So the function has the same value for all n over a small threshold.
double rec_sqrt_series(int n)
{
static const int R = 0x100;
return
0 < n ? n < R ? rec_sqrt_series(-n) : rec_sqrt_series(1-R)
: n/R > n%R ? sqrt(-n/R+1 + rec_sqrt_series(n-R)) : 0;
}
Without mathematically transforming the formula (I don't know if it is possible), you can't truly use just one parameter, as for each element you need two informations: the current step and the original n. However you can cheat. One way is to encode the two numbers in the int parameter (as shown by Eric).
Another way is to store the original n in a static local variable. At the first call we save n in this static variable, we start the recursion and at the last step we reset it to the sentinel value:
// fn(i) = sqrt(n + 1 - i + fn(i - 1))
// fn(1) = sqrt(n)
//
// note: has global state
double f(int i)
{
static const int sentinel = -1;
static int n = sentinel;
// outside call
if (n == sentinel)
{
n = i;
return f(n);
}
// last step
if (i == 1)
{
double r = sqrt(n);
n = sentinel;
return r;
}
return sqrt(n + 1 - i + f(i - 1));
}
Apparently static int n = sentinel is not standard C because sentinel is not a compile time constant in C (it is weird because both gcc and clang don't complain, even with -pedantic)
You can do this instead:
enum Special { Sentinel = -1 };
static int n = Sentinel;
This problem begs for contorted solutions.
Here is one that uses a single function taking one or two int arguments:
if the first argument is positive, it computes the expression for that value
if the first argument is negative, it must be followed by a second argument and performs a single step in the computation, recursing for the previous step.
it uses <stdarg.h> which might or might not be allowed.
Here is the code:
#include <math.h>
#include <stdarg.h>
double rec_sqrt_series(int n, ...) {
if (n < 0) {
va_arg ap;
va_start(ap, n);
int m = va_arg(ap, int);
va_end(ap);
if (m > -n) {
return 0.0;
} else {
return sqrt(m + rec_sqrt_series(n, m + 1));
}
} else {
return rec_sqrt_series(-n, 1);
}
}
Here is another solution with a single function, using only <math.h>, but abusing the rules in a different way: using a macro.
#include <math.h>
#define rec_sqrt_series(n) (rec_sqrt_series)(n, 1)
double (rec_sqrt_series)(int n, int m) {
if (m > n) {
return 0.0;
} else {
return sqrt(m + (rec_sqrt_series)(n, m + 1));
}
}
Yet another one, strictly speaking recursive, but with single recursion level and no other tricks. As Eric commented, it uses a for loop which might be invalid under the OP's constraints:
double rec_sqrt_series(int n) {
if (n > 0) {
return rec_sqrt_series(-n);
} else {
double x = 0.0;
for (int i = -n; i > 0; i--) {
x = sqrt(i + x);
}
return x;
}
}
Here is another approach.
It relies on int being 32 bits. The idea is to use the upper 32 bit of a 64 bit int to
1) See if the call was a recursive call (or a call from the "outside")
2) Save the target value in the upper 32 bits during recursion
// Calling convention:
// when calling this function 'n' must be a positive 32 bit integer value
// If 'n' is zero or less than zero the function have undefined behavior
double rec_sqrt_series(uint64_t n)
{
if ((n >> 32) == 0)
{
// Not called by a recursive call
// so start the recursion
return rec_sqrt_series((n << 32) + 1);
}
// Called by a recursive call
uint64_t rn = n & 0xffffffffU;
if (rn == (n >> 32)) return sqrt(rn); // Done - target reached
return sqrt (rn + rec_sqrt_series(n+1)); // Do the recursive call
}
I'm reading a file with a set format so I'm sort of aware of what to expect from the file, however, when I try to print all the input, just to make sure that the code works, the console crashes with a timeout exception. I've got a nested for loop, since I find it the easiest way to handle the file format. But I don't know if there's a better way to handle this.
The problem is a geeks for geeks coding challenge. I noticed that when I change the for variable use in the for loop the code compiles, but this way I wouldn't be able to handle different file formats. As long as I have a constant in the for loop as my parameter it runs. Any idea as to why that is?
the first line is the number of cases, every first line after that tells me the number of node and the number of links, and the following line has linking nodes.
The expected output would be 4 and 3 but I haven't made it that far yet, I'm still making sure that I'm able to read in file properly.
#include <stdio.h>
#include <ctype.h>
int nextInt();
int main() {
int c = getchar() - '0';
printf("%d\n", c);
while(c > 0){
int x, y;
x = nextInt();
y = nextInt();
printf("%d%4d\n", x, y);
int i, a, b;
for(i = 0;i<2*y; i++){
a = nextInt();
printf("%4d", a);
}
printf("\n");
c--;
}
return 0;
}
int nextInt(){
int c, n;
int num;
while(isspace(c=getchar())){;}
num = c - '0';
while(!isspace(n = getchar())){
num = (num * 10) + (n - '0');
}
return num;
}
An example for the input looks something like this:
2
4 4
0 2 0 3 1 3 2 3
4 3
0 2 0 1 0 3
output
4
3
The while loop in nextInt() doesn't stop when it reads EOF. If the last line doesn't end with a newline, you'll go into an infinite loop, because it will never find the delimiter after the last number.
int nextInt(){
int c, n;
int num;
while(isspace(c=getchar())){;}
num = c - '0';
while(!isspace(n = getchar()) && n != EOF){
num = (num * 10) + (n - '0');
}
return num;
}