Recursive function to reduce zeros from number - python

I have a mission to write a recursive function named Reduce. This function should reduce all the zeros from number and return new number.
for example:
Reduce(-160760) => -1676
Reduce(1020034000) => 1234
I started to to something but I got stuck in the condition. here's the code I wrote so far:
def Reduce(num):
while num != 0:
if num % 10 != 0:
newNum = (num % 10) +
Reduce(num//10)

def reduce(num):
if num == 0: return 0
if num < 0: return -reduce(-num)
if num % 10 == 0:
return reduce(num // 10)
else:
return num % 10 + 10 * reduce(num // 10)

String version of recursive function:
def reduce(n):
return int(reduce_recursive(str(n), ''))
def reduce_recursive(num, res):
if not num: # if we've recursed on the whole input, nothing left to do
return res
if num[0] == '0': # if the character is '0', ignore it and recurse on the next character
return reduce_recursive(num[1:], res)
return reduce_recursive(num[1:], res+num[0]) # num[0] is not a '0' so we add it to the result and we move to the next character
>>> reduce(1200530060)
12536

Related

How to solve this "Jumping numbers" task

Implement the is_jumping function, which accepts the number number and returns the string JUMPING, if each digit in the number differs from the adjacent one by 1. If the condition is not met - the string NOT JUMPING.
def is_jumping(number: int) -> str:
newStr = str(number)
for i in range(len(newStr)):
if len(newStr) == 1:
return "JUMPING"
elif int(newStr[i + 1]) - int(newStr[i]) == 1:
return "JUMPING"
else: return "NOT JUMPING"
AssertionError: assert is_jumping(12543) == "NOT JUMPING", ( "Function 'is_jumping' should return 'NOT JUMPING' " "when number is 12543" )
Where is a problem? why can not pass number 12543? Thank you!
UPD
According to your advice I made some change, but still it doesn't work. Any chance to make my code work?
def is_jumping(number: int) -> str:
newStr = str(number)
for i in range(len(newStr) - 1):
if int(newStr[i + 1]) - int(newStr[i]) != 1 or int(newStr[i + 1]) - int(newStr[i]) != -1:
return "NOT JUMPING"
return "JUMPING"
#Michael Butscher #bbbbbbbbb #Johnny
Problems in your code already explained in the comment section.
Regardless, no need to convert your input number to a string; try this:
def is_jumping(num: int) -> str:
while num >= 10:
x = num % 10
num //= 10
if num % 10 not in [x - 1, x + 1]:
return "NOT JUMPING"
return "JUMPING"

Find if a number is divisible by another number using recursion

How would I check if a number is divisible by another using recursion in python?
This is my code so far, but I would like to make it recursive.
def is_divisable(num, div):
if num % div == 0:
return True
else:
False
For educational purposes, you could keep subtracting until you reach 0 or below:
def is_divisible(num, div):
while(num > 0):
num -= div
return num == 0
Using this logic you can make it recursive (Thanks to Anonymous for pointing out the above version is not recursive):
def is_divisible(num, div):
if (num == 0):
return True
elif (num < 0):
return False
return is_divisible(num-div, div)
However, the correct way would be:
def is_divisible(num, div):
return num % div == 0
def is_divisable(num,div):
if num<div:
return num %div==0
else:
return is_divisable(num-div,div)

How to generate alternating substrings using recursion

I have a practice question that requires me to generate x number of alternating substrings, namely "#-" & "#--" using both recursion as well as iteration. Eg.string_iteration(3) generates "#-#--#-".
I have successfully implemented the solution for the iterative method,
but I'm having trouble getting started on the recursive method. How can I proceed?
Iterative method
def string_iteration(x):
odd_block = '#-'
even_block = '#--'
current_block = ''
if x == 0:
return ''
else:
for i in range(1,x+1):
if i % 2 != 0:
current_block += odd_block
elif i % 2 == 0:
current_block += even_block
i += 1
return current_block
For recursion, you almost always just need a base case and everything else. Here, your base case it pretty simple — when x < 1, you can return an empty string:
if x < 1:
return ''
After than you just need to return the block + the result of string_iteration(x-1). After than it's just a matter of deciding which block to choose. For example:
def string_iteration(x):
# base case
if x < 1:
return ''
blocks = ('#--', '#-')
# recursion
return string_iteration(x-1) + blocks[x % 2]
string_iteration(5)
# '#-#--#-#--#-'
This boils down to
string_iteration(1) + string_iteration(2) ... string_iteration(x)
The other answer doesn't give the same result as your iterative method. If you always want it to start with the odd block, you should add the block on the right of the recursive call instead of the left:
def string_recursion(x):
odd_block = '#-'
even_block = '#--'
if x == 0:
return ''
if x % 2 != 0:
return string_recursion(x - 1) + odd_block
elif x % 2 == 0:
return string_recursion(x - 1) + even_block
For recursive solution, you need a base case and calling the function again with some other value so that at the end you will have the desired output. Here, we can break this problem recursively like - string_recursive(x) = string_recursive(x-1) + string_recursive(x-2) + ... + string_recursive(1).
def string_recursion(x, parity):
final_str = ''
if x == 0:
return ''
if parity == -1: # when parity -1 we will add odd block
final_str += odd_block
elif parity == 1:
final_str += even_block
parity *= -1 # flip the parity every time
final_str += string_recursion(x-1, parity)
return final_str
odd_block = '#-'
even_block = '#--'
print(string_recursion(3, -1)) # for x=1 case we have odd parity, hence -1
# Output: #-#--#-

'None' is printed when I want 'True' for input 5

In this primality test program, 'None' is printed when I input a prime, instead of 'True'. How can I get it to print 'True'?.
def main():
import math
def check_n(n):
n_s = int(math.sqrt(n))
for i in range(2, n_s):
if (n_s % i) == 0:
return False
break
else:
return True
def msg():
n = int(input('Enter a number, I will return True if it is a prime'))
return n
print(check_n(msg()))
main()
You need to change int(math.sqrt(n)) to int(math.sqrt(n)+1), because range runs until n_s-1. So if the input is 5, range(2,int(math.sqrt(5))) is just range(2,2), which is empty.
In addition, you need to take the return True outside of the for loop, otherwise your code may stop in a too early stage. You also don't need the break statement after return False (the function will never arrive to that line, as it will return False if it enters to that if statement).
Finally, change if (n_s % i) == 0: to if (n % i) == 0:, as you need to check if n is divisible by i (and not its square root).
Here is a more clean version:
import math
def check_n(n):
n_s = int(math.sqrt(n)+1)
for i in range(2, n_s):
if (n % i) == 0:
return False
return True
def msg():
n = int(input('Enter a number, I will return True if it is a prime'))
return n
print(check_n(msg()))
First: Your break statement is redundant.
Second: For values such as 3 the for loop is never executing because value
n_s is less than 2 and since the for loop isn't executing the
python is returning the default value None(which is returned when
no value is specified).
Hence your check_n(n) function has to be
def check_n(n):
n_s = int(math.sqrt(n))
for i in range(2, n_s + 1):
if (n_s % i) == 0:
return False
return True
one liner :
check_n = lambda n : sum([i for i in range(2, int(math.sqrt(n)+1)) if n % i == 0]) == 0
don't overcomplicate things ..
Your range is (2,2) or None when you choose anything less than 9.
So to solve your first problem: add 2 to n_s (for input 3)
You also have a problem with your logic.
Your for loop should be checking that n mod i is 0, not n_s.
This should work:
def main():
import math
def check_n(n):
n_s = int(math.sqrt(n)+1)
for i in range(2, n_s):
if (n % i) == 0:
return False
return True
def msg():
n = int(input('Enter a number, I will return True if it is a prime'))
return n
print(check_n(msg()))
main()

Convert between str and int without using built-in typecasting

NB: You may not use built-in typecasting: code this yourself.
def str2int(s):
result = 0
if s[0] == '-':
sign = -1
i = 1
while i < len(s):
num = ord(s[i]) - ord('0')
result = result * 10 + num
i += 1
result = sign * result
return result
else:
i = 0
while i < len(s):
num = ord(s[i]) - ord('0')
result = result * 10 + num
i += 1
return result
NB: You may not use built-in str() or string template. Code this yourself.
def int2str(i):
strng = ""
if i > 0:
while i != 0:
num = i % 10
strng += chr(48+num)
i = i / 10
return strng[::-1]
else:
while i != 0:
num = abs(i) % 10
strng += chr(48+num)
i = abs(i) / 10
return '-' + strng[::-1]
I am a newbie and I have to write code based on basic. I write these function by myself but these look weird. Can you help me to improve code? Thank you
This maybe a better question for https://codereview.stackexchange.com/.
Not withstanding there is no error checking, one obvious comment is you have common code that can be factored out. Only capture in the if, else what is unique rather than repeat the while loop:
def str2int(s):
if s[0] == '-':
sign = -1
i = 1
else:
sign = 1
i = 0
result = 0
while i < len(s):
num = ord(s[i]) - ord('0')
result = result * 10 + num
i += 1
return sign * result
It is generally considered better form in python to iterate over list rather than indices:
def str2int(s):
sign = 1
if s[0] == '-':
sign = -1
s = s[1:]
result = 0
for c in s:
num = ord(c) - ord('0')
result = result * 10 + num
return sign * result
These last lines are equivalent to a standard map and reduce (reduce is in functools for py3). Though some would argue against it:
from functools import reduce # Py3
def str2int(s):
sign = 1
if s[0] == '-':
sign = -1
s = s[1:]
return sign * reduce(lambda x,y: x*10+y, map(lambda c: ord(c) - ord('0'), s))
There are similar opportunities to do the same for int2str().

Categories

Resources