问题
I am stuck in this exercise.
Task:
A digital root is the recursive sum of all the digits in a number. Given n, take the sum of the digits of n. If that value has more than one digit, continue reducing in this way until a single-digit number is produced. This is only applicable to the natural numbers.
Here's how it works:
digital_root(16)
1 + 6 = 7
digital_root(942)
9 + 4 + 2 = 15 ... 1 + 5 =6
My approach is here. Any tips on how to properly return correct value? I would appreciate any help.
def digital_root(n):
answ = 0
s = 0
x = str(n)
for i in range(0, len(x)):
s = s + int(x[i])
if len(str(s)) > 1:
digital_root(s)
elif len(str(s)) == 1:
answ = s # here is an answer
return answ # answer is 2 but this one is not returning 2, why?
return answ # here it returns answ=0, I want to return 2...
print(digital_root(493193))
回答1:
The main problem is that, when doing the recursive calls, you're not assigning the return value to anything, so you'll always get 0 for any value that requires more than one pass.
Also, after the recursive call, the length should be 1 so the following elif
is not necessary and will cause incorrect return values since it won't be assigning s
to answ
Fixed version:
def digital_root(n):
answ = 0
s = 0
x = str(n)
for i in range(0, len(x)):
s = s + int(x[i])
if len(str(s)) > 1:
s = digital_root(s)
answ = s # You could even return s directly
return answ
print(digital_root(493193))
回答2:
What do you say about this:
def digital_root(n):
if n<10 :
return n
return digital_root( n%10 + digital_root( n//10 ) )
回答3:
Here is my take on it. I felt the urge to use sum
but that almost feels like cheating since you could just use sum([int(i) for i in str(n)])
.
def digital_root(n):
# convert to a string
as_str = str(n)
# get the value of the current first digit
value = int(as_str[0])
if len(as_str) > 1:
# add the recursive return plus the value
# for anything other than our base case.
# pass the rest of the digits into our recursive call
return digital_root(int(as_str[1:])) + value
# our base case
return value
print(digital_root(493193))
回答4:
You do nothing with the result of your recursive call - thats why your code goes wrong.
Iterating via index is mostly not good - better iterate over the string directly.
This is a cleaner way for recursion using some built in python functions:
def rec_sum(n):
sn = str(n)
# base case - return the number
if len(sn)==1:
return n
# not the base case,return whatever the recursive output returns
return rec_sum(sum(map(int,sn)))
for n in range(1,71):
print(f"{n:3}=>{rec_sum(n):3}", end = "|")
if n%7 == 0:
print()
Output:
1=> 1| 2=> 2| 3=> 3| 4=> 4| 5=> 5| 6=> 6| 7=> 7|
8=> 8| 9=> 9| 10=> 1| 11=> 2| 12=> 3| 13=> 4| 14=> 5|
15=> 6| 16=> 7| 17=> 8| 18=> 9| 19=> 1| 20=> 2| 21=> 3|
22=> 4| 23=> 5| 24=> 6| 25=> 7| 26=> 8| 27=> 9| 28=> 1|
29=> 2| 30=> 3| 31=> 4| 32=> 5| 33=> 6| 34=> 7| 35=> 8|
36=> 9| 37=> 1| 38=> 2| 39=> 3| 40=> 4| 41=> 5| 42=> 6|
43=> 7| 44=> 8| 45=> 9| 46=> 1| 47=> 2| 48=> 3| 49=> 4|
50=> 5| 51=> 6| 52=> 7| 53=> 8| 54=> 9| 55=> 1| 56=> 2|
57=> 3| 58=> 4| 59=> 5| 60=> 6| 61=> 7| 62=> 8| 63=> 9|
64=> 1| 65=> 2| 66=> 3| 67=> 4| 68=> 5| 69=> 6| 70=> 7|
The part sum(map(int,sn))
means: map(function,iterable)
applies the int()
-function to all characters in sn
(strings are iterable) which is the string of your number. Then it sum()
s it up and calls itself with that sum.
回答5:
With recursive functions, it's generally a good idea to start with the most basic case and then incrementally add complexity.
Additionally, a trick that's useful is that taking list()
of a string cuts the string into characters, ergo list("abc")
returns ["a", "b", "c"]
.
Using this, we get:
def digital_root(n):
# basic scenario: n is 1 digit, ergo <10.
if n < 10:
return n
# alternative case: more than 1 digit
# cut n into digits with a list comprehension
# str(714) => "714", list(str(714)) => "['7', '1', '4']
digits = [int(c) for c in list(str(n))]
# take the digital root of the sum
return digital_root(sum(digits))
来源:https://stackoverflow.com/questions/61233330/recursive-sum-of-all-the-digits-in-a-number