Digital sum, Python - python

I need to write a code that counts the sum of the digits of a number, these is the exact text of the problem:The digital sum of a number n is the sum of its digits. Write a recursive function digitalSum(n) that takes a positive integer n and returns its digital sum. For example, digitalSum(2019) should return 12 because 2+0+1+9=12. These is the code I wrote :
def digitalSum(n):
L=[]
if n < 10:
return n
else:
S=str(n)
for i in S:
L.append(int(i))
return sum(L)
These code works fine, but it's not a recursive function, and I'm not allowed to change any int to str. May you help me?

Try this:
def digitalSum(n):
if n < 10 :
return n
return n % 10 + digitalSum( n // 10 )
Edit: The logic behind this algorithm is that for every call of the recursive function, we chop off the number's last digit and add it to the sum. First we obtain the last digit with n % 10 and then we call the function again, passing the number with the last digit truncated: n // 10. We only stop when we reach a one-digit number. After we stop, the sum of the digits is computed in reverse order, as the recursive calls return.
Example for the number 12345 :
5 + digitalSum( 1234 )
5 + 4 + digitalSum( 123 )
5 + 4 + 3 + digitalSum( 12 )
5 + 4 + 3 + 2 + 1 <- done recursing
5 + 4 + 3 + 3
5 + 4 + 6
5 + 10
15

It's homework, so I'm not writing much code. Recursion can be used in the following way:
get the first (or last) digit
format the rest as a shorter number
add the digit and the digital sum of the shorter number (recursion!)

This is more of a question related to algorithms.
Here is your answer:
def digit_sum(a):
if a == 0:
return 0
return a % 10 + digit_sum(a/10)
Let me know if you don't understand why it works and I'll provide an explanation.

Some hints:
You can define inner functions in Python
You can use the modulus operator (look up its syntax and usage) to good effect, here
There's no need to build up an explicit list representation with a proper recursive solution
EDIT The above is a bit "bad" as a general answer, what if someone else has this problem in a non-homework context? Then Stack Overflow fails ...
So, here's how I would implement it, and you need to decide whether or not you should continue reading. :)
def digitalSum(n):
def process(n, sum):
if n < 10:
return sum + n
return process(n / 10, sum + n % 10)
return process(n, 0)
This might be a bit too much, but even in a learning situation having access to one answer can be instructive.
My solution is more a verbose than some, but it's also more friendly towards a tail call optimizing compiler, which I think is a feature.

def digital_sum(number):
if number < 10:
return number
else:
return number % 10 + digital_sum(number / 10)

def sumofdigits(a):
a = str(a)
a = list(a)
b = []
for i in a:
b.append(int(i))
b = sum(b)
if b > 9:
return sumofdigits(b)
else:
return b
print sumofdigits(5487123456789087654)

For people looking non-recursive ways,
Solution 1:
Using formula,
digits = int(input())
res = (digits * (digits + 1) // 2)
Solution 2:
Using basic syntax
numbers = [6, 5, 3, 8, 4, 2, 5, 4, 11]
total = numbers[0]
print(f'{total}')
for val in numbers[1:]:
print(f'{total} + {val} = {total + val}')
total += val
gives
6
6 + 5 = 11
11 + 3 = 14
14 + 8 = 22
22 + 4 = 26
26 + 2 = 28
28 + 5 = 33
33 + 4 = 37
37 + 11 = 48

Still you can do it in O(log10 n)...cancel out all the digits that adds to 9 then if no numbers left,9 is the answer else sum up all the left out digits...
def rec_sum_Reduce(n) :
ans = 0
for i in map(int,str(n)) :
ans = 1+(ans+i-1)%9
return ans

def drs_f(p):
drs = sum([int (q) for q in str(p)])
while drs >= 10:
drs = sum([int(q) for q in str(drs)])
return drs

def digitalSum(n):
if n < 10:
return n
else:
return ???
The 1st part is from your existing code.
The ??? is the part you need to work out. It could take one digit off n and add it to the digitalSum of the remaining digits.
You don't really need the else, but I left it there so the code structure looks the same

Related

Is ther any other way to get sum 1 to 100 with recursion?

I'm studing recursive function and i faced question of
"Print sum of 1 to n with no 'for' or 'while' "
ex ) n = 10
answer =
55
n = 100
answer = 5050
so i coded
import sys
sys.setrecursionlimit(1000000)
sum = 0
def count(n):
global sum
sum += n
if n!=0:
count(n-1)
count(n = int(input()))
print(sum)
I know it's not good way to get right answer, but there was a solution
n=int(input())
def f(x) :
if x==1 :
return 1
else :
return ((x+1)//2)*((x+1)//2)+f(x//2)*2
print(f(n))
and it works super well , but i really don't know how can human think that logic and i have no idea how it works.
Can you guys explain how does it works?
Even if i'm looking that formula but i don't know why he(or she) used like that
And i wonder there is another solution too (I think it's reall important to me)
I'm really noob of python and code so i need you guys help, thank you for watching this
Here is a recursive solution.
def rsum(n):
if n == 1: # BASE CASE
return 1
else: # RECURSIVE CASE
return n + rsum(n-1)
You can also use range and sum to do so.
n = 100
sum_1_to_n = sum(range(n+1))
you can try this:
def f(n):
if n == 1:
return 1
return n + f(n - 1)
print(f(10))
this function basically goes from n to 1 and each time it adds the current n, in the end, it returns the sum of n + n - 1 + ... + 1
In order to get at a recursive solution, you have to (re)define your problems in terms of finding the answer based on the result of a smaller version of the same problem.
In this case you can think of the result sumUpTo(n) as adding n to the result of sumUpTo(n-1). In other words: sumUpTo(n) = n + sumUpTo(n-1).
This only leaves the problem of finding a value of n for which you know the answer without relying on your sumUpTo function. For example sumUpTo(0) = 0. That is called your base condition.
Translating this to Python code, you get:
def sumUpTo(n): return 0 if n==0 else n + sumUpTo(n-1)
Recursive solutions are often very elegant but require a different way of approaching problems. All recursive solutions can be converted to non-recursive (aka iterative) and are generally slower than their iterative counterpart.
The second solution is based on the formula ∑1..n = n*(n+1)/2. To understand this formula, take a number (let's say 7) and pair up the sequence up to that number in increasing order with the same sequence in decreasing order, then add up each pair:
1 2 3 4 5 6 7 = 28
7 6 5 4 3 2 1  = 28
-- -- -- -- -- -- -- --
8 8 8 8 8 8 8 = 56
Every pair will add up to n+1 (8 in this case) and you have n (7) of those pairs. If you add them all up you get n*(n+1) = 56 which correspond to adding the sequence twice. So the sum of the sequence is half of that total n*(n+1)/2 = 28.
The recursion in the second solution reduces the number of iterations but is a bit artificial as it serves only to compensate for the error introduced by propagating the integer division by 2 to each term instead of doing it on the result of n*(n+1). Obviously n//2 * (n+1)//2 isn't the same as n*(n+1)//2 since one of the terms will lose its remainder before the multiplication takes place. But given that the formula to obtain the result mathematically is part of the solution doing more than 1 iteration is pointless.
There are 2 ways to find the answer
1. Recursion
def sum(n):
if n == 1:
return 1
if n <= 0:
return 0
else:
return n + sum(n-1)
print(sum(100))
This is a simple recursion code snippet when you try to apply the recurrent function
F_n = n + F_(n-1) to find the answer
2. Formula
Let S = 1 + 2 + 3 + ... + n
Then let's do something like this
S = 1 + 2 + 3 + ... + n
S = n + (n - 1) + (n - 2) + ... + 1
Let's combine them and we get
2S = (n + 1) + (n + 1) + ... + (n + 1) - n times
From that you get
S = ((n + 1) * n) / 2
So for n = 100, you get
S = 101 * 100 / 2 = 5050
So in python, you will get something like
sum = lambda n: ( (n + 1) * n) / 2
print(sum(100))

10 digit number whose first n digits are divisible by n

So I came upon this little problem and I challenged myself to write my first program to solve it. The problem is to find a 10 digit number, for which if you take the first n digits, the resulting number must be divisible by n (eg. 1236, where 1 is divisible by 1, 12 by 2, 123 by 3 and 1236 by 4). My code is a little clumsy which i don't mind, but I'm getting error messages I don't understand.
from itertools import permutations
oddperm = permutations([1,3,7,9])
evenperm = permutations([2,4,6,8])
for odd in oddperm:
for even in evenperm:
num1 = (even[0]*(10**7)) + (even[1]*(10**5)) + (even[2]*10**3) + (even[3]*10)
num2 = (odd[0]*10**8 )+ (odd[1]*10**6) + (5*10**4) + (odd[2]*10**2) + (odd[3])
num = str((num1+num2)*10)
if (num[0]*10 + num[1]) % 2 == 0 and #etc etc etc and (num[0]*10**8 + num[1]*10**7 + num[2]*10**6 + num[3]*10**5 + 5*10**4 + num[5]*10**3 + num[6]*10**2 + num[7]*10 + num[8]) % 9 == 0:
print(num)
break
else:
continue
The trouble is im getting
TypeError Traceback (most recent call last)
<ipython-input-75-cb75172b012c> in <module>
10 num2 = (odd[0]*10**8 )+ (odd[1]*10**6) + (5*10**4) + (odd[2]*10**2) + (odd[3])
11 num = str((num1+num2)*10)
---> 12 if (num[0]*10 + num[1]) % 2 == 0 and ... and (num[0]*10**8 + num[1]*10**7 + num[2]*10**6 + num[3]*10**5 + 5*10**4 + num[5]*10**3 + num[6]*10**2 + num[7]*10 + num[8]) % 9 == 0:
13 print(num)
14 break
TypeError: not all arguments converted during string formatting
Also if someone has an idea on how to make that line a touch more elegant I'm all ears.
Thanks in advance for any and all contributions!
It looks to me like the error you describe is coming from a type conversion. You are converting num to a string, and then using indexing to get a certain digit of the number (which is fine), but before you can do any math with the digit, you need to convert it back into an int.
# num gets converted to a string
num = str((num1+num2)*10)
# num's digits get converted back into integers
if (int(num[0])*10 + int(num[1])) % 2 == 0:
print(num)
Additionally, to make your checking of each digit more elegant, you can use a for loop and check for failure rather than success. This is an interesting problem so I spent a bit of time on it, haha. The following function can be called in place of the long if (int(num[0])*10 + int(num[1])) % 2 == 0 and ... etc:, changing it to simply if check_num(num):.
def check_num(num:str):
# define powers in advance for convenience
powers = [10**p for p in range(len(num))]
# check that the number satisfies the desired property
place = 1
while place < len(num):
sum = 0
# check each digit
for i in range(place+1):
sum += int(num[i]) * powers[place - i]
# check for failure
if sum % (place+1) != 0:
return False
# check the next place
place += 1
# we made it all the way through
return True
Hope this is enlightening.

Trying to find sum of digits between two numbers

Trying to figure out how to find the sum of digits between two numbers(including those numbers) using a function in python.
I tried recursion for each individual argument and then subtracted them to compensate for the numbers in between. Then I added these two and got my sum, which is incorrect for every argument unless the digits are below 10. Not sure of the proper way to approach this problem, please help.
def sum_digits(a, b):
"""sum of digits between two numbers"""
sum = 0
ones = a - b
if ones < 0:
ones = ones * -1
if a >= 10 and b >= 10:
sum += ones
while a > 0 and b > 0:
d = a % 10 + b % 10
a = a // 10
b = b // 10
sum += d
return sum
def sum_digits(a, b):
sum = 0
for i in range(a,b+1):
for e in (str(i)):
sum += int(e)
return sum
print(sum_digits(17, 20))
Does this work ?
this works basically by getting the numbers within a range. Now since endrange is usually one less, I manually add a 1 to the endrange
startNumber = 1
endNumber = 5
total = 0;
for i in range(startNumber,endNumber+1):
print(i)
total += i
print total
Thanks
Just sum the digit sum for every number from the first argument to the last. For more ways to do each digit sum, see Sum the digits of a number - python
def sum_digits(a, b):
total = 0
for number in range(a,b+1):
total += sum(int(digit) for digit in str(number))
return total
Here you go:
def sum_digits(a, b):
sum = 0
for i in range(a, b + 1):
number = i
while (number > 0):
sum += number % 10
number = number // 10
return sum
print(sum_digits(17, 20))
My approach:
def sum_of_products(lst, s, f):
result = 0
for i, item in enumerate(range(s, f+1)):
lst[i] = list(map(int, str(item)))
result += sum(lst[i])
return result
lst = [x for x in range(0, 10)]
x = sum_of_products(lst, 14, 20)
print(x)
My 2 cents would to point out that there should be a closed-form formula that doesn't involve looping trough the whole range.
For example, we know that the sum of n numbers is
n*(n-1)/2
and for the sum of digits 0 to 9 it is 45 == 9*10/2
01
02
03
04
05
06
07
08
09
then it becomes a bit more complicated for the next 10 numbers:
10
11
12
13
14
15
16
17
18
19
the sum is 10 times the tens(decades) plus 45.
and then we could have:
for 00..09 we have 0*10+45
for 10..19 we have 1*10+45
for 20..29 we have 2*10+45
...
for d0..d9 we have d*10+45
I am too lazy to derive the good formula myself, therefore I Googled it. And below is what I have found:
The formula is simple if we know before hand the number of digits. For example, as per https://oeis.org/A007953 , if the number of n is less than 100 then the closed-form formula is:
For n < 100 equal to (floor(n/10) + n mod 10)
For an arbitrarily large number there is a sample code here: https://www.geeksforgeeks.org/count-sum-of-digits-in-numbers-from-1-to-n/
dsum(10**d - 1) = dsum(10**(d-1) - 1) * 10 + 45*10**(d-1)
to compute the digit sum of a range just find the difference
dsum(b) - dsum(a)

How return works in recursion?

def sum_it(n,y):
if n ==0:
return y
else:
return sum_it(n-1,n+y)
required output for sum_it(3,4)i.e. (3+2+1)+4 must be 10
but obtained output is 5
Please how the return really works ?
Altough unclear, it seems like what you need when calling sum_it(n,y) is the sum of natural numbers from 1 to n plus y.
This initial sum is also known as "nth" triangular number.
If that's the case, you actually don't need recursion:
def sum_it(n,y):
return (n*(n+1))//2 + y
If recursion is a must:
def sum_it(n,y):
if (n > 1):
return n + sum_it(n-1,y)
return n + y
Feel free to ask if any doubt remains.
If you intended to sum like (3+2+1) + 4, this code will works.
def sum_it(n,y):
if( n == 1):
return y + 1
else:
return(n + sum_it(n-1,y))
For example, sum_it(3,4) works like below
sum_it(3,4) returns 3 + sum_it(2,4)
sum_it(2,4) returns 2 + sum_it(1,4)
sum_it(1,4) returns 1 + 4
It means
sum_it(3,4) returns 3 + 2 + 1 + 4

How to added up a variable with multiple values together in Python Recursion Function?

So I was studying recursion function online. And the one question asks me to write a function to add up a number's digits together. For example (1023) -> 1 + 0 + 2 + 3 = 6. I used % and // get get rid of a digit each time. However, I don't know how to add them up together. The closest I can get is to print out each digit. Can anyone help me solve it or give me a hint please?
def digitalSum(n):
if n < 10:
sum_total = n
print(sum_total)
else:
sum_total = n % 10
digitalSum((n - (n % 10))//10)
print(sum_total)
digitalSum(1213)
Your function should return the current digit plus the sum of the rest of the digits:
def digitalSum(n):
if n < 10: return n
return n % 10 + digitalSum(n // 10)
print digitalSum(1213)
For completeness, you can also handle negative numbers:
def digitalSum(n):
if n < 0: sign = -1
else: sign = 1
n = abs(n)
if n < 10: return n
return sign * (n % 10 + digitalSum(n // 10))
print digitalSum(1213)
A correct version of your function is as follows:
from math import log10
def sum_digits(n, i=None):
if i is None:
i = int(log10(abs(n)))
e = float(10**i)
a, b = (n / e), (abs(n) % e)
if i == 0:
return int(a)
else:
return int(a) + sum_digits(b, (i - 1))
print sum_digits(1234)
print sum_digits(-1234)
Example:
$ python -i foo.py
10
8
>>>
Updated: Updated to properly (IHMO) cope with negative numbers. e.g: -1234 == -1 + 2 + 3 + 4 == 8
NB: Whilst this answer has been accepted (Thank you) I really think that perreal's answer should have been accepted for simplicity and clarity.
Also note: that whilst my solution handles negative numbers and summing their respective digits, perreal clearly points out in our comments that there are ate least three different ways to interpret the summing of digits of a negative number.

Categories