def digit_sum(n):
'''(int)->number
Returns the sum of all the digits in the given integer, n'''
if n<10:
return n
return n%10 + digit_sum(n//10)
def digital_root(n):
'''(int)->number
Returns the resulting sum of the digits in the given integer until it reaches a single digit number; via digit_sum'''
while n>9:
n=sum(digit_sum(n))
return n
Wrote the code for digit_sum and then used recursion to write digital_root. How would I go about this? Any help is appreciated!
Wikipedia lists a simple O(1) formula for the digital root:
def digit_root(n):
return (n - 1) % 9 + 1
This does not take into account an input less than 1, so you can modify as follows, with the assumption that the input is a whole number:
def digit_root(n):
return (n - 1) % 9 + 1 if n else 0
Examples:
>>> digit_root(1)
1
>>> digit_root(11)
2
>>> digit_root(235)
1
So the idea is that you have to use recursion for the last one as well? In that case, this should do the job:
def digital_root(n):
if n < 10:
return n
return digital_root(digit_sum(n))
Try this:
def num(n) :
sum = 0 #provided sum as 0
for i in str(n):
a = int(n) % 10 #taken variable a
sum = sum + a #put the sum.
n = n/10
print(sum)
if sum < 10:
print(str(sum) + "=this is a digital root")
else:
num(sum)
please try the following code:
def dgtl_rt(n):
return n%9 or n and 9
print(dgtl_rt(123))
def droot(a):
while a>=10:
b =int(a/10) #other digit(s)
c =a-(b*10) #the rightmost digit
a =b+c #add together
return a
I have not seen this solution anywhere, so I thought it would be nice to share, i discovered it myself! Just 1 looping structure.
{def MDR(n):
'''
this function returns multiplicative digital root.
'''
count, mdr = 0, n
while mdr > 9:
m, digitsMul = mdr, 1
while m:
m, md = divmod(m, 10)
digitsMul *= md
mdr = digitsMul
count += 1
return count, mdr}
Related
I've got a question- how do I write a function sum_even_factorials that finds the sum of the factorials of the even numbers that are less than or equal to n.
Eg:
sum_even_factorials(1)=
1
sum_even_factorials (3)=
3
sum_even_factorials (6)=
747
This is my current code:
Is there a logical error in the current code?
Is there a logical error in the current code?
To begin with, function sum_even_factorial doesn't return a value in every execution flow:
if cond1:
return val1
elif cond2:
return val2
else: # this part is missing in your code
return val3
In addition, note that when you call this function, you are not doing anything with the value that it returns:
sum_even_factorial(6)
Finally, although parts of your code are not visible in your question, I tend to guess that you cannot recursively compute the factorials of even numbers the way you did it, because the factorial of an even number n depends on the factorial of the odd number n - 1.
I think the code needs a loop. I'd write it like so:
def factorial(n):
if n == 0 or n == 1:
return 1;
else:
return n * factorial(n-1)
def sum_even_factorial(n):
current_sum = 0
while n >= 0:
if n % 2 == 0:
current_sum += factorial(n)
n -= 1
return current_sum
print(sum_even_factorial(6))
If you return tuples from the function, you can do it with one single function. See the comments in the code on how it works ...
def factorial_with_sum(n):
if n < 2:
return 1, 0 # first item of the tuple is the factorial, second item is the sum
else:
f, s = factorial_with_sum(n - 1) # calc factorial and sum for n - 1
f = f * n # factorial = n * factorial (n - 1)
if n % 2 == 0:
s = s + f # if n is even, add the current factorial to the sum
return f, s
fact, sum = factorial_with_sum(6)
print(fact)
print(sum)
You can also do it iteratively with a simple for loop as follows
def factorial_with_sum_iterative(n):
s = 0 # initialize sum
f = 1 # and factorial
for i in range(2, n + 1): # iterate from 2 to n
f = f * i # calculate factorial for current i
if i % 2 == 0:
s = s + f # if current i is even, add it to sum
return f, s
Example : If my input is 582109 , the output should be (5+8+2+1+0+9)+(8+2+1+0+9)+(2+1+0+9)+(1+0+9)+(0+9)+(9)=25+20+12+10+9+9=85
Code:
def getSum(n):
sum = 0
while (n != 0):
sum = sum + int(n % 10)
n = int(n/10)
return sum
n = int(input("Number : "))
print(getSum(n))
This code is just giving sum of all digits in input. how to make it calculate the sum of sum of digits in cyclic order as mentioned in example?
Try this:
def add_digits(string):
result = 0
for i in range(len(string)):
for char in string[i:]:
result += int(char)
return result
print(add_digits("582109"))
To prevent interating over the digits twice, you can account for the number of times each digit appears in the final sum:
def getSum(n):
n_string = str(n)
sum, mult = 0, 1
for c in n_string:
sum += mult * int(c)
mult += 1
return sum
getSum(582109)
Here's another solution using the same algorithm as Dallan's answer but as a comprehension using enumerate, and with some inspiration from TheOneMusic's answer:
def add_digits_cyclic(digits):
return sum(i * int(c) for i, c in enumerate(digits, 1))
print(add_digits_cyclic('582109')) # -> 85
Trying to write a piece of code that will sum the digits of a number. Also I should add that I want the program to keep summing the digits until the sum is only 1 digit.
For example, if you start with 1969, it should first add 1+9+6+9 to get 25. Since the value 25 has more than a single digit, it should repeat the operation to obtain 7 as a final answer.
Was just wondering how I could pull this off and possibly make it recursive as well. This is what I have so far
def sum_digits3(n):
r = 0
while n:
r, n = r + n % 10, n // 10
return r
Convert back and forth between strings and ints, make use of sum().
>>> def foo(n):
n = str(n)
if len(n) == 1:
return int(n)
return foo(sum(int(c) for c in n))
>>> foo(1969)
7
>>>
def foo(n):
n = str(n)
if len(n) == 1:
return int(n)
return foo(sum(int(c) for c in n))
It is as simple as involving explicitly the recursion.
def sum_digits3(n):
r = 0
while n:
r, n = r + n % 10, n // 10
if len(str(r))>1:
return sum_digits3(r)
return r
But i must admit that i am going to read the links given by suspicious dog. And the answer of wwii is smarter than mine.
def digit_sum(n):
if n==0 or n==1:
return n
else:
return n+digit_sum(n-1)
def digital_root(n):
if n<10:
return n
else:
return digit_sum((n // 10) + n % 10)
I am trying to use digit_sum to calculate the sum of digits of digital_root can someone help me please. I am trying to use a recursive function for digital_root.
Running the file in Python shell:
digital_root(1969)
This should calculate 1+9+6+9=25 then since 25 is greater than 10 it should then calculate the sum of its digits 2+5 so that the final answer is 7.
To get the last digit of a (positive integer) number you can calculate the modulo:
last_digit = n % 10
The remainder of the number (excluding the last place) is:
rest = (n - last_digit) / 10
This should in theory be enough to split a number and add the digits:
def sum_digits(n):
if n < 10:
return n
else:
last_digit = n % 10
rest = n // 10
# or using divmod (thanks #warvariuc):
# rest, last_digit = divmod(n, 10)
return last_digit + sum_digits(rest)
sum_digits(1969) # 25
If you want to apply this recursivly until you have a value smaller than 10 you just need to call this function as long as that condition is not fulfilled:
def sum_sum_digit(n):
sum_ = sum_digit(n)
if sum_ < 10:
return sum_
else:
return sum_sum_digit(sum_)
sum_sum_digit(1969) # 7
Just if you're interested another way to calculate the sum of the digits is by converting the number to a string and then adding each character of the string:
def sum_digit(n):
return sum(map(int, str(n)))
# or as generator expression:
# return sum(int(digit) for digit in str(n))
If you really require a recursive solution without using any loops (for, while) then you can always recurse again to ensure a single digit:
def digital_root(n):
if n < 10:
return n
a, b = divmod(n, 10)
b += digital_root(a)
return digital_root(b)
>>> digital_root(1969)
7
Or you could just not recurse at all:
def digital_root(n): # n > 0
return 1+(n-1)%9
>>> digital_root(1969)
7
try this...
digitSum = 0
solution = 0
S = raw_input()
S = list(map(int, S.split()))
#print S
for i in S:
digitSum += i
#print digitSum
singleDigit = len(str(digitSum)) == 1
if singleDigit == True: solution = digitSum
while singleDigit == False:
solution = sum( [ int(str(digitSum)[i]) for i in range( 0, len(str(digitSum))) ] )
digitSum = solution
singleDigit = len(str(solution)) == 1
print(solution)
import sys
def keepsumming(number):
numberlist = []
for digit in str(number):
numberlist.append(int(digit))
total = reduce(add, numberlist)
if total > 9:
keepsumming(total)
if total <= 9:
return total
def add(x,y):
return x+y
keepsumming(sys.argv[1])
I want to create a function that adds the individual digits of any number, and to keep summing digits until the result is only one digit. (e.g. 1048576 = 1+0+4+8+5+7+6 = 31 = 3+1 = 4). The function seems to work in some laces but not in others. for example:
$python csp39.py 29
returns None, but:
$python csp39.py 30
returns 3, as it should...
Any help would be appreciated!
As others have mentioned, the problem seems to be with the part
if total > 9:
keepsumming(total) # you need return here!
Just for completeness, I want to present you some examples how this task could be solved a bit more elegantly (if you are interested). The first also uses strings:
while number >= 10:
number = sum(int(c) for c in str(number))
The second uses modulo so that no string operations are needed at all (which should be quite a lot faster):
while number >= 10:
total = 0
while number:
number, digit = divmod(number, 10)
total += digit
number = total
You can also use an iterator if you want to do different things with the digits:
def digits(number, base = 10):
while number:
yield number % base
number //= base
number = 12345
# sum digits
print sum(digits(number))
# multiply digits
from operator import mul
print reduce(mul, digits(number), 1)
This last one is very nice and idiomatic Python, IMHO. You can use it to implement your original function:
def keepsumming(number, base = 10):
if number < base:
return number
return keepsumming(sum(digits(number, base)), base)
Or iteratively:
def keepsumming(number, base = 10):
while number >= base:
number = sum(digits(number, base))
UPDATE: Thanks to Karl Knechtel for the hint that this actually is a very trivial problem. It can be solved in one line if the underlying mathematics are exploited properly:
def keepsumming(number, base = 10):
return 1 + (number - 1) % (b - 1)
There's a very simple solution:
while number >= 10:
number = sum(divmod(number, 10))
I am fairly sure you need to change
if total > 9:
keepsumming(total)
into
if total > 9:
return keepsumming(total)
As with most recursive algorithms, you need to pass results down through returning the next call.
and what about simply converting to string and summing?
res = 1234567
while len(str(res)) > 1 :
res = sum(int(val) for val in str(res))
return res
Thats's what I use to do :)
Here is a clean tail-recursive example with code that is designed to be easy to understand:
def keepsumming(n):
'Recursively sum digits until a single digit remains: 881 -> 17 -> 8'
return n if n < 10 else keepsumming(sum(map(int, str(n))))
Here you go:
>>> sumdig = (lambda recurse: (lambda fix: fix(lambda n: sum(int(c) for c in str(n)))) (recurse(lambda f, g: (lambda x: (lambda d, lg: d if d == lg else f(f,g)(d))(g(x),x)))))(lambda f: lambda x: f(f,x))
>>> sumdig(889977)
3
You are sure to get full, if not extra, credit for this solution.
Your code as currently written need to replace the recursive call to keepsumming(total) with return keepsumming(total); python does not automatically return the value of the last evaluated statement.
However, you should note that your code has redundancies.
for digit in str(number):
numberlist.append(int(digit))
total = reduce(add, numberlist)
should become
from operator import add
total = reduce(add, (int(digit) for digit in str(number)))
A code golf-able version that doesn't require a while loop, or recursion.
>>> import math
>>> (lambda x: sum(int((x * 10 ** -p) % 10) for p in range(math.ceil(math.log(x, 10)))))(1048576)
31
This is probably what I'd use though.
def sum_digits(number):
return sum(
int(number * (10 ** -place) % 10)
for place in range(math.ceil(math.log(number, 10)))
)
It's easier to see what's going on if you append to a list instead of summing the integer values.
def show_digits(number):
magnitude = int(math.log(number, 10))
forms = []
for digit_place in range(magnitude + 1):
form = number * (10 ** -digit_place) # force to one's place
forms.append(form)
return forms
>>> show_digits(1048576)
[1048576, 104857.6, 10485.76, 1048.576, 104.8576, 10.48576, 1.048576]
For keepsumming that takes a string:
def keepsumming(number):
return number if len(number) < 2 \
else keepsumming(str(sum(int(c) for c in number)))
For keepsumming that takes a number:
def keepsumming(number):
return number if number < 10 \
else keepsumming(sum(int(c) for c in str(number)))