Using Recursion to find sum of applicable integers - c

I am trying to take an integer (X) and use recursion to find the sum of digits that apply to a particular condition up to X. For example, given 10 and using conditions divisible by 2 or 3, the sum would be 5.
I have already used a different loops to solve the problem and now trying to practice with recursion.
int sum(int n) {
int totalSum;
if (n==0)
return 0;
else {
if ((n%2==0)||(n%3==0)){
totalSum+= sum(n-1);
return totalSum;
}
else {
totalSum=sum(n-1);
return totalSum;
}
}
}
I keep either receiving a zero or an incredibly high number.

totalSum+= sum(n-1);
can't possibly be correct. You never initialized totalSum, so how could it be correct to add something to it? Even if C automatically initialized variables, it would presumably initialize it to 0, so this would be equivalent to totalSum = sum(n-1);, which is the same thing you do when n is not a multiple of 2 or 3.
Notice that neither of your conditions adds the current iteration variable to anything. You should be adding n, not totalSum:
totalSum = n + sum(n-1);

Related

Variable is exceeding specified limit in for loop

I have written code to find the units and tens digit of a number,but am facing a problem when the number is greater than 99.The value of i has been set to less than 10 inside the for loop but when i execute the code with no=100,I find that i has a value of 10.
Why is this happening?
#include <stdio.h>
int unit(int x){
return x%10;
}
int ten(int x){
int temp=x-unit(x);
if(temp==0){
return 0;
}
else{
for(int i=1;i<10;i++){
if(temp%(i*10)==0 && temp/(i*10)==1){
return i;
}
}
}
}
int main(){
int no=100;
printf("%d",ten((no)));
return 0;
}
Think about what happens when the number is greater than 99. You will not be able to find a value of i b/w 1 and 9 such that the expression in the if is true. You will need a value of i > 10, but of course, then it wouldn't be the tens digit of the number.
Your method only works for a specific case, ie, when the number is b/w 1 and 10^2. Sure, you could write some more code to make it work for numbers b/w 1 and 10^3, but that would just be a pain in the ass. Even then, you'd have to write more code if the number is greater than that.
Try to think of a solution for the general case. To do that, two facts would be very useful:
Dividing using / only gives the integer part of the answer. Eg: 66/10 = 6
% This operator gives you the remainder. Eg: 59%10 = 9
1) In the else block of ten() you are returning a value only if some condition is met. If the condition does not satisfy you are not returning anything. In that case a garbage value may be printed.
2) To get the tenth digit, that is a lot of work. Just change the function body to -
int ten(int x) {
return (x % 100) /10;
}
The numbers upto 99 gets correct result because the condition satisfies. Lets take 99 as an example. After unit digit subtraction you got 90. When i becomes 9, the temp%(i*10) becomes 0 and temp/(i*10) becomes 1.
When number is 100, after unit digit subtraction the number remains same(i.e. 100). But for values of i from 1 to 9 temp/(i*10) never becomes 1 and the loop quits, resulting in the absurd behavior. You will get the same behavior for all the numbers that are greater than 99 using your code.

Why we can't compare a int variable with int return type function in c?

I tried to compare int variable with the function in two ways:
storing the int function return value in a variable then comparing with another
in value.
Directly comparing the int variable and the function call.
Here I got the answer for the first one but not for the second one.
Why does this happen?
My code:
#include < stdio.h >
int count = 0;
int countDigits(int);
int main() {
int i;
int result = countDigits(435);
for (i = 0; i < result; i++) {
printf("id %d\n", 3);
}
for (i = 0; i < countDigits(435); i++) {
printf("i =%d\n", i);
}
}
int countDigits(int n) {
if (n == 0) {
return count;
} else {
countDigits(n / 10);
count++;
}
}
We can.
It's just that your function has a logical error. Debug it, and you will be fine.
Enabling compiler warnings would have helped you. For example with GCC and Wall flag, you get:
prog.c: In function 'countDigits':
prog.c:32:1: warning: control reaches end of non-void
function [-Wreturn-type]
}
^
Tip: Think of what your function does if n us different than zero.
count is a global variable.
The function countDigits(n) adds the number of decimal digits in n to count and
If n is zero it returns 1.
If n is non-zero the return value is undefined.
Since countDigits(435) has an undefined value, anything can happen and no further analysis is necessary.
Let's assume that this obvious error is corrected by inserting return count; after count++;. In this case, the function returns the incremented count.
So we have this nice sequence:
Set result to countDigits(435).
countDigits(435) adds 3 to count and returns 3.
Set i to 0 and compare to countDigits(435).
countDigits(435) adds 3 to count and returns 6. 0 is less than 6, so the for loop continues.
Now i is 1, and we compare it to countDigits(435).
countDigits(435) adds 3 to count and returns 9. 1 is less than 9, so the for loop continues.
Now i is 2, and we compare it to countDigits(435).
countDigits(435) adds 3 to count and returns 12. 2 is less than 12, so the for loop continues.
... And so on.
Morality:
Beware of side effects. Never use and modify global variables unless you have a good reason to.
When you must use side effects, keep them prominent in your mind.
It is possible to compare a variable directly with the output of a function. However, your function countDigits has several problems.
Not all code paths return a value - you're missing a return statement in the else block. This alone makes the output of the function undefined.
It's not algorithmically correct. Have you tried debugging it? Just start with printing the output for different inputs and you'll see.
Modifying and returning a global variable count inside that function is a really bad practice - it should be local to the function. When it's global, every call to the function modifies a [possibly] already modified variable.
Others have already addressed the problem here with globals, so I will not go into details about that. Instead, here is a solution without globals:
int countDigits(int n) {
int count = 0;
while(n>0) {
n/=10;
count++;
}
return count;
}
I guess you could be philosophical about whether 0 has 0 or 1 digit, but your code implied that you wanted it to be 0. If you want it to be 1 instead, just change the first row to int count = 1.

Incorrect output from recursive function to compute sum of digits of a number

I was trying to write a function that would compute the sum of the digits of a number using recursion, but the output is incorrect. Here's the code:
/*Write a function to calculate sum of digits of a number using recursion*/
/*Author:Udit Gupta Date:10/08/2011*/
#include<stdio.h>
int sum (int);
int main () {
int n,s;
printf ("Enter the number:");
scanf ("%d",&n);
s = sum (n);
printf ("The sum of the digits of the number is %d",s);
}
int sum (int a) {
int f;
if (a == 0) {
return f;
}
f = (a% 10) + sum (a/10);
}
Here are some of the output values:
udit#udit-Dabba ~/Desktop/letusc/ch5/J $ ./a2.out
Enter the number:123
The sum of the digits of the number is 7
udit#udit-Dabba ~/Desktop/letusc/ch5/J $ ./a2.out
Enter the number:1234
The sum of the digits of the number is 2919930
udit#udit-Dabba ~/Desktop/letusc/ch5/J $ ./a2.out
Enter the number:123456
The sum of the digits of the number is 4620297
udit#udit-Dabba ~/Desktop/letusc/ch5/J $ ./a2.out
Enter the number:12345
The sum of the digits of the number is 15 /*Only this one seems correct*/
Can someone help me figure out why this isn't working correctly?
Let's look at this recursive function in more detail:
int sum (int a) {
int f;
if (a == 0)
return f;
f = (a% 10) + sum (a/10);
}
While you're on the right track and you have the right idea in general, your actual implementation is a bit buggy. For starters, let's look at these lines:
if (a == 0)
return f;
You have the right idea to terminate the recursion when a reaches zero, but the way you're doing it is a bit off. In particular, you're returning the value of the integer f, but you've never initialized it. This means that the return value is completely arbitrary. Instead of writing this, I think that you probably meant to write something closer to
if (a == 0)
return 0;
which correctly says "if the number is zero, the sum of its digits is zero."
Similarly, take a look at the last line of your function:
f = (a% 10) + sum (a/10);
Again, your intuition is spot-on: the sum of the digits of a number are given by the sum of its first digit and the sum of the rest of its digits. However, notice that while you're correctly computing the sum of the digits, you aren't correctly returning the sum of the digits. In fact, you don't return anything at all if you execute this code, so the return value from the function is unspecified, hence the garbage output. To fix this, consider rewriting the code like this:
return (a % 10) + sum (a / 10);
This actually says to hand back the value that you just generated right here, instead of storing it in a local variable that will be immediately cleaned up as soon as the function returns.
I believe that the reason you coded this function this way is that you're under the impression that the value of int f; is carried across the function calls. Unfortunately, it is not. When writing a recursive function, each instance of the function is completely independent of each other instance and local variables accessible in one recursive call are not accessible in other recursive calls. Consequently, even though each recursive call has its own variable int f, those variables are all completely independent of one another. The value isn't carried through them. If you want to communicate values across recursive functions, the best way to do it is by using the return value of the recursive calls, or (if you must) by passing a pointer to some value down through the recursion.
Hope this helps!
When a is 0, you are returning an uninitialized value (f was not initialized).
Change it to:
if (a == 0)
return 0;
You also forgot the return in the end of the function:
return (a% 10) + sum (a/10);
It is highly recommended that you always compile with the flag -Wall, which would warn you about those mistakes.
Your recursive function will calculate nothing it either returns an uninitialized int or nothing. You need to be returning the work you are doing in the function.
int sum (int a) {
if (a == 0) {
return 0;
}
return (a% 10) + sum(a/10);
}
return a == 0 ? 0 : ((a% 10) + sum (a/10));
You only return f is it is 0, but not if it isn't, which makes your return value undefined. I assume you want to do:
int sum (int a) {
int f;
if (a == 0)
return 0;
f = (a % 10) + sum (a / 10);
return f;
}

Trouble making a running total in C

I'm new at programming, new on this site too, so hello...
I'm attempting to obtain a running total for integers one thru 10, but I'm getting gibberish answers and I just can't understand why.
To attempt to find out what was going wrong, I added the
printf(" running total is %d\n", sum);
line to the while loop, but just got more of the same nonsense...
please see http://codepad.org/UxEw6pFU for the results....
I'm sure this has a blindingly obvious solution...I'm just too dumb to see it though!
anyone know what I'm doing wrong?
#include <stdio.h>
int main(void) {
int count,sum,square;
int upto=10;
count = 0;
square = 0;
while (++count < upto) {
square = count * count;
printf("square of %d is %d",count,square);
sum =square + sum;
printf(" running total is %d\n", sum);
}
printf("overall total of squares of integers 1 thru 10 is %d\n", sum);
return 0;
}
You need to initialize sum to 0.
EDIT As others have stated after the fact, the reason you're seeing garbage is because sum isn't initialized and contains whatever is in memory. It can be anything, and your use of it with sum = square + sum is going to add square to the uninitialized value.
You are never initializing the value of sum.
The first time your code runs
sum = square + sum;
The value of sum (on the right side) is an arbitrary number because it has not been initialized. Therefore, the resulting value of sum (on the left side) is that arbitrary number plus square.
Simply add a sum = 0 statement like you have for count and square already.
Right off the bat, you do not initialize 'sum' to anything.
edit: A cleaned up version, though depending on compiler, you might need to enforce C99 mode, otherwise older compilers might not support initial declarations in the for loop.
#include <stdio.h>
int main()
{
const int COUNT_MAX = 10;
int sum = 0;
for ( int i = 1; i <= COUNT_MAX; ++i )
{
sum += i*i;
}
printf("The sum of squares from 1 to 10 is: %d\n", sum);
return 0;
}
Initialize sum with 0, otherwise it contains arbitrary data:
sum = 0;
See: http://codepad.org/e8pziVHm
sum is not initialized
You should do :
sum=0;
and remove
square=0;

Is my looping solution cheat for this puzzle?

This programming problem is #85 from a page of Microsoft interview questions. The complete problem description and my solution are posted below, but I wanted to ask my question first.
The rules say that you can loop for a fixed number of times. That is, if 'x' is a variable, you can loop over a block of code based on the value of 'x' at the time that you enter the loop. If 'x' changes during the loop, that won't change how many times you loop. Also, that is the only way to loop. You can't, for instance, loop until some condition is met.
In my solution to the problem, I have a loop which will be set to execute zero or more times. The problem is, in reality, it only ever executes 0 times or 1 time because the only statement in my loop is a return statement. So if we enter the loop, it only has a chance to run once. I am using this tactic instead of using an if-else block, because logical comparisons and if statements are not allowed. The rules don't explicitly say that you can't do this, but I am wondering if you would consider my solution invalid. I couldn't really figure out another way to do it.
So here are my questions:
Do you think my solution is invalid?
If so, did you think of another way to solve the problem?
Problem description:
85) You have an abstract computer, so just forget everything you know
about computers, this one only does what I'm about to tell you it
does. You can use as many variables as you need, there are no negative
numbers, all numbers are integers. You do not know the size of the
integers, they could be infinitely large, so you can't count on
truncating at any point. There are NO comparisons allowed, no if
statements or anything like that. There are only four operations you
can do on a variable.
You can set a variable to 0.
You can set a variable = another variable.
You can increment a variable (only by 1), and it's a post increment.
You can loop. So, if you were to say loop(v1) and v1 = 10, your loop would execute 10 times, but the value in v1 wouldn't change so
the first line in the loop can change value of v1 without changing the
number of times you loop.
You need to do 3 things.
Write a function that decrements by 1.
Write a function that subtracts one variable from another.
Write a function that divides one variable by another.
See if you can implement all 3 using at most 4 variables. Meaning, you're not making function calls now, you're making macros. And at
most you can have 4 variables. The restriction really only applies to
divide, the other 2 are easy to do with 4 vars or less. Division on
the other hand is dependent on the other 2 functions, so, if subtract
requires 3 variables, then divide only has 1 variable left unchanged
after a call to subtract. Basically, just make your function calls to
decrement and subtract so you pass your vars in by reference, and you
can't declare any new variables in a function, what you pass in is all
it gets.
My psuedocode solution (loop(x) means loop through this block of code x times):
// returns number - 1
int decrement(int number)
{
int previous = 0;
int i = 0;
loop(number)
{
previous = i;
i++;
}
return previous;
}
// returns number1 - number2
int subtract(int number1, int number2)
{
loop(number2)
{
number1= decrement(number1);
}
return number1;
}
//returns numerator/denominator
divide(int numerator, int denominator)
{
loop(subtract(numerator+1, denominator))
{
return (1 + divide(subtract(numerator, denominator), denominator));
}
return 0;
}
Here are C# methods that you can build and run. I had to make an artificial way for me to
satisfy the looping rules.
public int decrement(int num)
{
int previous = 0;
int LOOP = 0;
while (LOOP < num)
{
previous = LOOP;
LOOP++;
}
return previous;
}
public int subtract(int number1, int number2)
{
int LOOP = 0;
while (LOOP < number2)
{
number1 = decrement(number1);
LOOP++;
}
return number1;
}
public int divide(int numerator, int denominator)
{
int LOOP = 0;
while (LOOP < subtract(numerator+1, denominator))
{
return (1 + divide(subtract(numerator, denominator), denominator));
}
return 0;
}
Ok so the reason I think your answer might be invalid is because of how you use return. In fact I think just using the return is too much of an assumption. in a few places you use the return value of a function call as an extra variable. Now if the return statement is ok, then your answer is valid. The reason i think its not valid is because the problem hints at the fact that you need to think of these as macros, not function calls. Everything should be done by reference, you should change the variables and the return values are how you left those variables. Here is my solution:
int x, y, v, z;
//This function leaves x decremented by one and v equal to x
def decrement(x,v):
v=0;
loop(x):
x=v;
v++;
//this function leaves x decremented by y (x-y) and v equal to x
def subtract(x,y,v):
loop(y):
decrement(x,v);
//this function leaves x and z as the result of x divided by y, leaves y as is, and v as 0
//input of v and z dont matter, x should be greater than or equal to y or be 0, y should be greater than 0.
def divide(x,y,v,z):
z=0;
loop(x):
//these loops give us z+1 if x is >0 or leave z alone otherwise
loop(x):
z++;
decrement(x,v);
loop(x):
decrement(z,v)
//restore x
x++;
//reduce x by y until, when x is zero z will no longer increment
subtract(x,y,v);
//leave x as z so x is the result
x=z;

Resources