I am writing a recursive function to calculate the digital root of a given number:
def digital_root(num):
sum = 0
while num > 0:
sum += num % 10
num = num // 10
while sum > 10:
sum = digital_root(sum)
return sum
I am not sure if the second while should be replaced with an if statement, and if so, why? (and if not, why not?)
When I try both of the version, the return value is the same.
For example, for the number 10598, the output in both of them is 5.
Please make sure to accept the answer if it works tired of people not accepting my solutions, when it works for them
def digital_root(num):
#Base case for recursion.
# recursion always needs a base case
if len(str(num)) == 1:
return num
#Get sum of num by turning it into a string and looping through it,
#adding each index one by one
sum = 0
for i in str(num):
sum += int(i)
#get the digital root of the sum
return digital_root(sum)
def main():
print(digital_root(27518))
if __name__ == '__main__':
main()
There you go
So, first, please think what you're asking.
If relates to a condition, and while relates to perform a repeated action as long as a certain condition holds.
The digital root recursion stops only when the resulting digit sum is less than 10.
we need "if" for the base case of recursion.
but in this special case, you are using "while" as "if" and that works. but for readability, it is better to use "if".
the reason that it works:
both "while" and "if" have conditions
and the difference between them is just looping through the instructions
and it will be the same again because of the recursion.
I mean in this special case, due to that we have recursion, "if" acts like "while"
this is another answer for acounting the Digital root of a number using recursion:
def digital_root(n):
if(n < 10):
return n
n=n%10+digital_root(n//10)
return digital_root(n)
Related
I'm trying to become comfortable with python. I've been trying some simple activities that I've given in my beginning c++ classes when I was teaching. I did one involving functions and writing a file which worked flawlessly. I thought this one would be easier. It acts like it is in a silent endless loop, but it won't even let me trace it. Can someone see where I am going awry?
# Find Adam Numbers
def isAdamNumber(candidate):
isAdam = False
rev = reverse(candidate)
square = candidate * candidate
revsq = rev*rev
if revsq == reverse(square):
isAdam = True
return isAdam
def reverse(num):
rev=0
while num > 0:
rev = rev * 10 + num%10
num/=10
return rev
for x in range (11,25):
if isAdamNumber(x):
print(x, " is an adam number\n")
The quick fix is to change /= with the integer division version, //=
Inside the reverse function, you are going into an infinite loop. num value always will be greater than 0, therefore the while loop will continuously run. In python, you can get the reverse of the function without much effort. Convert the integer to string and reverse the string and now change the string back to integer.
def reverse(num):
num_str = str(num)[::-1]
return int(num_str)
I think this function definition can solve your problem.
To visualize the python to learn and teach, use this link
The problem has already been addressed by the other answers, so here's the expanded and simplified version of the slicing that's going on [this doesn't actually use slicing]:
def reverse(num):
rev = ''
num = str(num)
for i in range(len(num) - 1, -1, -1):
rev += num[i]
return int(rev)
This counts backward from the last element in the string version of num, and adds all the elements of num (in reverse order) to rev.
num > 0 is never False. Dividing a positive number by 10 repeatedly makes it smaller, but it never becomes zero, so the while loop keeps repeating.
Use //= instead. It rounds to the nearest integer, so it will reach 0.
This also wouldn't reverse numbers (unless I'm missing something). Alternatively, you can use
int(str(num)[::-1])
which converts the number to a string, reverses it using slicing, and turns it back into an integer.
def countz(n):
if n<10:
if n==0:
return 1
else:
return 0
small=countz(n//10)
if n%10==0:
return small+1
else:
return small
from sys import setrecursionlimit
setrecursionlimit(11000)
n = int(input())
print(countz(n))
Someone helped me write this code, I did not understand why he used the condition n<10 in the base case of the recursion. I though the code would work without that condition but it didn't. Can anyone help me understand why the code is not working without that condition/ what is the real purpose or reason for that condition?
The base case that we want here is indeed n<10, or in words, n is a single digit number.
You might be tempted to choose n==0 as the base case and simply return 1 because it has one zero:
def countz(n):
if n==0:
return 1
small=countz(n//10)
if n%10==0:
return small+1
else:
return small
But that wouldn't work! Why? Consider the input 9, which has no zeroes. This isn't the base case, so we enter the recursive call: small=countz(n//10). n//10 gives 0, so we call countz(0) which returns 1. This is then returned as the answer, even though it should be 0.
The underlying problem is that, by convention, we denote the number zero with one more digit than is actually needed. Ideally it would consist of no digits at all, but that would be a bit impractical in daily life!
Given 1 to 100 numbers, for multiples of 3 it should print "he" ,for multiples of 5 it should print "llo" ,for both multiples of 3 and 5 it should print "hello".
This is what I have:
for i in range (1,100):
if(i%3==0):
print("he")
elif(i%5==0):
print("llo")
elif(i%3==0 and i%5==0):
print("hello")
How would I do this recursively?
How about the code below?
def find_multiples(current, last_num=100):
# Base Case
if current > last_num:
return
result = ""
if current % 3 == 0:
result += "he"
if current % 5 == 0:
result += "llo"
if result:
print(f"{current}: {result}")
find_multiples(current+1, last_num)
find_multiples(1)
Base case is if current reaches last_num or the maximum number you'd like to check.
Here is a general outline for doing simple recursive things in python:
BASE_CASE = 1 #TODO
def f(current_case):
if current_case == BASE_CASE:
return #TODO: program logic here
new_case = current_case - 2 #TODO: program logic here ("decrement" the current_case somehow)
#TODO: even more program logic here
return f(new_case) + 1 #TODO: program logic here
Of course, this doesn't handle all possible recursive programs. However, it fits your case, and many others. You would call f(100), 100 would be current_value, you check to see if you've gotten to the bottom yet, and if so, return the appropriate value up the call stack. If not, you create a new case, which, in your case, is the "decrement" logic normally handled by the "loop" construct. You then do things for the current case, and then call the function again on the new case. This repeated function calling is what makes it "recursive". If you don't have an "if then" at the beginning of the function to handle the base case, and somewhere in the function recall the function on a "smaller" value, you're probably going to have a bad time with recursion.
This recursive function prints multiples of a number! hope it helps
def multi(n,x):
if x == 12:
print(n*x)
else :
print(n*x,end =",")
multi(n,x+1)
print(multi(4,1));
I'm trying to convert below code to recursive function but seems i'm quite confusing how could i write below in recursive function. could help me to give some thoughts?
Basically, what I'm generating below is the sum of the first n odd numbers.
def sum_odd_n(n):
total=0
j=2*n-1
i=1
if i>j:
return 1
else:
total =((j+1)/2)**2
i+=2
return total
> >>> sum_odd_n(5)
> 25.0
> >>> sum_odd_n(4)
> 16.0
> >>> sum_odd_n(1)
> 1.0
This smells somewhat like homework so I'm going to offer some advice instead of a solution.
Recursion is about expressing a problem in terms of itself.
Suppose you know the sum of the odd numbers from N to N - 2.
Can you write the total sum in terms of this sum and the function itself (or a related helper function)?
Recursive functions have at least one base case and at least one recursive call. Here are some hints:
def f(n):
# Base case - for which
# n do we already know the answer
# and can return it without
# more function calls? (Clearly,
# this must also terminate any
# recursive sequence.)
if n == ???:
return ???
# Otherwise, lets say we know the answer
# to f(n - 1) and assign it to
# the variable, 'rest'
rest = f(n - 1)
# What do we need to do with 'rest'
# to return the complete result
return rest + ???
Fill out the question marks and you'll have the answer.
Try:
def sum_of_odd(n):
if n>0:
x=(n*2)-1
return x+sum_of_odd(n-1)
else:
return 0
The answer of this:
sum_of_odd(5)
will be:
25
Try :
def sum_odd_n(n):
if n>0:
if n==1:
return 1
else:
return 2*n-1 + sum_odd_n(n-1)
My parameter, n is a phone number as an integer.
Using recursion I want to return the first three numbers in the integer.
I've turned the integer into a list of individual number characters and I'm attempting to delete the last number over and over again until I'm left with the last three, but I'm stuck on how to repeat it.
def areaCodes(n):
n = str(n)
n = list(n)
del n[-1]
#n = reduce(opperator.add, n)
n = ''.join(n)
n = int(n)
return n
I know I'm supposed to repeat the name in the return somehow, but because n isn't an integer that I can use to repeat. What do I do?
How about something like this?
def areaCodes(n):
# if n is less than 1000, what does it mean about the number of digits?
if n < 1000:
return # fill...
# otherwise, if n is greater than 1000, how can we alter n to remove the last
# digit? (hint: there's an operation similar to division called f...r division)
return areaCodes( # operate on n somehow...)
I assume that this is an exercise where recursion is necessary. If so, try this (there are better ways to accomplish your end goal, but I tried to modify your existing code as little as possible):
def areaCodes(n):
n_lst = list(str(n))
del n_lst[-1]
n_str = ''.join(n_lst)
n_int = int(n_str)
if len(n_lst) > 3:
return areaCodes(n_int)
return n_int
This will call the function again if the length of the number is greater than three, and return the number otherwise. Basically, the only part you were missing in your original function was the following, which is the recursive part:
if len(n_lst) > 3:
return areaCodes(n_int)
Remember that for a function to be recursive, it will have two main attributes:
It will at some point call itself. (this is what makes it 'repeat')
It will have some stopping condition (or base case).
You mentioned #1 when you wrote that you're supposed to use "the name in the return," so that's great! You just need to write that in your code:
return areaCodes(n), Where n is the updated phone number with a digit removed.
As you can see, each recursive call should do some work towards the solution, and should pass its mini-solution to the next recursive call.
Along with #2 above, you need to specify a base case, where the recursion will cease. So, since you're taking away a digit each time you call your function, you should include some kind of check to see if the current input is the length you want yet.
If it is the right length, you're done, and you should return the current number (not another recursive call).
Otherwise, you aren't done with the recursion yet.
import sys
def areaCodes(n):
#Create a list
myList = list(str(n))
#Delete last element
del myList[-1]
#Combine your elements into string list
myListStr = ''.join(myList)
#Type cast to int
myListInt = int(myListSte)
#Check whether your list satisfies your condition
if len(myList) > 3:
#Recusivley call the function again
return areaCodes(myListInt)
#Return your list when recursion completes
return myListInt
n = 12345
print areaCodes(n)