a recursive function to calculate sum of a number digits - python

i have to write a recursive function which calculates sum of a number digits,here's the code i tried :
def sum_digit(n):
sum=0
a = n % 10
n //= 10
sum += a
while n > 0 :
sum = sum + sum_digit(n)
return sum
print(sum_digit(67154))
i don't know why i don't get the 23 as answer...my program doesn't come to an end
for example 23 number(please correct me if I'm wrong,I'm a newbie in python),the 3 goes to sum, and n become2,since its > 0 then it should go to while,so now it should calculate sum digit(2),the a become 2 and 2 goes to sum and n become 0 and sum digit(2) returns 2,then it sum with the 3 and i must get 5.
i appreciate your help.

You have an infinite loop because n never changes within the loop. Note that assigning a new value to n in the scope of the called function will not change n in the outer scope.
Also, it seems you are mixing an iterative solution with a recursive one. If you do the recursive call, you do not need the loop, and vice versa.
You can either do it recursively:
def sum_digit(n):
if n > 0:
return sum_digit(n // 10) + n % 10
else:
return 0
Or in an iterative way:
def sum_digit(n):
s = 0
while n > 0:
s += n % 10
n //= 10
return s
Or just using bultin functions (probably not what your teacher wants to see):
def sum_digit(n):
return sum(map(int, str(n)))

i must change the while with a if, and it works,thanks for your comments and sorry for posting such a question here.

This will do the trick:
def sum_digit(n, current_sum=0):
if n == 0:
return current_sum
else:
digit = n % 10
current_sum += digit
n //= 10
return sum_digit(n, current_sum)
The output:
print(sum_digit(67154))
> 23
You were mixing up an iterative method (the while loop) and the recursive method (the function call).
In a recursive function, must make sure you get these things right:
The end condition (in our case, we return the sum when the digit is 0)
and
The recursive call (in our case, going down one digit each time)

Change your code as following:
def sum_digit(n):
sum=0
a = n % 10
n //= 10
sum += a
if n > 0 :
sum = sum + sum_digit(n)
return sum
The reason is n is assigned new reference inside function, but it's invisible outside. so while part is loop died. In fact, while part is executed at most once, so code was changed as above.

Related

a (recursive) function that will calculate sum for a given n

How to write a recursive function that will calculate this sum for a given n?
n
∑ 1/k
k=1
My code:
def sum(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return sum(1/n) + sum(1/n+1)
print(sum(3))
For n = 3 the output should be: 1.8333333333333333
You should avoid declaring a new function with the name sum as there already exists a built-in function with this name.
You can recursively calculate
n n-1
∑ 1/k == 1/n + ∑ 1/k
k=1 for n > 0 k=1
with
def my_recursive_sum(n):
if n <= 0:
return 0
if n == 1:
return 1
return 1/n + my_recursive_sum(n-1)
print(my_recursive_sum(3))
Your solution would easily reach the maximum recursion limit.
when you call again the function using 1/n and 1/n+1 you would use the same n and increase it, so you would never reach the end condition.
the next couple of sum would never have an n value equal to 0 or 1.
Also you should not call again the function with 1/n otherwise you would endup looping forever in the function recall
you should use something like:
>>> def my_sum(n):
... if n < 1:
... return 0
... return 1/n + my_sum(n-1)
...
>>> print(my_sum(3))
1.8333333333333333
>>> 11/6
1.8333333333333333
>>>
edit:
Like mentioned in another answer you should avoid using sum as a name of a function because it's a name already use by python

How to find even sum

I need to find the sum of all even numbers below the inserted number. For example if I insert 8 then the sum would be 2+4+6+8=20. If I insert 9 then it also needs to be 20. And it needs to be based on recursion.
This is what I have so far:
def even(a):
if a == 0:
else:
even(a - 1)
even(8)
I cannot figure out what to change under the "if" part for it to give the right outcome
If the function is called with an odd number, n, then you can immediately call again with the number below (an even).
Then if the function is called with an even number return that even number plus the result of summing all the even numbers below this number by calling again with n - 2.
Finally, your base case occurs when n = 0. In this case just return 0.
So we have
def even_sum(n):
if n % 2 == 1: # n is odd
return even_sum(n - 1)
if n == 0:
return 0
return n + even_sum(n - 2)
which works as expected
>>> even_sum(8)
20
>>> even_sum(9)
20
>>> even_sum(0)
0
To design a recursive algorithm, the first thing to wonder is "In what cases can my algorithm return an answer trivially?". In your case, the answer is "If it is called with 0, the algorithm answers 0". Hence, you can write:
def even(n):
if n == 0:
return 0
Now the next question is "Given a particular input, how can I reduce the size of this input, so that it will eventually reach the trivial condition?"
If you have an even number, you want to have this even number + the sum of even numbers below it, which is the result of even(n-2). If you have an odd number, you want to return the sum of even numbers below it. Hence the final version of your function is:
def even(n):
if n == 0 or n == 1:
return 0
if n % 2 == 0:
return n + even(n - 2)
return even(n - 1)
Both with o(n) time complexity
With For loop
num = int(input("Enter a number: ")) # given number to find sum
my_sum = 0
for n in range(num + 1):
if n % 2 == 0:
my_sum += n
print(my_sum)
With recursion
def my_sum(num):
if num == 0:
return 0
if num % 2 == 1:
return my_sum(num - 1)
return num + my_sum(num - 2)
always avoid O(n^2) and greater time complexity
For a recursive solution:
def evenSum(N): return 0 if N < 2 else N - N%2 + evenSum(N-2)
If you were always given an even number as input, you could simply recurse using N + f(N-2).
For example: 8 + ( 6 + (4 + ( 2 + 0 ) ) )
But the odd numbers will require that you strip the odd bit in the calculation (e.g. subtracting 1 at each recursion)
For example: 9-1 + ( 7-1 + ( 5-1 + ( 3-1 + 0 ) ) )
You can achieve this stripping of odd bits by subtracting the modulo 2 of the input value. This subtracts zero for even numbers and one for odd numbers.
adjusting your code
Your approach is recursing by 1, so it will go through both the even and odd numbers down to zero (at which point it must stop recursing and simply return zero).
Here's how you can adjust it:
Return a value of zero when you are given zero as input
Make sure to return the computed value that comes from the next level of recursion (you are missing return in front of your call to even(a-1)
Add the parameter value when it is even but don't add it when it is odd
...
def even(a):
if a == 0 : return 0 # base case, no further recusion
if a%2 == 1 : return even(a-1) # odd number: skip to even number
return a + even(a-1) # even number: add with recursion
# a+even(a-2) would be better
A trick to create a recursive function
An easy way to come up with the structure of a recursive function is to be very optimistic and imagine that you already have one that works. Then determine how you would use the result of that imaginary function to produce the next result. That will be the recursive part of the function.
Finally, find a case where you would know the answer without using the function. That will be your exit condition.
In this case (sum of even numbers), imagine you already have a function magic(x) that gives you the answer for x. How would you use it to find a solution for n given the result of magic(n-1) ?
If n is even, add it to magic(n-1). If n is odd, use magic(n-1) directly.
Now, to find a smaller n where we know the answer without using magic(). Well if n is less than 2 (or zero) we know that magic(n) will return zero so we can give that result without calling it.
So our recursion is "n+magic(n-1) if n is even, else magic(n-1)"
and our stop condition is "zero if n < 2"
Now substitute magic with the name of your function and the magic is done.
For an O(1) solution:
Given that the sum of numbers from 1 to N can be calculated with N*(N+1)//2, you can get half of the sum of even numbers if you use N//2 in the formula. Then multiply the result by 2 to obtain the sum of even numbers.
so (N//2)*(N//2+1) will give the answer directly in O(1) time:
N = 8
print((N//2)*(N//2+1))
# 20
# other examples:
for N in range(10):
print(N,N//2*(N//2+1))
# 0 0
# 1 0
# 2 2
# 3 2
# 4 6
# 5 6
# 6 12
# 7 12
# 8 20
# 9 20
Visually, you can see the progression like this:
1..n : 1 2 3 4 5 6 7 8
∑n : 1 3 6 10 15 21 28 36 n(n+1)/2
n/2 : 0 1 1 2 2 3 3 4
1..n/2 : 1 2 3 4
∑n/2 : 1 3 5 10 half of the result
2∑n/2 : 2 6 10 20 sum of even numbers
So we simply replace N with N//2 in the formula and multiply the result by 2:
N*(N+1)//2 --> replace N with N//2 --> N//2*(N//2+1)//2
N//2*(N//2+1)//2 --> multiply by 2 --> N//2*(N//2+1)
Another way to see it is using Gauss's visualisation of the sum of numbers but using even numbers:
ascending 2 4 6 8 ... N-6 N-4 N-2 N (where N is even)
descending N N-2 N-4 N-6 ... 8 6 4 2
--- --- --- --- --- --- --- ---
totals N+2 N+2 N+2 N+2 ... N+2 N+2 N+2 N+2 (N/2 times N+2)
Because we added the even numbers twice, once in ascending order and once in descending order, the sum of all the totals will be twice the sum of even numbers (we need to divide that sum by 2 to get what we are looking for).
sum of evens: N/2*(N+2)/2 --> N/2*(N/2+1)
The N/2(N/2+1) formulation allows us to supply the formula with an odd number and get the right result by using integer division which absorbs the 'odd bit': N//2(N//2+1)
Recursive O(1) solution
Instead of using the integer division to absorb the odd bit, you could use recursion with the polynomial form of N/2*(N+2)/2: N^2/4 + N/2
def sumEven(n):
if n%2 == 0 : return n**2/4 + n/2 # exit condition
return sumEven(n-1) # recursion
Technically this is recursive although in practice it will never go deeper than 1 level
Try out this.
>>> n = 5
>>> sum(range(0, n+1, 2))
with minimum complexity
# include <stdio.h>
void main()
{
int num, sum, i;
printf("Number: ");
scanf("%d", &num);
i = num;
if (num % 2 != 0)
num = num -1;
sum = (num * (num + 2)) / 4;
printf("The sum of even numbers upto %d is %d\n\n", i, sum);
}
It is a C program and could be used in any language with respective syntax.
And it needs to be based on recursion.
Though you want a recursion one, I still want to share this dp solution with detailed steps to solve this problem.
Dynamic Programming
dp[i] represents the even sum among [0, i] which I denote as nums.
Case1: When i is 0, there is one number 0 in nums. dp[0] is 0.
Case2: When i is 1, there are two numbers 0 and 1 in nums. dp[1] is still 0.
Case3: When i is 2, there are three numbers 0, 1 and 2 in nums. dp[2] is 2.
Case4: When i is greater than 2, there are two more cases
If i is odd, dp[i] = dp[i-1]. Since i is odd, it is the same with [0, i-1].
If i is even, dp[i] = dp[i-2] + i by adding the current even number to the even sum among [0, i-2] (i-1 is odd, so won't be added).
PS. dp[i] = dp[i-1] + i is also ok. The difference is how you initialize dp.
Since we want the even sum among [0, n], we return dp[n]. You can conclude this from the first three cases.
def even_sum(n):
dp = []
# Init
dp.append(0) # dp[0] = 0
dp.append(0) # dp[1] = 0
# DP
for i in range(2, n+1): # n+1 because range(i, j) results [i, j) and you take n into account
if i % 2 == 1: # n is odd
dp.append(dp[i-1]) # dp[i] = dp[i-1]
else: # n is even
dp.append(dp[i-2] + i) # dp[i] = dp[i-2] + i
return dp[-1]

Incrementing while loop isn't working in some test cases

I have to define a function where:
Starting with a positive integer original, keep multiplying original
by n and calculate the sum of all multiples generated including
original until the sum is no longer smaller than total. Return the
minimum number of multiplications needed to reach at value at or above
the given total.
So for example:
multiply_until_total_reached (1,5,2)
1*2=2, (1+2)<5, 2*2=4, (1+2+4)>5, 2 multiplications needed
multiply_until_total_reached (1,15,2)
1*2=2, (1+2)<15, 2*2=4, (1+2+4)<15, 4*2=8, (1+2+4+8)=15, 3 multiplications
My current code works but the returned value is off by 1 in some cases. In a 1,1038,2 case, I get 9 multiplication needed instead of 10 but in the 1,15,2 case, I get the correct amount (3) multiplications.
Here's my code:
def multiply_until_total_reached(original, total, n):
if total < original:
return 0
elif total > original:
sumofdigits = 0 #declares var to keep track of sum of digits to compare to total
timesofmult = 0 #track how many multiplication operations
while sumofdigits <= total + 1:
multnum = original * n
sumofdigits = multnum + original
original = multnum
sumofdigits = sumofdigits + multnum
timesofmult = timesofmult + 1
return timesofmult
What's causing it to be off?
Try this, lot smaller and neater. Explanation is in the comments..
def multiply_until_total_reached(original, total, n):
sum = original #Initialize sum to original
mult_no = 0
while sum < total: #Will auto return 0 if original>=total
sum += original*n #Add original * n
original = original*n #Update the new original
mult_no += 1 #Increase multiplications by 1
return mult_no
print multiply_until_total_reached(1,5,2)
print multiply_until_total_reached(1,15,2)
print multiply_until_total_reached(1,1038,2)
#Output
#2
#3
#10
Your problem is that you are reassigning sumofdigits in every loop iteration. You just have to add multnum to sumofdigits in every iteration (sumofdigits += multnum). Also, your loop condition needs to be fixed to sumofdigits < total since you have to "Return the minimum number of multiplications needed to reach at value or above the given total."
Since solution for your code has already been posted, and you accept alternative solutions, allow me to suggest the following, which makes good use of Python's > 3.2 accumulate() function:
from itertools import accumulate, count
def multiply_until_total_reached(original, total, n):
for i, result in enumerate(accumulate(original*n**c for c in count())):
if result >= total: return i
assert multiply_until_total_reached(1,5,2) == 2
assert multiply_until_total_reached(1,15,2) == 3
assert multiply_until_total_reached(1,1038,2) == 10

Anyway to inverse factorial function?

So the question comes like this, I'm new to python:
def factorial_cap(num): For positive integer n, the factorial of n (denoted as n!), is the product
of all positive integers from 1 to n inclusive. Implement the function that returns the smallest
positive n such that n! is greater than or equal to argument num.
o Assumption: num will always be a positive integer.
# Examples
# factorial_cap(20) output is 4 since 3!<20 but 4!>20
# factorial_cap(24) output is 4 since 4!=24
# factorial_cap(1) output is 1 since 1!=1
# And here is what I got
def factorial_cap(num):
n = 1
for i in range (1,num+1):
n = n*i
I'm pretty sure this is the right function for factorial def. But I just couldn't figure out, instead of getting the 'total value', how can I just get the right output as I posted example above?
Btw, should I use 'return' at the end of def, or it does not matter in this case?
There needs to be a test for when the current total is greater than or equal to the requested number. So you can use the condition of a while loop to perform that check, and increment a counter, i, that keeps track of the current iteration. Then it's a matter of returning the current value of i that produced the value >= the required number:
def factorial_cap(num):
n = 1
i = 1
while n < num:
i += 1
n *= i
return i
>>> factorial_cap(20)
4
>>> factorial_cap(24)
4
>>> factorial_cap(25)
5
>>> factorial_cap(1)
1
>>> factorial_cap(3628800)
10
You want a return but that isn't n, but i
def factorial_cap(num):
n = 1
i = 0
while True:
i += 1
n = n*i
if n >= num:
break
return i
print(factorial_cap(20))
print(factorial_cap(24))
print(factorial_cap(1))

Factorial in Python using while

why this function doesn't work as a factorial function?
def Factor(n):
while n>=1:
print n*(n-1)
return 1
This will work
def Factor(n):
val=1
while n>=1:
val = val * n
n = n-1
return val
You have recursion and iteration mixed. Take a look at these two:
def factor_recursion(n):
while n>=1:
return n * factor_recursion(n-1)
return 1
def factor_iteration_for(n):
factor = 1
for i in range(n):
factor *= i+1
return factor
def factor_iteration_while(n):
factor = 1
while n >= 1:
factor *= n
n -= 1
return factor
print factor_iteration_for(4)
print factor_iteration_while(4)
print factor_recursion(4)
You never change the value of n to anything other than what is passed into the function.
I don't think this is going to do what you think it will. Looks like you've mixed recursion and iteration.
First of all, none of your code changes the value of n, so the loop will run indefinitely unless n == 1 when the function is called.
Secondly, you aren't accumulating a partial product inside the loop (hint: before the loop set result =, then inside it multiply the current value of result by the value of n.
Finally, you should then return the accumulated result rather than one.
def factorial(num):
if num == 0:
return 1
else:
return num * factorial(num - 1)
print factorial(5)

Categories

Resources