Recursive addition/subtraction in python with negative integers - python

I am trying to make a program that adds and subtracts two arguments using recursion. So far my program is working for positive integers but I am completely lost about how I can make this work for negative integers. I would really appreciate your help.
Here is my code so far:
def add(x,y):
"""add takes x and y and adds them together"""
if y == 0:
return x
else:
return add1(add(x, sub1(y)))
def sub(x,y):
"""sub takes x and y and subtracts them"""
if y == 0:
return x
else:
return sub1(sub(x, sub1(y)))
def add1(x):
return x+1
def sub1(x):
return x-1

I'd go with this
def add(x,y):
if y > 0:
return add(x, y-1) + 1
elif y < 0:
return add(x, y+1) - 1
else:
return x
Subtract would be the same idea, but flip the signs
def sub(x,y):
if y > 0:
return sub(x, y-1) - 1
elif y < 0:
return sub(x, y+1) + 1
else:
return x
Testing
>>> add(3,5)
8
>>> add(3,0)
3
>>> add(3,-5)
-2
>>> subtract(8,3)
5
>>> subtract(3,8)
-5
>>> subtract(3,0)
3

In each case you try to get y closer to 0 since y==0 is the base case for your recursion.
If y is positive, you do so by repeatedly subtracting 1.
If y is negative, you repeatedly add 1.
In every case, do "the right thing" to x:
Addition
if x or y is 0, return the other value
if y is positive, add 1 to x, subtract 1 from y: 6 + 2 = 7 + 1 = 8 + 0 = 8
if y is negative, subtract 1 from x, add 1 to y: 6 + (-2) = 5 + (-1) = 4 + 0 = 4
code:
def add(x, y):
if y == 0:
return x
elif x == 0:
return y
elif y > 0:
return add(add1(x), sub1(y))
else:
return add(sub1(x), add1(y))
Subtraction
if y is 0, return x
if y is positive, subtract 1 from x, subtract 1 from y: 6 - 2 = 5 - 1 = 4 - 0 = 4
if y is negative, add 1 to x, add 1 to y: 6 - (-2) = 7 - (-1) = 8 - 0 = 8
code:
def sub(x, y):
if y == 0:
return x
elif y > 0:
return sub(sub1(x), sub1(y))
else:
return sub(add1(x), add1(y))

Related

Python: Print largest even number from 3 inputs without using list and max()

The program first asks for 3 integers then computes for the largest even from the set. It will print None if there are no even numbers. We are not allowed to use built-in functions (like max()) and not allowed to import math libraries.
What code can I use so it does not print None when I input x = 11, y = 11, z = 8? The correct output should be 8.
def getMaximum(x,y,z):
if x >= y and x >= z:
return x
elif y >= x and y >= z:
return y
else:
return z
def getLargestEven(x,y,z):
LargestVal = getMaximum(x,y,z)
if LargestVal%2 == 0:
return LargestVal
elif x%2 == 0 and (x > y or x > z):
return x
elif y%2 == 0 and (y > x or y > z):
return y
elif z%2 == 0 and (z > x or z > y):
return z
else:
return None
x = int(input("Enter x: "))
y = int(input("Enter y: "))
z = int(input("Enter z: "))
print("Largest Even:", getLargestEven(x,y,z))
You can also use a simple loop structure to test for the maximum even number among three
def getLargestEven(x,y,z):
max_num = -99999999999999
for num in [x,y,z]:
if num%2==0:
if num>max_num:
max_num = num
return None if max_num ==-99999999999999 else max_num

Why is (x,y) NoneType?

I'm having problem with my code (Jupyter). Ordered pattern vacuum cleaner with obstacles. I am loading an array from a file (see picture if needed)
Then I have a function:
x_lim = 9
y_lim = 9
def ordered_move(x,y,gulv):
if gulv[x,y] == 0:
if x < 9:
x +=1
return (x,y)
if x == x_lim:
y +=1
return (x,y)
if gulv[x, y] > 0:
x == 0
y += 1
return (x,y)
if x == 9 and y == 9:
x == 6
y == 3
x += 1
return (x,y)
if x == 9 and y == 3:
x == 7
y == 4
x += 1
return (x,y)
if x == 9 and y == 4:
x == 6
y == 5
x += 1
return (x,y)
if x == 9 and y == 5:
x == 7
y == 6
x += 1
return (x,y)
if x == 9 and y == 6:
x == 6
y == 7
x += 1
return (x,y)
and then I use the code in:
x = 0
y = 0
time = 0
dust_in_room = 100
dust_removed = 0
time_passed_vec = []
dust_in_room_vec = range(100)
while dust_in_room > 7:
if array_from_file[x,y] == -1:
dust_in_room -= 1
array_from_file[x,y] = -2
time_passed_vec = time_passed_vec + [time]
dust_removed +=1
print(time)
time += 1
(x,y)=ordered_move(x,y,array_from_file)
I get the Type Error
"cannot unpack non-iterable NoneType object"
in the last line.
As you can tell from the code I am new to python, so maybe you are able to help with a simple explanation. Thank you.
The explanation is that none of the if conditions is verified.
If a function ends without a return statement the result is like if there was a return None.

2 counter variables in for loop are not working for equal to condition

Problem Description:
Given an array arr[] of size N and two elements x and y, use counter
variables to find which element appears most in the array, x or y. If
both elements have the same frequency, then return the smaller
element.
Note: We need to return the element, not its count.
My solution:
def MajorityWins(arr, n, x, y):
countX = 0
countY = 0
for i in arr:
if i==x:
countX+=1
if i==y:
countY+=1
if countX>countY:
return x
if countY>countX:
return y
if countX==countY:
if x>y:
return x
else:
return y
n=11
arr=[1,1,2,2,3,3,4,4,4,4,5]
x=4
y=5
print(MajorityWins(arr, n, x, y))
The correct output is 4.
But the output of my program is 5.
When I don't use the condition countX==countY, the outputs are correct.
When I add if countX==countY, all the other conditions are ignored.
Can someone tell me the solution to this please?
What #Sayse said was absolutely correct. You need to flip the > around. But another problem you have it you return while iterating through your list. This can cause problems later on, so please indent it backward so it no on the same indentation level as your loop.
for i in arr:
if i==x:
countX+=1
if i==y:
countY+=1
if countX>countY:
return x
if countY>countX:
return y
if countX==countY:
if x<y:
return x
else:
return y
If both elements have the same frequency, then return the smaller element.
Your code does the exact opposite of this. If x is greater than y, then you need to return y and vice versa
if countX==countY:
if x>y:
return y
else:
return x
If you put a print statement in the loop and you will see what is happening. At the end of the loop countX has a value of 4, countY has a value of 1. 4 is larger than 1 so the value of x is returned.
def MajorityWins(arr, n, x, y):
countX = 0
countY = 0
for i in arr:
if i==x:
countX+=1
if i==y:
countY+=1
print(i, countX, countY)
if countX>countY:
result = x
elif countY>countX:
result = y
elif countX==countY:
if x<y:
result = x
else:
result = y
return result
n=11
arr=[1,1,2,2,3,3,4,4,4,4,5]
x=4
y=5
print(f"Result: {MajorityWins(arr, n, x, y)}")
Output:
1 0 0
2 0 0
2 0 0
3 0 0
3 0 0
4 1 0
4 2 0
4 3 0
4 4 0
5 4 1
Result: 4

Python3 sorted function checking the same conditions twice

I want to sort an array of numbers and return the largest number in string format.
For example:
Array = [5,1,9,30]
should return
'95301'
I have the following code that accomplishes it
class LargestKey(str):
def __lt__(x, y):
print("x",x,"y",y, x+y > y+x)
return x+y > y+x
class Largest():
def largestNumber(self, nums):
mapResult = map(str, nums)
num = ''.join(sorted(mapResult, key=LargestKey))
testNum = Largest()
print(testNum.largestNumber([5,1,9,30]))
According to the print in the LargestKey function, the output is:
x 1 y 5 False
x 9 y 1 True
x 9 y 1 True
x 9 y 5 True
x 30 y 5 False
x 30 y 1 True
95301
I don't understand why the checking with x = 9 and y = 1 is happening twice

Division using recursion

I am pretty sure that this must be some glaringly stupid mistake by me. But can anyone explain what is wrong in this division code using recursion. I know there are a lot of alternatives, but I need to know what is wrong with this
def division(a, b):
x = 0
if a < b:
return x
else:
x += 1
return division(a - b, b)
return x
When I do division(10, 2), it gives me 0 as output
You always set your local variable x to 0.
Then if the dividend is smaller than the divisor you return that x which is of course 0.
On the other hand when the dividend is greater or equal to the divisor you increment x by 1 and do a recursive call with a decremented dividend which will of course lead to the first case at the end and still you return an x which holds the value of 0.
Note: Nonetheless your final return is not reachable since both your if and else branch contains a return.
So please try considering this solution:
def division(a, b):
if a < b:
return 0
else:
return 1 + division(a-b, b)
Update:
A possible solution for working with negative integers following python's round towards negative infinity division:
def division_with_negatives(a, b):
a_abs, b_abs = abs(a), abs(b)
if (a >= 0 and b >= 0) or (a < 0 and b < 0):
# branch for positive results
if a_abs < b_abs:
return 0
else:
return 1 + division_with_negatives(a_abs - b_abs, b_abs)
else:
# branch for negative results
if b_abs > a_abs or a_abs == b_abs:
return -1
else:
return -1 + division_with_negatives(a_abs - b_abs, -b_abs)
assert division_with_negatives(-4, 1) == -4 // 1
assert division_with_negatives(10, 2) == 10 // 2
assert division_with_negatives(1, -5) == 1 // -5
assert division_with_negatives(-3, -2) == -3 // -2
This might save you from RecursionError:
def div(x, y):
if y == 0:
return 0
elif x == y:
return 1
elif x < y:
if y * -1 == x:
return -1
elif x % y == 0:
return 1 + div(x - y, y)
else:
return 0
else:
if y < 0:
return 1 - div(x - y, -y)
else:
return 1 + div(x - y, y)
#Application
A = div(1, 2)
B = div(-9, 9)
C = div(3, 2)
D = div(-9, -3)
E = div(100, -2)
print(A) # 0
print(B) # -1
print(C) # 1
print(D) # 3
print(E) # -50
Your escape condition is if a < b. That means that for this function to terminate, this must be fulfilled to leave the recursion. However, because x is declared at the top of the function, only redefined inside the body of the else statement but never returned, the function will always terminate with a value of x = 0.
You should either set x = 1 + division(a-b,b) or return division(a-b,b) + 1 and remove the unreachable returnat the end.
def div(a, b, x):
if a < b:
return x
else:
x +=1
return div(a - b, b, x)
print(div(130, 10, 0))
# 13
This might work a little better for you:
def division(a,b,x=0):
if a < b:
return x
else:
x += 1
return division(a-b,b,x)
return x
Every time your function ran through a new recusion, you were setting x to 0. This way, it defaults to 0 if x is not specified, and should work like I think you want.
Also note that this will not work for negative numbers, but you probably knew that :)
With global you get:
def division(a,b):
global x
if a < b: return x
else:
x += 1
return division(a-b,b)
x=0
print (division(10,2))
But you have to set x to zero every time before call the division
i think this is best way, this way u can get floating answer also
def division(a,b):
if a == 0 or a == 1 or a == 2:
return b
else:
return a / division(a % b,b)
print(division(9,2))

Categories

Resources