how to implement this new operation with recursion? - c

I have a homework that include a new operation (a [n] b), given:
a [1] b = ab
a [n] 1 = a
2 [2] 3 = 2 [2-1] (2 [2-1] 2) 2 repeated 3 times = 2 [1] (2 [1] 2) = 222 = 16
2 [2] 2 = 2 [2-1] 2 2 repeated 2 times = 2 [1] 2 = (22) = 4
4 [3] 3 = 4 [3-1] (4 [3-1] 4) = 4 [2] (4 [2] 4) 4 repeated 3 times = 4 [2] (4 [1] (4 [1] ( 4 [1] 4))) =
= 4 [2] 4 444
I don't need a solution, I just need advice so that I can solve it myself.

What is being said here can be rephrased as follows.
For any positive integers a, b and n define
a [n] b = a [n-1] ( a [n-1] ( ... a ) ) taken b times
In a C-like language
int myoperator (a, n, b) {
int x, i;
x = a;
if (n == 1){
x = pow(a,b);
} else {
for(i = 1; i < b; i++){
x = myoperator (a, [n-1], x);
}
return x;
}
Note that the values will grow quickly and get out of the range of machine integers very soon.
Note also that a[n]b can be defined as
a [n] b = a [n-1] ( a [n-1] (b-1) ).
using this definition the for loop above can be eliminated.
int myoperator (a, n, b)
int a,n,b;
{
int x;
x = a;
if (n == 1)
x = pow(a,b);
else if (b == 1)
x = a;
else {
assert(b>1 && n>1);
x = myoperator (a, n-1, myoperator(a,n-1,b-1));
}
return x;
}

Related

C Program to calculate difference of n natural numbers using recursion and recursion is must to use [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I wrote the code but I am getting the wrong output. Say for example when I enter 5 the output I am getting is 3 instead it should be -5. Please point out my mistakes and provide me some solutions.
#include <stdio.h>
int difference(int a);
int difference(int a)
{
if (a != 0)
{
return (a - difference(a - 1));
}
else
{
return 0;
}
}
int main()
{
int n;
printf("Enter number until which you want difference of:\n");
scanf("%d", &n);
printf("The difference of numbers is %d", difference(n));
return 0;
}
I'm not sure what you mean by
difference of numbers
What your program does is calculate the division of the given number by 2 rounded up.
Input
Result
0
0
1
1
2
1
3
2
4
2
5
3
6
3
7
4
8
4
If you wish to substract one number from another you need to get 2 numbers from the user which you wish to substract, and use another function.
After clarification, what you need is to accumulate the subtraction result.
It should look more or less like this:
#include <stdio.h>
int difference(int a);
int difference(int a){
if(a == 0)
return 0;
return -(a-1) + difference(a-1);
}
int main()
{
int n;
printf("Enter number until which you want difference of:\n");
scanf("%d", &n);
printf("The difference of numbers is %d", n + difference(n));
return 0;
}
As this seems home work, just the error cause:
d 5 = [a] 5 - d 4 = [k] 5 - 2 = 3
d 4 = [b] 4 - d 3 = [j] 4 - 2
d 3 = [c] 3 - d 2 = [i] 3 - 1
d 2 = [d] 2 - d 1 = [h] 2 - 1
d 1 = [e] 1 - d 0 = [g] 1 - 0
d 0 = [f] 0
Bad algorithm, bad, bad.
If difference between two numbers is meant:
int difference(int a, int b)
{
if (a == b)
{
return 0;
}
else if (a > b)
{
return 1 + difference(a - 1, b);
}
else //if (a < b)
{
return difference(b, a);
}
}
Even if this is home work, a solution:
int identityByRecursiveDifference(int a)
{
return a == 0 ? 0 : 1 + identityByRecursiveDifference(a - 1);
}
Here the difference is 1.
int identityByRecursiveDifference(int a)
{
if a == 0 {
return 0;
}
int half = identityByRecursiveDifference(a / 2);
return 2 * half + (a % 2);
}
Here the difference is half; exact with even a or about with odd a.
a % 2 is remainder by division of 2.
Less recursion, not a steps but ²log a steps.

goto statement leading to an infinite loop

We were having a quiz of sorts and had the following question where we had to find the error, or if there's none, the output of the given code:
#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n--);
if(n!=0){
n--;
goto b;
}
return 0;
}
I don't see anything wrong with this in theory but this leads to an infinite loop with the variable going way below 0. Could anyone help me with this?
#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n);
if(n!=0){
n--;
goto b;
}
return 0;
}
This would work. The version you posted does not work because it will never get to 0. It is subtracting once in the if statement, and once in the printf.
You should only have one n-- statement. otherwise even if it reaches 0, when it get the first n-- it will be decremented one more time and will become -1. (so it will never match 0).
Hence, please change your code to
#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n--);
if(n!=0){
goto b;
}
return 0;
}
The condition if (n != 0) is always getting satisfied.
On each iteration the number n decreases by 2.
So when n = 2, it gets decremented once after printf("%d\n",n--)
then the condition if (n != 0) is true, as n = 1
Inside the condition block n is decremented once again, n = 0
So the next time before reaching the condition if (n != 0), n equals to -1,
which leads to an infinite loop.
In C 012 is an octal base number, in decimal it is equal to 10.
This code:
#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n--);
if(n!=0){
n--;
goto b;
}
return 0;
}
Does this:
print n (10)
subtract 1 of n (n = 10 - 1 = 9)
check if n != 0 (9 != 0 -> true)
subtract 1 of n (n = 9 - 1 = 8)
jump to b
print n (8)
subtract 1 of n (n = 8 - 1 = 7)
check if n != 0 (7 != 0 -> true)
subtract 1 of n (n = 7 - 1 = 6)
jump to b
print n (6)
subtract 1 of n (n = 6 - 1 = 5)
check if n != 0 (5 != 0 -> true)
subtract 1 of n (n = 5 - 1 = 4)
jump to b
print n (4)
subtract 1 of n (n = 4 - 1 = 3)
check if n != 0 (3 != 0 -> true)
subtract 1 of n (n = 3 - 1 = 2)
jump to b
print n (2)
subtract 1 of n (n = 2 - 1 = 1)
check if n != 0 (1 != 0 -> true)
subtract 1 of n (n = 1 - 1 = 0)
jump to b
print n (0)
subtract 1 of n (n = 0 - 1 = -1)
check if n != 0 (-1 != 0 -> true)
subtract 1 of n (n = -1 - 1 = -2)
jump to b
print n (-2)
...
...
... goes on infinitely
Note that when n will never equal to 0 when the program checks if n != 0, because in this evaluation n is always an odd number since two subtractions by 1 are made every time.
Change from b: printf("%d\n",n--); to b: printf("%d\n",n);.
or
Change from
if(n!=0){
n--;
goto b;
to
if(n!=0){
n;
goto b;
Because n-- equals n = n - 1.
Your program:
#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n--); // n = n - 1
if(n!=0){
n--; // n = n - 1
goto b;
}
return 0;
}
for out put [10, 8, 6, 4,2, 0]
#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n--);
if(n>0){
n--;
goto b;
}
return 0;
}
for [10,9,8,7,6,5,4,3,2,1]
#include <stdio.h>
int main(void) {
int n = 012;
b: printf("%d\n",n--);
if(n>0){
//n--;
goto b;
}
return 0;
}

Need help for find the logic of a heuristic sequence

I'm developing a system that can explore entirely a simple heuristic map of this gender (which can have different numbers of branches, and different depths) :
Simple heuristic map
So, I'm saving the positions explored in an int array of the size of the depth of the map. The goal is to explore all nodes of the map, so to have this output : 0 2 6, 0 2 7, 0 3 8, 0 3 9, 1 4 10 etc.. But actually with my code (which needs to be called several times because it can update just one time the array), i have this : 0 2 6, 0 2 7, 0 3 8, **1** 3 9, 1 4 10 etc..
This is my code, I don't know how to solve this problem..
void get_next_branch(int *s, int nbr_branch, int size)
{
int a;
a = 0;
while (a < size)
{
condition = (size - a)/(nbr_branch - 1);
if (condition)
{
if (s[size - 1] % (condition) + 1 == condition)
s[a]++;
}
a++;
}
}
And this is the main example who call this function.
int main(void)
{
int id[3] = {0, 2, 6};
while (id[2] < 13)
{
printf("%d %d %d\n", id[0], id[1], id[2]);
get_next_branch(id, 2, 3);
}
return (0);
}
I thank you in advance!
You might want to use a closed formula for this problem
b being the number of branches
d the depth you want to find the numbers in (d >= 0)
we get immediately
Number of nodes at depth d = bd+1
(since at depth 0 we have already two nodes, there is no "root" node used).
The number of the first node at depth d is the sum of the number of nodes of the lower levels. Basically,
first node number at depth 0 = 0
first node number at depth d > 0 = b1 + b2 + b3 + ... + bd
This is the sum of a geometric series having a ratio of b. Thanks to the formula (Wolfram)
first node number at depth d = b * (1 - bd) / (1 - b)
E.g. with b == 2 and d == 2 (3rd level)
Number of nodes: 2 ^ 3 = 8
Starting at number: 2 * (1 - 2^2) / (1 - 2) = 6
A program to show the tree at any level can be done from the formulas above.
To print a number of levels of a tree with b branches:
Utility power function
int power(int n, int e) {
if (e < 1) return 1;
int p=n;
while (--e) p *= n;
return p;
}
The two formulas above
int nodes_at_depth(int branches, int depth) {
return power(branches, depth+1);
}
int first_at_depth(int branches, int depth) {
return (branches * (1 - power(branches, depth))) / (1 - branches);
}
Sample main program, to be called
./heuristic nb_of_branches nb_of_levels
that calls the two functions
int main(int argc, char **argv)
{
if (argc != 3) return 1;
int b = atoi(*++argv);
int d = atoi(*++argv);
if (b < 2) return 2;
int i,j;
for (i=0 ; i<d ; i++) {
int n = nodes_at_depth(b, i); // number of nodes at level i
int s = first_at_depth(b, i); // first number at that level
for (j=0 ; j<n ; j++) printf(" %d", s+j);
printf("\n");
}
return 0;
}
Calling
./heuristic 2 4
gives
0 1
2 3 4 5
6 7 8 9 10 11 12 13
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29

Getting Compiling Error

Here is the task I was given:
Write a function fact_calc that takes a string output argument and an integer input argument n and returns a string showing the calculation of n!. For example, if the value supplied for n were 6, the string returned would be
“6! x 6 x 5 x 4 x 3 x 2 x 1 x = 720”. Write a program that repeatedly prompts the user for an integer between 0 and 9, calls fact_calc and outputs the resulting string in a box of asterisks of the right size to surround the result. If the user inputs an invalid value, the program should display an error message and reprompt for valid input. Input of the sentinel -1 should cause the input loop to exit.
Here is my code:
#include <stdio.h>
/*Prototypes*/
void fact_calc(char [], int);
int main(void)
{
char calc[99];
int num1;
do{
printf("Enter an integer between 0 and 9 or -1 to quit: ");
scanf("%d", &num1);
fact_calc(calc, num1);
}while( num1 != -1 );
return (0);
} //end main
/*Place function definitions below*/
void fact_calc(char calc[], int num1)
{
if(num1 == 0)
char calc[] = "0! = 0 = 0";
else if(num1 == 1)
char calc[] = "1! = 1 = 0"
else if(num1 == 2)
char calc[99] = "2! = 2 x 1 = 2"
else if(num1 == 3)
char calc[99] = "3! = 3 x 2 x 1 = 6"
else if(num1 == 4)
char calc[99] = "4! = 4 x 3 x 2 x 1 = 24"
else if(num1 == 5)
char calc[99] = "5! = 5 x 4 x 3 x 2 x 1 = 120"
else if(num1 == 6)
char calc[99] = "6! = 6 x 5 x 4 x 3 x 2 x 1 = 720"
else if(num1 == 7)
char calc[99] = "7! = 7 x 6 x 5 x 4 x 3 x 2 x 1 = 5040"
else if(num1 == 8)
char calc[99] = "8! = 8 x 7 x 6 x 5 x 4 x 3 x 2 x 1 = 40320"
else if(num1 == 9)
char calc[99] = "9! = 9 x 8 x 7 x 6 x 5 x 4 x 3 x 2 x 1 = 362880"
else
printf("Invalid Entry");
}
I am getting the error:
expected
expression
ch...
^
I still have to print out the string but I can't figure out what the error means or what I am doing wrong. Thanks in advance for the help!
char calc[] = "1! = 1 = 0"
Don't you think you should be ending this line with a ;
char calc[] = "1! = 1 = 0";
Similar fix needs to be done for the rest of the lines
Your program is doing something strange. I doubt it does what you expect.
You are declaring variables inside the body of if statements. These variables will only be in scope for the body, and you don't do anything with them.
Your program can be made to work. I suggest simply making fact_calc() return literal strings rather than try to assign to variables.
/*Place function definitions below*/
char const *fact_calc(char calc[], int num1)
{
if(num1 == 0)
return "0! = 0 = 0";
else if(num1 == 1)
return "1! = 1 = 0";
else if(num1 == 2)
return "2! = 2 x 1 = 2";
else if(num1 == 3)
return "3! = 3 x 2 x 1 = 6";
else if(num1 == 4)
return "4! = 4 x 3 x 2 x 1 = 24";
else if(num1 == 5)
return "5! = 5 x 4 x 3 x 2 x 1 = 120";
else if(num1 == 6)
return "6! = 6 x 5 x 4 x 3 x 2 x 1 = 720";
else if(num1 == 7)
return "7! = 7 x 6 x 5 x 4 x 3 x 2 x 1 = 5040";
else if(num1 == 8)
return "8! = 8 x 7 x 6 x 5 x 4 x 3 x 2 x 1 = 40320";
else if(num1 == 9)
return "9! = 9 x 8 x 7 x 6 x 5 x 4 x 3 x 2 x 1 = 362880";
/* Invalid Entry */
return NULL;
}
Then your main function should declare a variable of type char const * to store the pointer returned by this function, and should check that the pointer is not set to NULL (and print "Invalid Entry" if the pointer was set to NULL).
You cannot assign strings (char arrays) in C. You should use strcpy() instead.
E.g.
strcpy(calc, "2! = 2 x 1 = 2");
Note that you should use strcpy() only if you are 100% certain calc is large enough to store the entire string. If not, use strncpy() instead. Example:
strncpy(calc, "2! = 2 x 1 = 2", 99);
calc[98] = '\0';
// a better way would be to pass 99 to your function, or to declare a macro
Finally, note that both 0! and 1! should be 1, not 0.

Optimize a summing of array (subset problem)

In the hottest part of my program (90% of time according to gprof), I need to sum one array A into another B. Both arrays are 2^n (n is 18..24) sized and holds an integer (for simplicity, actually the element stored is mpz_t or small int array). The rule of summing: for each i in 0..2^n-1, set B[i] = sum (A[j]), where j is bit vector, and j & ~ i == 0 (in other words, k-th bit of any j can't be set to 1 if k-th bit of i is not 1).
My current code (this is a body of innermost loop) does this in the time of 2^(1.5 * n) sums, because I will iterate for each i on (in average) 2^(n/2) elements of A.
int A[1<<n]; // have some data
int B[1<<n]; // empty
for (int i = 0; i < (1<<n); i++ ) {
/* Iterate over subsets */
for (int j = i; ; j=(j-1) & i ) {
B[i] += A[j]; /* it is an `sum`, actually it can be a mpz_add here */
if(j==0) break;
}
}
My I mentioned, that almost any sum is recomputed from the values, summed earlier. I suggest, there can be code, doing the same task in the time of n* 2^n sums.
My first idea is that B[i] = B[i_without_the_most_significant_bit] + A[j_new]; where j_new is only j's having the most_significant bit from i in '1' state. This halves my time, but this is not enough (still hours and days on real problem size):
int A[1<<n];
int B[1<<n];
B[0] = A[0]; // the i==0 will not work with my idea and clz()
for (int i = 1; i < (1<<n); i++ ) {
int msb_of_i = 1<< ((sizeof(int)*8)-__builtin_clz(i)-1);
int i_wo_msb = i & ~ msb;
B[i] = B[i_wo_msb];
/* Iterate over subsets */
for (int j_new = i; ; j_new=(j_new-1) & i ) {
B[i] += A[j_new];
if(j_new==msb) break; // stop, when we will try to unset msb
}
}
Can you suggest better algorithm?
Additional image, list of i and j summed for each i for n=4:
i j`s summed
0 0
1 0 1
2 0 2
3 0 1 2 3
4 0 4
5 0 1 4 5
6 0 2 4 6
7 0 1 2 3 4 5 6 7
8 0 8
9 0 1 8 9
a 0 2 8 a
b 0 1 2 3 8 9 a b
c 0 4 8 c
d 0 1 4 5 8 9 c d
e 0 2 4 6 8 a c e
f 0 1 2 3 4 5 6 7 8 9 a b c d e f
Note the similarity of figures
PS the msb magic is from here: Unset the most significant bit in a word (int32) [C]
Divide and conquer anyone? Now not in-place.
void sums(int *a, int n, int *b) {
if (n <= 0) {
*b = *a;
return;
}
int m = 1 << (n - 1);
sums(a, n - 1, b);
sums(a + m, n - 1, b + m);
for (int i = 0; i < m; i++) {
b[m + i] += b[i];
}
}

Resources