C program recursive function - c

I have a small problem I want to build a function that returns with recursive function the nn expression with one parameter in the calling function. Can someone help me? My thought so far :
int powerThroughRecursion(int n) {
if (n == 0) {
return 1;
}
if (n <= 1) {
return n;
}
return n * powerThroughRecursion(n - 1);
}

Yes, you are actually computing n! there. One way to do it is the following:
#include <iostream>
#include <string>
int powerThroughRecusion(int n, int step) {
if (step < 1)
return 1;
return n * powerThroughRecusion(n, step - 1);
}
int main()
{
std::cout << powerThroughRecusion(4, 4);
}
You multiply by n, but a step will tell you how much multiplications to be done.
[edit] using a single parameter function
#include <iostream>
#include <string>
int powerThroughRecusionInternal(int n, int step) {
if (step < 1)
return 1;
return n * powerThroughRecusionInternal(n, step - 1);
}
int powerThroughRecusion(int n)
{
return powerThroughRecusionInternal(n, n);
}
int main()
{
std::cout << powerThroughRecusion(2) << "\n";
std::cout << powerThroughRecusion(4);
}

If you want a one parameter function. just hide and wrap the two parameter implementation version with another function call.
static int powerThroughRecusionImpl(int n, int power) {
if (power == 0) {
return 1;
}
if (power == 1) {
return n;
}
return n * powerThroughRecusionImpl(n ,power - 1);
}
int powerThroughRecusion(int n) {
return powerThroughRecusionImpl(n ,n);
}
Or if you want to be non thread-safe.
int powerThroughRecusion(int n) {
static int base = 0;
if (!base) {
base = n;
n = powerThroughRecusion(n);
base = 0;
return n;
} else {
if (n == 0) {
return 1;
} else if (n == 1) {
return base;
}
return base * powerThroughRecusion(n - 1);
}
}

Related

Having a hard time creating a function that displays all different combinations of n numbers (0<n<10)by ascending order

I'm having difficulty finding the underlying logic for this. I know recursion would help however I don't know how to approach it. My difficulty lies when get dealing with sending/ printing the array on the base case. Everything I do I can only iterate the last digit and don't know how to go about the others.
If n is 2:
$>./a.out | cat -e
01, 02, 03, ..., 09, 12, ..., 79, 89$
If n is 3 things get harder:
012, 013, 014, ..., 123, 124, ..., 134, 135,... 234, ..., 789$
My code is far from working
#include <unistd.h>
#include <stdlib.h>
#include <stdbool.h>
void ft_putchar(char c)
{
write(1, &c, 1);
}
bool is_consecutive(int arr[], int n)
{
int last_value = 9;
if ( n <= 0 )
return false;
while ( --n ) {
if ( arr[n] != last_value-- )
return false;
}
return true;
}
void ft_print_screen(int *t, int size)
{
int i;
i = 0;
while (i < size)
{
ft_putchar(t[i] + '0');
i++;
}
if (is_consecutive(t, size) != true)
{
ft_putchar(',');
ft_putchar(' ');
}
}
void ft_print_combn(int n)
{
int i;
int tab[n];
i = 0;
if (n == 1)
while (i < 10)
{
ft_putchar(i + '0');
i++;
}
while (i < n)
{
tab[i] = 0;
i++;
}
while (tab[0] <= (10 - n) && n > 1)
{
ft_print_screen(tab, n);
tab[n - 1]++;
i = n;
while (i && n > 1)
{
i--;
if (tab[i] > 9)
{
tab[i - 1]++;
tab[i] = 0;
}
}
}
}
void main(int argc, char *argv[])
{
int x = atoi(argv[1]);
ft_print_combn(x);
}
Here's a solution that you should be able to adapt to your needs. The code is conditionalized to use either stdio or bare write calls. Just change the definition of USE_STDIO to #define USE_STDIO 0 to make it use bare write calls (or simply remove the conditionlization).
Note that I used int rather than size_t for the string lengths, since they will never be larger than the character set size (i.e. 10), but you could of course use size_t if you prefer.
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#define USE_STDIO 1
void my_write(int len, char buf[len])
{
#if USE_STDIO
printf("%.*s", len, buf);
#else
write(1, buf, len);
#endif
}
void my_write_s(char *buf)
{
my_write(strlen(buf), buf);
}
void show(bool first, int len, char buf[len])
{
if (! first) {
my_write_s(", ");
}
my_write(len, buf);
}
void end(void)
{
my_write_s("$\n");
}
void gen_combs2(bool first, char *buf, int off, int m, char chars[m], int n)
{
if (n == 0) {
show(first, off, buf);
return;
}
for (int i = 0; i < m + 1 - n ; i++) {
buf[off] = chars[i];
gen_combs2(first, buf, off + 1, m - i - 1, chars + i + 1, n - 1);
first = false;
}
}
void gen_combs(char *chars, int n)
{
int m = strlen(chars);
char buf[n];
gen_combs2(true, buf, 0, m, chars, n);
end();
}
int main(void)
{
gen_combs("0123456789", 1);
gen_combs("0123456789", 2);
gen_combs("0123456789", 3);
return 0;
}

Optimizing the following recursive function

trying to solve an assignment question...
info I have is:
foo(0)=0
foo(1)=1
foo(2)=2
the below code works upto approximately 30 numbers...but it needs to work fluently until 100, so I need to optimize it. I tried to create an equation which links every successive number but it did not work. Any ideas how to optimize it?
#include <stdio.h>
#include<stdlib.h>
long foo(int n) {
long a;
if (n==0)
{
return 0;
}
else if(n==1)
{
return 1;
}
else if(n==2)
{
return 2;
}
else
{
return foo(n-1)-2*foo(n-2)+foo(n-3)-2;
}
}
int main(void) {
long b=foo(7);
printf("%ld",b);
}
For such a simple problem, you can make the function iterative.
#include <stdint.h>
uint64_t foo (int n)
{
if (n == 0)
return 0;
else if (n == 1)
return 1;
else if (n == 2)
return 2;
else
{
uint64_t a = 0, b = 1, c = 2;
uint64_t ret;
for (int i = 2; i<n; i++)
{
ret = a + 2*b + c - 2;
a = b;
b = c;
c = ret;
}
return (ret);
}
}
If you have to use recursion, you can significantly improve runtime with memoisation. In this case, you need an extra array to store the results of already calculated values.
uint64_t memo[101]; // size this array to the maximum value of n needed to be calculated.
uint64_t foo(int n) {
uint64_t a;
if (n==0)
{
return 0;
}
else if(n==1)
{
return 1;
}
else if(n==2)
{
return 2;
}
else
{
if (memo[n] == 0)
{
a = foo(n-1)-2*foo(n-2)+foo(n-3)-2;
memo[n] = a;
}
else
{
a = memo[n];
}
return a;
}
}

Way to represent an object in C or dealing with multiple value return

I was wondering if you might be able to help, I'm trying to "convert" some code that was written in javascript to 'C' code, but I'm not sure how to deal with the object :
function updateObj(o, k) {
return {
n: o.n + 1,
way: k + "-" + o.way
}
}
function steps(k) {
if (k == 1) {
return {
n: 2,
way: "1-0<BR>"
};
}
let case1 = updateObj(steps(k - 1),k);
for (i = 2; k % i > 0; i++);
if (k == i) {
return case1;
}
let case2 = updateObj(steps(k / i),k);
if (case1.n < case2.n) return case1
else return case2;
}
document.write(steps(291).way);
How would you transfer it to 'C' ?
Here is my try :
#include <stdio.h>
#include <conio.h>
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
int steps(int num);
int main() {
int res;
res = steps(150);
_getch();
return 0;
}
int steps(k)
{
int i = 0;
if (k == 1) return 1;
for (int i = 2; k%i > 0; i++);
if (k == i) {
return steps(k - 1);
}
return 1 + MIN(steps(k - 1), steps(k / i));
}
Example of a close mapping of javascript to 'C' code.
// Include needed headers.
#include <stdio.h>
#include <stdlib.h>
// Form a struct
typedef struct {
int n;
char *way; // Code will need to manage the strings - oh the joy of C!
} function;
function updateObj(function o, int k) {
// Body left for OP to implement
// Determine concatenation memory needs
// Allocate
// Concatenate
// Free `o` resources
// Form `function`
}
function steps(int k) {
if (k == 1) {
// v---Compound Literal -----------------------v Since C99
return (function) {.n = 2, .way = strdup("1-0<BR>")};
}
function case1 = updateObj(steps(k - 1), k);
int i;
for (i = 2; k % i > 0; i++) {
;
}
if (k == i) {
return case1;
}
function case2 = updateObj(steps(k / i), k);
if (case1.n < case2.n) {
function_free(case2); // need to free resources in case2
return case1;
} else {
function_free(case1); // need to free resources in case1
return case2;
}
}
int main() {
function f = steps(291);
puts(f.way);
function_free(f);
}
structs might be what you are looking for.
They can be used to group some kind of data. In order to declare a structure that contains an integer and a char pointer, use:
struct S {
int i;
char *c;
};
Then you can do something like:
struct S function() {
struct S s;
s.i = 1;
// more code
return s;
}
If your structure is memory intensive you might want to put it on the heap and return a pointer.

Count zeroes with Recursion keep crashing

My code is supposed to count the number of zeroes using recursion.
However my program keeps crashing.
Expected output:
Input: 10500
Result: 3
Code:
void rCountZeros2(int num, int *result) {
if (num > 0) {
if ((num % 10) == 0) {
rCountZeros2((num / 10) + 1, *result);
}
rCountZeros2(num / 10, *result);
} else if (num == 0) {
*result = 1;
}
*result = num;
}
How do I make it work?
Here's the solution with and without using pointers
Hope this helps
#include <stdio.h> // For C++ #include<iostream>
// Without using pointer
int count_zeros_recursive2(int num) {
if (num % 10 == 0) {
if (num > 19 || num < -19) {
return 1 + count_zeros_recursive2(num / 10);
}
return 1;
}
if (num > 19 || num < -19) {
return count_zeros_recursive2(num / 10);
}
return 0;
}
// Using pointer
void count_zeros_recursive(int num, int *result) {
if (num % 10 == 0)
*result = *result + 1;
if (num > 19 || num < -19)
count_zeros_recursive(num / 10, result);
}
int count_zeros(int num) {
int result = 0;
count_zeros_recursive(num, &result);
//result = count_zeros_recursive2(num);
return result;
}
int main() {
int n;
while (1) {
scanf("%d", &n); // For C++ std::cin >> n;
printf("%d\n", count_zeros(n));// For C++ std::cout << n << "\n";
}
return 0;
}
eg Input: 1010
Output: 2
Input: 0
Output: 1
Input: 10204012410
Output: 4
Input: -101
Output: 1
I prefer returning the result instead of passing the pointer to the result.
Stop condition is when the number is a single digit, then if 0 you have 1 zero, otherwise none.
If the number is not a single digit, calculate the number of zeros in the number without the lowest digit (num/10) and add 1 to the returned value if the lowest digit was 0.
#include <stdio.h>
int count_zeros_recursive(int num)
{
int res = 0;
int num_without_lowest_digit = num/10;
if(num_without_lowest_digit == 0)
{
res = (num == 0);
}
else
{
res = count_zeros_recursive(num_without_lowest_digit);
if (num % 10 == 0)
{
res++;
}
}
return res;
}
int main(void) {
int nums[] = { 202, 7, 100, 10500, 10234, 10000};
int i;
for (i=0; i < sizeof(nums)/sizeof(nums[0]); ++i)
{
printf("Number %d has %d zeros\n", nums[i], count_zeros_recursive(nums[i]));
}
return 0;
}
Tested here
Number 202 has 1 zeros
Number 7 has 0 zeros
Number 100 has 2 zeros
Number 10500 has 3 zeros
Number 10234 has 1 zeros
Number 10000 has 4 zeros
Let's say you really want to use a pointer for some reason. Here's a full solution:
#include <stdio.h>
void rCountZeros2(int num, int *result)
{
if(num>0)
{
if( (num % 10) == 0)
{
*result = *result + 1;
}
rCountZeros2(num/10, result);
}
}
int main() {
int i = 0;
int n;
n = scanf("%d", &n);
int *result = &i;
rCountZeros2(n, result);
printf("%d\n", *result);
}
So what will happen is that you're effectively just updating the value at the location which result is pointing to, which means that you're really just storing the count in the variable i.
There is no need to pass a pointer if you can use a functional approach. Just return the value.
long recursiveZeroesCount(long num) {
if(num == 0) return 1;
if(num < 10) return 0;
if(num % 10 == 0) return 1 + recursiveZeroesCount(num / 10);
else return recursiveZeroesCount(num / 10);
}
Your program has undefined behavior because you pass the value of the *result instead of the pointer to the result variable to recursive calls. Furthermore, your algorithm is flawed as you cannot use this API recursively because the recursive calls update the result as well as the current call, a very impractical situation.
Here is a corrected version without recursion:
void rCountZeros2(int num, int *result) {
int count = 0;
for (;;) {
if (num % 10 == 0)
count++;
num /= 10;
if (num == 0)
break;
}
*result = count;
}
And here is a recursive implementation with a simpler API:
int rCountZeros2(int num) {
if (num % 10 == 0) {
if (num == 0)
return 1;
else
return 1 + rCountZeros2(num / 10);
} else {
if (num < 10)
return 0;
else
return rCountZeros2(num / 10);
}
}
The above function can be simplified as a single statement:
int rCountZeros2(int num) {
return !(num % 10) + ((num < 10) ? 0 : rCountZeros2(num / 10));
}

Recursive Caching Based Fibonacci

I am trying to implement caching based Fibonacci sequence. But it gave me the wrong output for example (fibcache(8) gave me an answer of 13 instead of 21. However in some cases it gave me the correct output. For example fibcache(6) gave me 8. Cant figure out whats wrong
#include <stdio.h>
#include <stdlib.h>
#define DCACHE_SIZE 5
int fibcache(int number);
long cacheodd[DCACHE_SIZE] = {0};
long cacheeven[DCACHE_SIZE] = {0};
int i_odd, i_even;
int main(int argc, char *argv[])
{
int fibNum = fibcache(6);
printf("The Fibonacci number is %d\n", fibcache(fibNum));
}
int fibcache(int n)
{
int result;
if (n == 0)
return 0;
if (n == 1)
return 1;
if(n%2==0)
{
if (cacheodd[i_odd] != 0)
result = cacheodd[i_odd];
else
{
cacheodd[i_odd] = fibcache(n-1) + fibcache(n-2);
result = cacheodd[i_odd];
}
}
else
if(n%2==1)
{
if (cacheeven[i_even] != 0)
result = cacheeven[i_even];
else
{
cacheeven[i_even] = fibcache(n-1) + fibcache(n-2);
result = cacheeven[i_even];
}
}
return result;
}
You have some problems:
You actually print fib(fib(6)), a much larger number than fib(6).
Your caching function is too complicated: why handle even and odd numbers differently? You should make a special case of numbers larger than the cache size and verify if the cached value has been computed.
Here is a simpler version:
#include <stdio.h>
#define DCACHE_SIZE 5
long fibcache(int number);
long fibcache_values[DCACHE_SIZE] = { 0 };
int main(void) {
printf("List of Fibonacci numbers:\n");
for (int i = 0; i < 47; i++) {
printf(" fib(%d) = %ld\n", fibcache(i));
}
return 0;
}
long fibcache(int n) {
if (n <= 0)
return 0;
if (n == 1)
return 1;
if (n < DCACHE_SIZE) {
if (fibcache_values[n] != 0)
return fibcache_values[n];
else
return fibcache_values[n] = fibcache(n - 1) + fibcache(n - 2);
} else {
return fibcache(n - 1) + fibcache(n - 2);
}
}

Resources