I'm attempting to create a function that will sum all the digits
and will return the sum of the summarized number.
Example:
For Input getNumValue(1589)
The Output will be: 5
Becuase: 1 + 5 + 8 + 9 = 23
And 2 + 3 = 5
So the output will be 5
Because we can't split it into more digits.
I did managed to create a recursion function that summarize the digits:
def getNumValue(number: int):
if number == 0:
return 0
return (number % 10 + getNumValue(int(number / 10)))
But I can't seem to utilize it to my cause.
Btw
I don't want to use any strings
And I'm trying to use recursion so far no luck.
I bet this is a known mathematic problem I'm just unfamiliar with.
Any advice?
Even shorter:
def getNumValue(number: int): return ((number-1) % 9) + 1
The digit sum is always in the same remainder class mod 9 as the original decimal number, this applies recursively, and thus reducing it to one digit just is the remainder under division by 9.
The shift by 1 just serves the purpose that the remainder class 0 is represented by 9.
you can make a final check before returning the answer.
def getNumValue(number: int):
if number == 0:
return 0
answer = (number % 10 + getNumValue(int(number // 10)))
if answer < 10:
return answer
return getNumValue(answer)
print(getNumValue(15899999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999))
OUTPUT :
9
You can check if number is greater than 9. If yes, then call the function again:
def getNumValue(number: int):
if number == 0:
return 0
j=(number % 10 + getNumValue(int(number // 10)))
if j>9:
return getNumValue(j)
return j
print(getNumValue(getNumValue(1589)))
Without recursion:
def getNumValue(number: int) -> int:
while True:
total = 0
while number:
total += number % 10
number //= 10
number = total
if total <= 9:
return total
>>> getNumValue(number)
5
pythonic recursion :)
def getNumValue(number=1589):
ans = number % 10 + getNumValue(int(number / 10)) if number else 0
return getNumValue(ans) if ans > 10 else ans
output
5
Related
I have this problem I did the positive but what about if it is a negative number and need to sum? Please help.
Question: Write a function called sum_digits.
Given a number, sum_digits returns the sum of all its digits.
output = sum_digits(1148)
print(output) # --> 14
If the number is negative, the first digit should count as negative.
output = sum_digits(-316)
print(output) # --> 4
Notes:
In order to use some of the methods that will be most helpful to you, you will most likely want to do some string to number conversion and vice versa.
Below is my function:
def sum_digits(num):
num_str = str(num)
num_sum = 0
for i in num_str:
dig = int(i)
num_sum += dig
return num_sum
If parsing number to string is okay with you solution this simple should be okay.
In [1]: def sum_digits(x):
...: x = str(x)
...: if x[0] == '-':
...: return sum(map(int, [x[:2], *x[2:]]))
...: return sum(map(int, x))
In [2]: sum_digits(1148)
Out[2]: 14
In [3]: sum_digits(-316)
Out[3]: 4
One-liner just because:
sum(map(int, num[1:])) + (int(num[0]) if num[0] != '-' else int(num[0:2]) * 2)
This assumes num is a string, otherwise convert it to a string before using the above.
num = str(num)
No need for string conversion. This works for positive and negative integers:
def sum_digits(num):
if num < 0:
return -sum_digits(-num)
elif not num:
return 0
else:
return num % 10 + sum_digits(num // 10)
If recursion isn't on the menu:
def sum_digits(num):
factor, num, total = -1 if num < 0 else 1, abs(num), 0
while num:
total += num % 10
num = num // 10
return total * factor
Edit: someone pointed out you may only want the first digit subtracted, instead of having the result be negative, i.e. -316 as -3 + 1 + 6 instead of -(3 + 1 + 6). If you do indeed want to subtract the first digit if the number is negative:
def sum_digits(num):
factor, num, total = -1 if num < 0 else 1, abs(num), 0
while num:
total += num % 10 if num > 10 else factor * num
num = num // 10
return total
For the first 2 examples, the result for -316 would be -10, for the last, the result would be 4.
>>> def sum_digits(num):
... negative = num < 0 # returns Boolean of if number is negative or not
... if negative:
... value_1 = int(str(num)[1]) # get the first numerical digit i.e. in -35, 3
... num = str(abs(num)) # convert to modulus of number and to string
... num_sum = sum(int(i) for i in num) # sum of all the digits i.e. -35 = 8
... if negative:
... num_sum = num_sum - 2*value_1 # subtract 2*the first numerical digits i.e 8-(2*3) = 2
...
... return num_sum
...
>>> """test cases"""
>>> print(sum_digits(316))
10
>>> print(sum_digits(-316))
4
A simple and logical solution
Just add an if-statement to deal with the negative case.
def sum_digits(num):
num_str = str(num)
num_sum = 0
# Check if number is negative (first char is negative sign)
if num_str[0] == "-":
# If so, subtract first digit then remove the first two chars
num_sum -= int(num_str[1])
num_str = num_str[2:]
# Number is now positive, so can deal with it accordingly
for i in num_str:
dig = int(i)
num_sum += dig
return num_sum
output = sum_digits(1148)
print(output) # --> 14
output = sum_digits(-316)
print(output) # --> 4
I think such a simple problem should not be solved using str/int conversions, slices and other complex instruments. So, that's my solution:
def sum_digits(num: int) -> int:
is_negative = num < 0
num = abs(num)
num_sum = 0
while num > 10:
num_sum += num % 10
num = num // 10
if is_negative:
num_sum -= num % 10
else:
num_sum += num % 10
return num_sum
I was working on a problem that determines whether the digits in the numbers are in the increasing sequence. Now, the approach I took to solve the problem was, For instance, consider the number 5678.
To check whether 5678 is an increasing sequence, I took the first digit and the next digit and the last digit which is 5,6,8 and substitute in range function range(first,last,(diff of first digit and the next to first digit)) i.e range(5,8+1,abs(5-6)).The result is the list of digits in the ascending order
To this problem, there is a constraint saying
For incrementing sequences, 0 should come after 9, and not before 1, as in 7890. Now my program breaks at the input 7890. I don't know how to encode this logic. Can someone help me, please?.
The code for increasing sequence was
len(set(['5','6','7','8']) - set(map(str,range(5,8+1,abs(5-6))))) == 0
You can simply check if the number, when converted to a string, is a substring of '1234567890':
str(num) in '1234567890'
you could zip the string representation of the number with a shifted self and iterate on consecutive digits together. Use all to check that numbers follow, using a modulo 10 to handle the 0 case.
num = 7890
result = all((int(y)-int(x))%10 == 1 for x,y in zip(str(num),str(num)[1:]))
I would create a cycling generator and slice that:
from itertools import cycle, islice
num = 5678901234
num = tuple(str(num))
print(num == tuple(islice(cycle(map(str, range(10))), int(num[0]), int(num[0]) + len(num))))
This is faster than solutions that check differences between individual digits. Of course, you can sacrifice the length to make it faster:
def digits(num):
while num:
yield num % 10
num //= 10
def check(num):
num = list(digits(num))
num.reverse()
for i, j in zip(islice(cycle(range(10)), num[0], num[0] + len(num)), num):
if i != j:
return False
return True
Since you already have the zip version, here is an alternative solution:
import sys
order = dict(enumerate(range(10)))
order[0] = 10
def increasing(n):
n = abs(n)
o = order[n % 10] + 1
while n:
n, r = divmod(n, 10)
if o - order[r] != 1:
return False
o = order[r]
return True
for n in sys.argv[1:]:
print n, increasing(int(n))
Here's my take that just looks at the digits and exits as soon as there is a discrepancy:
def f(n):
while (n):
last = n % 10
n = n / 10
if n == 0:
return True
prev = n % 10
print last, prev
if prev == 0 or prev != (last - 1) % 10:
return False
print f(1234)
print f(7890)
print f(78901)
print f(1345)
Somehow this question got me thinking of Palindromes and that got me to thinking of this in a different way.
5 6 7 8
8 7 6 5
-------------
13 13 13 13
9 0 1
1 0 9
---------
10 0 10
9 0 1 2
2 1 0 9
-------------
11 1 1 11
And that leads to this solution and tests.
pos_test_data = [5678, 901, 9012, 9012345678901]
neg_test_data = [5876, 910, 9021]
def monotonic_by_one(n):
fwd = str(n)
tgt = ord(fwd[0]) + ord(fwd[-1])
return all([ord(f) + ord(r) in (tgt, tgt - 10) for f, r in zip(fwd, reversed(fwd))])
print("Positive: ", all([monotonic_by_one(n) for n in pos_test_data]))
print("Negative: ", all([not monotonic_by_one(n) for n in neg_test_data]))
Results:
Positive: True
Negative: True
Instead of using to full list comprehension you could use a for loop and bail out at the first failure. I'd want to look at the size of the numbers being checked and time somethings to decide which was faster.
I would try this, a little verbose for readability:
seq = list(input())
seq1 = seq[1:]
seq2 = seq[:-1]
diff = [x-y for x,y in zip([int(x) if int(x)>0 else 10 for x in seq1],[int(x) if int(x)>0 else 10 for x in seq2])]
if any (t != 1 for t in diff) :
print('not <<<<<')
else :
print('<<<<<<')
A simple solution that checks the next number in the sequence and then using current_number + 1 == next_number to detect sequence.
import bisect
def find_next(x, a):
i = bisect.bisect_right(x, a)
if i:
return x[i]
return None
def is_sequence(x):
ans = True
for i in x[:-1]:
next_num = find_next(x, i)
if next_num and i+1 != next_num:
ans = False
break
return ans
print(is_sequence([1,2,3,4])) # True
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)
I am trying to make a program that finds primes numbers for a public-key cryptography system. I know that a prime number is a positive integer that has no positive divisors other than 1 and itself. I want to use an approach that that takes all integers from 2 to sqrt(n), to tell if it divides n or not.
I have to take a "brute force" approach that takes in an integer input seed and returns the lowest prime number; prime number >= seed.
Some examples of what I want is :
>>> prime_func(100)
101
>>> prime_func(1000)
1009
>>>prime_func(7)
7
>>>prime_func(3)
5
What I have so far is:
def prime_func(number):
START = 2
END = (number**0.5) + 1
for i in range(START, END):
if number % i == 0:
return('Composite')
else:
return number
For the return ('Composite') part, I want it to instead return the closest prime number after that.
Try the following code:
def prime_func(number):
number = int(number)
START = 2
END = int((number**0.5)) + 1
if number == 2:
return 1
if number == 1:
return 0
while True:
flag = True
for i in range(START, END):
if number % i == 0:
flag = False
break
if flag:
return number
else:
number += 1
if __name__ == '__main__':
num = int(input())
print(prime_func(num))
Input: 100
Output: 101
Input: 1000
Output: 1009
This can be achieved using a Sieve of Eratosthenes.
Code:
def primes_sieve(limit):
a = [True] * limit # Initialize the primality list
a[0] = a[1] = False
for (i, isprime) in enumerate(a):
if isprime:
yield i
for n in range(i*i, limit, i): # Mark factors non-prime
a[n] = False
for value in primes_sieve(32):
print(value)
Output:
2
3
5
7
11
13
17
19
23
29
31
See This Post.
So I know that this is something simple that can be done without a recursion function but I need to know the backside to this as I can't seem to figure out how to write this using recursion. im using this so far
n = int(raw_input("What is n? "))
def digit(n):
if n< 10:
return 1
else:
new = n/10
print 1 + digit(new/10)
return 1 + digit(new/10)
digit(n)
Now if I type in a number such as 33 then it outputs 2 but if I do a longer number then it doesn't print it properly and I was unsure as to what exactly it wrong with it.
The problem is,
new = n/10
return 1 + digit(new/10)
You are already dividing the number by 10, in new = n / 10, which reduces the last digit and you are again dividing it by 10 before calling digit. So, you are ignoring 1 digit in every recursive call.
Instead, you can simply do
return 1 + digit(n / 10)
or
new = n / 10
return 1 + digit(new)
#!/usr/bin/python
n = int(raw_input("What is n? "))
def digit(n):
if n < 10:
return 1
else:
return 1 + digit(n/10)
print digit(n)
You can do like this too.
def counter(number):
if(number == 0):
return 0
return counter(int(number/10)) + 1
number = 1998
print(counter(number)) // it will print 4