How can I change my iterative code to a recursive one? [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
int findnumb(int max)
{
int left,right,total,desk;
for(total=2; total<=max; total++)
{
for(desk=1; desk<total; desk++)
{
left=desk*(desk-1)/2;
right=(total*(total+1)/2)-(desk*(desk+1)/2);
if(left==right)
{
printf("Desk number %d, number of participants %d\n", desk, total);
break;
}
}
}
}
How can I turn this into a recursive function?
It works well in this form, but when I try to change it to a recursive function it compiles, but doesn't work properly, what should I do?
Edit:
It is for a riddle like this:
Suppose that there exists a meeting and we do not know how many people attend to it.
However, we see a man quitting from the meeting. If we ask the man how many people
exist at the meeting he just replies “I do not know”. Nonetheless he says “I was sitting on
a chair numbered x and summation of the numbers below and above me equals. In other
words, if the number of the chair is x, then 1,2,3….x-1 = x+1 x+2 …...t-1,t (total
participant count). Besides, we do not know the value of t and the chair number x.
Total participant 8, and the chair number 6 is an example configuration. Because
1+2+3+4+5 = 7+8 = 15. Your task is to find similar configurations by one by one try-out.
And It wants the solution to implement a recursive function
Second Edit:
Now I have produced a code that finds the numbers and crashes right after that why is it happening?
Here is the screenshot of the code and the crash http://imgur.com/a/UgZgC

The variables that need to change in each iteration need to be argumants and you need to be true to the functional approach so instead of printing you should return the result:
int findnumb_aux(int max, int total, int desk)
{
if( total > max ) {
return 0; // need to return something when no solution exist
} elseif( desk < total ) {
int left=desk*(desk-1)/2;
int right=(total*(total+1)/2)-(desk*(desk+1)/2);
if(left==right) {
return desk<<8+total; // there are better ways to return two numbers. you figure it out
} else {
return findnum_aux(max, total, desk+1);
}
} else {
return findnum_aux(max,total+1, 1);
}
}
int findnum(int max)
{
return findnum_aux(max, 2, 1);
}
Fun fact: This code is still iterative since it does not grow the stack if your C compiler has tail call optimization.

Related

Subtraction doesn't work in do while how can I fix it? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
Hi I am new in c and I making a text adventure game. But I have a problem withe subtraction in a do while loop. The problem is that the number doesn't change it remains at 95 or in 90 in the second statement. Can someone help how to fix that and explain to me how subtraction works in a loop? Also, I want the loop end when the enemy's life is at zero
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <signal.h>
struct batman{
int helath,punch,kick,darts;
};
int main(void) {
int s=0,sum=0,r,knife=5,gun1=10,punch,enemy=100;
struct batman b;
b.helath=100;
b.punch=5;
b.kick=10;
b.darts=100;
printf("\nPress 1 for punch and 2 for kick");
srand(time(NULL));
do{
scanf("%d",&punch);
if(punch==1){
sum=b.punch-enemy;
printf("\nEnemy's Helath %d",sum);
}
else if(punch==2){
sum=b.kick-enemy;
printf("\nEnemy's Helath %d",sum);
}
r=rand()%2;
if(r==1){
s=b.helath-knife;
printf("\nBatman's Health%d",s);
}
else if(r==2){
s=b.helath-gun1;
printf("\nBatman's Health%d",s);
}
}while(punch==1||punch>=2);
return 0;
}
The value of enemy never changes, so unless the value of punch changes this is effectively a constant. You probably want to do something like:
enemy -= punch;
if (enemy <= 0) {
printf("Batman wins!");
}
to update the health of the enemy. For batman you probably want to do the same, i.e.,
b.health -= gun;
if (b.health <= 0) {
printf("Oh no! Batman lost.");
} else {
printf("Batman's health: %d", b.health);
}
Your game should probably end when either batman.health or enemy reaches 0, so you would want to add a check.

How do I resolve this int overflow? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
int frequency(string note)
{
int i;
float f;
int n=0;
float octave= note[strlen(note)-1];
if(strlen(note)==3)
{
if(note[1]=='#')
{
n+=1;
}
else if(note[1]=='b')
{
n-=1;
}
}
if(note[0]=='B')
{
n+=2;
}
else if(note[0]=='C')
{
n-=9;
}
else if(note[0]=='D')
{
n-=7;
}
else if(note[0]=='E')
{
n-=5;
}
else if(note[0]=='F')
{
n-=4;
}
else if(note[0]=='G')
{
n-=2;
}
n+=(octave-4.0)*12.0;
float p= n/12.0;
f=(int)(round(pow(2.0,p)*440.0));
return f;
}
So basically whenever I run this code I get an error stating "runtime error: value 7.3641e+16 is outside the range of representable values of type 'int'"
Then the value returned is just-2147483648. I've looked it up online and haven't found an answer that helps me with my code. Also this was made in the cs50 IDE so there are a bunch of commands and things that are imported. My program compiles properly and it can run so how do I fix this?
Frequencies of notes of the chromatic scale are not integers in the first place.
If you are passed a two character string like Cb, you get a stupidly huge octive with a frequency way too high.

Gauss-Jordan Elimination in C [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
So, I have some class work that I cannot solve. I could get the code to work partially but now it is just useless. It either freezes (doesn't complete running) or it will give me several inf in the first row.
#include <stdio.h>
#include <math.h>
int main()
{
double a[10][11]={
{3.55618, 5.87317, 7.84934, 5.6951, 3.84642, 9.15038, -1.68539, 5.03067, 7.63384, -1.75626, -1.92193},
{-4.82893, 8.38177, -0.301221, 5.10182, -4.1169,-6.09145, -3.95675, -2.33365, 1.3969, 6.54555, -2.35262},
{-7.64196, 5.66605, 3.20481, 1.55619, -1.19814, 9.79288, 5.35547, 5.86109, 4.95544, -9.35749, 2.27709},
{-2.95914, -9.16958, 7.3216, 2.39876, -8.1302, -7.55135, -2.37718, 7.29694, 5.9867, 8.5401, -2.67493},
{-8.42043, -0.369407, -5.4102, -8.00545, 9.22153, 3.96454, 5.38499, 0.438365, 0.419677, 4.17166, 1.84756},
{6.02952, 4.57728, 5.46424, 3.52915, -1.01135, -3.74686, 8.14264, -8.86961, -2.88114, 1.29821, 4.154126},
{0.519819, -6.16655, 1.13216, 2.75811, -1.05975, 4.20286, -3.45764, 0.763558, -0.281287, -9.76168, -.93387},
{5.15737, -9.67481, 9.29904, -3.93334, 9.12785, -4.25208, -6.1652, 2.5375, 0.139195, 2.00106, -1.28356},
{-4.30784, 1.40711, -6.97966, -9.29715, 5.17234, 2.42634, 1.88818, -2.05526, -3.7679, 3.3708, -3.46841},
{-4.65418, 7.18118, 6.51338, 3.13249, 0.188456, -16.85599, 7.21435, -2.93417, 1.06061, 1.10807, -2.61529}};
int i, j, k, l;
double b[10][11];
i=0;
while(i<10)
{
j=0;
l=i;
while(l<10)
{
j=0;
l++;
while(j<11)
{
This code below works fine. When used on its own, it will turn all the diagonal values into 1.
b[i][j]=a[i][j]/a[i][i];
This code used below to work partially, setting the first column equal to 0, but now it is useless. I tried to manipulate it into getting rid of all values by having that 0 be a k, with k++ within the while code, but it would return either a segmentation code if I placed it by the i++; or a bus error is placed in front of the j=0;, and it would just freeze the program if I placed the i in the 0. Now it is useless that I restored it to default
b[l][j]=a[l][j]-b[i][j]*a[l][0];
j++;
}
}
i++;
}
j=0;
i=0;
while(i<10)
{
while(j<11)
{
printf("%lf\t", b[i][j]);
j++;
}
printf("\n");
i++;
j=0;
}
return 0;
}
How do I go about solving all these issues within my C program?
Not 100% sure what your code is up to, but I see at least 1 place where I believe that you are reading off the end of your arrays:
while(l<10)
{
j=0;
l++;
...
b[l][j]=a[l][j]-b[i][j]*a[l][0];
Because you are incrementing after you check for max size, you have 1 iteration where you are probably reading passed the max size of the array.
To check, put some prints on your indexes in your code where you do your assignments or assert them or something and I think you will find the source of your woes.
Also, PLEASE use constants for your sizes instead of the magic numbers all over the place. You will thank me later when trying to do a calculation of a matrix of a different size.

Board game functions

I have made a program to a board game. My problem is a function, so that certain fields transport the player back or forward. Apparently the thing I did doesn't work.
int numbers()
{
int maxscore;
int numbers[10];
maxscore = enter();
srand(time(NULL));
int nonumbers[3] = {0, 1, maxscore}; //to initialize the scores there shouldn't be a badfield
numbers[10] = rand() % maxscore + 1;
if(numbers[10] == nonumbers[3])
{
numbers[10] = rand() % maxscore + 1;
}
return numbers;
}
int badfields = numbers();
if(score[i] == badfields)
{
printf("Player %d. goes 5 fields backwards", playershown);
score[i] = score[i] - 5;
printf("This player is now in %d Field", score[i]);
}
Somehow I have to repeat the process of entering the maximum score.
I won't directly answer the "question" because there is no "question" to be answered. As others have pointed out in the comments, you need to be more specific and provide a proper description of your problem. But I can still provide the following feedback:
It seems to me you don't quite understand arrays and their indexing. For example, this line should give you a segmentation fault error, or at the very least make a comparison with an unknown value:
if(numbers[10] == nonumbers[3])
This is because your nonumbers array has 3 elements, and thus they should be addressed as nonumbers[0], nonumbers[1] or nonumbers[2] (or, in general, as Weather Vane put it in the comments, from nonumbers[0] to nonumbers[array_lenght-1]). nonumbers[3] will access an undefined position in memory. Your problem could be related to this.
Note that neither me nor anybody is going to review your entire code
to find the error. As stated above, please be more specific.
Also, are you sure you got rid of all compiler errors? Because further down your code you have an uninitialized variable i. To be sure you got rid of all potentially nasty errors, open the terminal (I'm assuming you are on linux) and use the following command to compile your program:
gcc *.c -Wall -Wextra -o program
Then run it with:
./program

Deciding the base condition in backtracking recursive algorithm

I was solving the N Queen problem where we need to place 4 queens on a 4 X 4 chess board such that no two queens can attack each other. I tried this earlier but my approach did not involve backtracking, so I was trying again. The code snippets are
int size=4,i,j;
int arr[4][4];
int lastjindex[4]; // to store the last location which we may need to backtrack
void placeQueen(int i,int j)
{
int availableornot=0;
for(j=0;j<size;j++)
{
if(isAvailable(i,j)==1)
{
availableornot=1;
break;
}
}
if(availableornot==1)
{
arr[i][j]=1;
lastjindex[i]=j;
if((i+1)!=size)
{
placeQueen(i+1,0);
}
}
else
{
// no column was availabe so we backtrack
arr[i-1][lastjindex[i-1]]=0;
placeQueen(i-1,lastjindex[i-1]+1);
}
}
The isAvailable() method returns 1 if arr[i][j] is not under attack, else it returns 0.
int isAvailable(int i,int j)
{
int m,n,flag=0;
for(m=0;m<i;m++)
{
for(n=0;n<size;n++)
{
int k=abs(i-m);
int l=abs(j-n);
if(arr[m][j]==0 || arr[k][l]==0)
{
flag=1;
break;
// means that spot is available
}
}
}
return flag;
}
I call the above method from main as
placeQueen(0,0);
My program compiles successfully but it prints all zeroes.
Is there any problem with my recursion? Please help me correct my code as I am trying to learn how to implement backtracking algorithms!
Also I am not able to decide the base condition to end recursion. How do I choose it here?
There's no printing in the code you posted. If you print after you have backtracked, you will be back to the initial condition of no queens on the board. Print after you have placed N queens, which is also the end condition for recursion. If you only want to print one solution, exit after printing, or set a flag that tells the caller that you're done so you pop all the way out. If you print all solutions, that will include reflections and rotations. You can eliminate one axis of reflection by only placing queens within size/2 in the first level.
Also, there are some clear logic errors in you code, such as
arr[m][j]==0 || arr[k][l]==0
A queen can only be placed if it isn't attacked on the file and it isn't attacked along a diagonal. Use a debugger or add printfs to your code to trace where it is trying to place queens -- that will help you figure out what it is doing wrong.
And aside from being wrong, your isAvailable is very inefficient. You want to know if the [i,j] square is attacked along the file or a diagonal. For that you should have a single loop over the rows of the previous queens for (m = 0; m < i; m++), but you only need three tests, not a loop, to check the file and the diagonals. As soon as you find any previous queen on a file or diagonal, you're done, and the square isn't available -- return false. (And ignore people who tell you that a function should only have one return -- they are wrong, and there are lengthly discussions here at SO and even scientific studies of error rates in code that bear this out.) Only if no previous queen is found is the square available.
Your placeQueen is also wrong. For each available square on a row, you need to place a queen and then recurse, but you're just finding the first available square. And backtracking is achieved simply by removing the queen you placed and then returning ... the previous level of placeQueen will try the next available spot.
Again, trace the code to see what it's doing. And, even more importantly, think through the logic of what is needed. Write your algorithm in words, convince yourself that it will solve the problem, then write the code to carry out the algorithm.
#include <stdio.h>
#define SIZE 4
int size=SIZE;
int arr[SIZE][SIZE] = { 0 };
void placeQueen(int col){
int r,c;
if(col == size){//all queen put!
//print out
for(r = 0;r<size;++r){
for(c = 0;c<size;++c)
printf("%d", arr[c][r]);
printf("\n");
}
printf("\n");
return ;
}
for(r=0;r<size;++r){
if(isAvailable(col, r)==1){
arr[col][r]=1;
placeQueen(col+1);
arr[col][r]=0;//reset
}
}
}
int isAvailable(int col,int row){
int c;
for(c=0;c<col;++c){
int d = col - c;
if(arr[c][row]==1)
return 0;//queen already same row
if(row+d < size && arr[c][row+d]==1 || row-d >= 0 && arr[c][row-d]==1)
return 0;//queen already same slanting position
}
return 1;
}
int main(){
placeQueen(0);
return 0;
}

Resources