This question already has an answer here:
Why Python recursive function returns None [duplicate]
(1 answer)
Closed 2 years ago.
I have a recursive function, I have no idea why the result printed in main is always None.
def find_nega(A: list, start: int, right: int) -> int :
s = start
r = right
mid = (s + r) // 2
if (s >= r):
return None
if (A[mid] == 0):
return mid - 1
if (A[s] < 0 and A[r] >= 0 and s == r - 1):
print(s)
return s
if (A[mid] < 0):
s = mid
find_nega(list1, s, r)
elif (A[mid] > 0):
r=mid
find_nega(list1, s,r)
else:
return mid
if __name__ == "__main__":
list1 = [-3,-2,-1,4,5,6]
x = find_nega(list1, 0, len(list1) - 1)
print(x)
In this example, it enters the condition A[s] < 0 and A[r] >= 0 and s == r - 1 but don't know why it doesn't print 2.
It doesn't print 2 because you don't return the value when you call the recursion. Here it works
def find_nega(A: list, start: int, right: int) -> int:
print(A, start, right)
s = start
r = right
mid = (s + r) // 2
if s >= r:
return None
if A[mid] == 0:
return mid - 1
if A[s] < 0 and A[r] >= 0 and s == r - 1:
#print(s)
return s
if A[mid] < 0:
s = mid
return find_nega(list1, s, r)
elif A[mid] > 0:
r = mid
return find_nega(list1, s, r)
else:
return mid
if __name__ == "__main__":
list1 = [-3, -2, -1, 4, 5, 6]
x = find_nega(list1, 0, len(list1) - 1)
print(x)
Related
This question already has answers here:
Why Python recursive function returns None [duplicate]
(1 answer)
Recursive function does not return specified value
(2 answers)
Closed 1 year ago.
I have written a maze solver program. I want the PathFinder function to return True if a path is found and then print the path or else simply return False. But my program always keeps returning False even if a path is found. It would be great if you guys can help me figure this out.
def findPaths(m,path,i,j):
r,c = len(m), len(m[0])
if i == r-1 and j == c-1:
print(path)
return True
#explore
path.append(m[i][j])
# move down
if i != r-1 and m[i+1][j] == '↓ ':
findPaths(m,path,i+2,j)
#move up
if i < 0 and m[i-1][j] == '↑ ':
findPaths(m,path,i-2,j)
#move right
if j != c-1 and m[i][j+1] == '→':
findPaths(m,path,i,j+2)
#move left
if j > 0 and m[i][j-1] == '←':
findPaths(m,path,i,j-2)
path.pop()
def maze(r,c):
m = []
for i in range(r):
row = []
for j in range(1, c + (c)):
rand_num = str(randint(1, 99))
if j % 2 != 0:
if len(rand_num) == 1:
row.append(' ' + rand_num)
else:
row.append(rand_num)
else:
row.append('?')
m.append(row)
up_left_count = r * c // 3
down_right_count = r * c * 2 // 3
for v in range(r + (r - 1)):
vertical_lst = []
for each in range(1, c + c):
if each % 2 == 0:
vertical_lst.append(' ')
else:
vertical_lst.append('? ')
if v % 2 != 0:
m.insert(v, vertical_lst)
idx_i = []
idx_j = []
idx_v_i = []
idx_v_j = []
for i in range(len(m)):
for j in range(len(m[0])):
if i % 2 == 0 and j % 2 != 0:
idx_i.append(i)
idx_j.append(j)
for v_i in range(len(m)):
for v_j in range(len(m[0])):
if v_i % 2 != 0 and v_j % 2 == 0:
idx_v_i.append(v_i)
idx_v_j.append(v_j)
idx_i = list(set(idx_i))
idx_j = list(set(idx_j))
idx_v_i = list(set(idx_v_i))
idx_v_j = list(set(idx_v_j))
for count in range(up_left_count):
i_int = randint(0, len(idx_i) - 1)
j_int = randint(0, len(idx_j) - 1)
if m[i_int][j_int] != '←':
m[idx_i[i_int]][idx_j[j_int]] = '←'
for count_v in range(up_left_count):
i_v_int = randint(0, len(idx_v_i) - 1)
j_v_int = randint(0, len(idx_v_j) - 1)
if m[i_v_int][j_v_int] != '↑':
m[idx_v_i[i_v_int]][idx_v_j[j_v_int]] = '↑ '
for i in range(len(m)):
for j in range(len(m[0])):
if i % 2 == 0 and j % 2 != 0:
if m[i][j] == '?':
m[i][j] = '→'
for i in range(len(m)):
for j in range(len(m[0])):
if i % 2 != 0 and j % 2 == 0:
if m[i][j] != '↑ ':
m[i][j] = '↓ '
m[0][0] = "S"
m[-1][-1] = "D"
for i in range(len(m)):
for j in range(len(m[0])):
print(m[i][j], end=" ")
print()
path = []
return findPaths(m, path, 0,0)
if maze(5,6):
print('True')
else:
print('False')
This code returns only the position of the target.
I need to compute number of steps also.
How can I modify this code to achieve my goal?
def binary_search(arr, low, high, x):
if high >= low:
mid = (high + low) // 2
if arr[mid] == x:
return mid
elif arr[mid] > x:
return binary_search(arr, low, mid - 1, x)
else:
return binary_search(arr, mid + 1, high, x)
else:
return -1
LT = [1,2,3,4,5,6,7,8,9,10]
pos = binary_search(LT,0,9,5)
print(str(pos))
You could add it as a function parameter and update recursively
def binary_search(arr, low, high, x, steps = 0):
if high >= low:
mid = (high + low) // 2
if arr[mid] == x:
print(f"found at {steps} steps")
return mid
elif arr[mid] > x:
return binary_search(arr, low, mid - 1, x, steps + 1)
else:
return binary_search(arr, mid + 1, high, x, steps + 1)
else:
return -1
Binary search code in Python without recursion :
def binary_search_itr(arr, size, val,step=0):
ln=0
r = size-1
mid = (ln + r) // 2
while (arr[mid] != val and ln <= r):
if val < arr[mid]:
step = step + 1
r = mid - 1
else:
step = step + 1
ln = mid + 1
mid = (ln + r) // 2
if arr[mid] == val:
step = step + 1
return mid,step
return -1
LT = [1,2,3,4,5,6,7,8,9,10]
pos = binary_search_itr(LT,9,9)
print(pos)
I need a little help with the code below, I have been tasked with changing the insertion sort to use the given binary search function.
def binarySearch(aList, start, end, value):
#Return the position where value is or should be inserted.
while start <= end:
mid = (start + end) // 2
if aList[mid] == value:
return mid
if value < aList[mid]:
end = mid - 1
else:
start = mid + 1
return start
def insertionSort(aList):
#Sort aList in ascending order.
for index in range(1, len(aList)):
key = aList[index]
pos = index
while pos > 0 and aList[pos - 1] > key:
aList[pos] = aList[pos - 1]
pos = pos - 1
aList[pos] = key
The code I am using to test the function is:
numbers = [71, 32, 22, 19, 18, 1, 15, 40]
insertionSort(numbers)
print(numbers)
Any help is appreciated as I am having a mind blank
def binary_search(arr, val, start, end):
if start == end: #折半到最后start和end可能会相等,递归退出条件之一
if arr[start] > val:
return start
else:
return start+1
if start + 1 == end: #折半到最后start和end相差1,递归退出条件之一
return start+1
mid = (start+end)//2
if arr[mid] < val:
return binary_search(arr,val,mid, end)
elif arr[mid] > val:
return binary_search(arr, val, start, mid)
else:
return mid #折半遇到mid值与val相等,递归退出条件之一
def insertion_sort(arr:list):
for i in range(1, len(arr)):
if arr[i] <= arr[0]:
index = 0
elif arr[i] >= arr[i-1]:
continue
else:
index = binary_search(arr[0:i],arr[i],0, i-1)
arr = arr[:index]+ [arr[i]] + arr[index:i] + arr[i+1:]
return arr
arr = [30,20,80,40,50,10,60,70,90]
insertion_sort(arr)
If I have 2 numbers in binary form as a string, and I want to add them I will do it digit by digit, from the right most end. So 001 + 010 = 011
But suppose I have to do 001+001, how should I create a code to figure out how to take carry over responses?
bin and int are very useful here:
a = '001'
b = '011'
c = bin(int(a,2) + int(b,2))
# 0b100
int allows you to specify what base the first argument is in when converting from a string (in this case two), and bin converts a number back to a binary string.
This accepts an arbitrary number or arguments:
>>> def bin_add(*bin_nums: str) -> str:
... return bin(sum(int(x, 2) for x in bin_nums))[2:]
...
>>> x = bin_add('1', '10', '100')
>>> x
'111'
>>> int(x, base = 2)
7
Here's an easy to understand version
def binAdd(s1, s2):
if not s1 or not s2:
return ''
maxlen = max(len(s1), len(s2))
s1 = s1.zfill(maxlen)
s2 = s2.zfill(maxlen)
result = ''
carry = 0
i = maxlen - 1
while(i >= 0):
s = int(s1[i]) + int(s2[i])
if s == 2: #1+1
if carry == 0:
carry = 1
result = "%s%s" % (result, '0')
else:
result = "%s%s" % (result, '1')
elif s == 1: # 1+0
if carry == 1:
result = "%s%s" % (result, '0')
else:
result = "%s%s" % (result, '1')
else: # 0+0
if carry == 1:
result = "%s%s" % (result, '1')
carry = 0
else:
result = "%s%s" % (result, '0')
i = i - 1;
if carry>0:
result = "%s%s" % (result, '1')
return result[::-1]
Can be simple if you parse the strings by int (shown in the other answer). Here is a kindergarten-school-math way:
>>> def add(x,y):
maxlen = max(len(x), len(y))
#Normalize lengths
x = x.zfill(maxlen)
y = y.zfill(maxlen)
result = ''
carry = 0
for i in range(maxlen-1, -1, -1):
r = carry
r += 1 if x[i] == '1' else 0
r += 1 if y[i] == '1' else 0
# r can be 0,1,2,3 (carry + x[i] + y[i])
# and among these, for r==1 and r==3 you will have result bit = 1
# for r==2 and r==3 you will have carry = 1
result = ('1' if r % 2 == 1 else '0') + result
carry = 0 if r < 2 else 1
if carry !=0 : result = '1' + result
return result.zfill(maxlen)
>>> add('1','111')
'1000'
>>> add('111','111')
'1110'
>>> add('111','1000')
'1111'
It works both ways
# as strings
a = "0b001"
b = "0b010"
c = bin(int(a, 2) + int(b, 2))
# as binary numbers
a = 0b001
b = 0b010
c = bin(a + b)
you can use this function I did:
def addBinary(self, a, b):
"""
:type a: str
:type b: str
:rtype: str
"""
#a = int('10110', 2) #(0*2** 0)+(1*2**1)+(1*2**2)+(0*2**3)+(1*2**4) = 22
#b = int('1011', 2) #(1*2** 0)+(1*2**1)+(0*2**2)+(1*2**3) = 11
sum = int(a, 2) + int(b, 2)
if sum == 0: return "0"
out = []
while sum > 0:
res = int(sum) % 2
out.insert(0, str(res))
sum = sum/2
return ''.join(out)
def addBinary(self, A, B):
min_len, res, carry, i, j = min(len(A), len(B)), '', 0, len(A) - 1, len(B) - 1
while i>=0 and j>=0:
r = carry
r += 1 if A[i] == '1' else 0
r += 1 if B[j] == '1' else 0
res = ('1' if r % 2 == 1 else '0') + res
carry = 0 if r < 2 else 1
i -= 1
j -= 1
while i>=0:
r = carry
r += 1 if A[i] == '1' else 0
res = ('1' if r % 2 == 1 else '0') + res
carry = 0 if r < 2 else 1
i -= 1
while j>=0:
r = carry
r += 1 if B[j] == '1' else 0
res = ('1' if r % 2 == 1 else '0') + res
carry = 0 if r < 2 else 1
j -= 1
if carry == 1:
return '1' + res
return res
#addition of two binary string without using 'bin' inbuilt function
numb1 = input('enter the 1st binary number')
numb2 = input("enter the 2nd binary number")
list1 = []
carry = '0'
maxlen = max(len(numb1), len(numb2))
x = numb1.zfill(maxlen)
y = numb2.zfill(maxlen)
for j in range(maxlen-1,-1,-1):
d1 = x[j]
d2 = y[j]
if d1 == '0' and d2 =='0' and carry =='0':
list1.append('0')
carry = '0'
elif d1 == '1' and d2 =='1' and carry =='1':
list1.append('1')
carry = '1'
elif (d1 == '1' and d2 =='0' and carry =='0') or (d1 == '0' and d2 =='1' and
carry =='0') or (d1 == '0' and d2 =='0' and carry =='1'):
list1.append('1')
carry = '0'
elif d1 == '1' and d2 =='1' and carry =='0':
list1.append('0')
carry = '1'
else:
list1.append('0')
if carry == '1':
list1.append('1')
addition = ''.join(list1[::-1])
print(addition)
Not an optimal solution but a working one without use of any inbuilt functions.
# two approaches
# first - binary to decimal conversion, add and then decimal to binary conversion
# second - binary addition normally
# binary addition - optimal approach
# rules
# 1 + 0 = 1
# 1 + 1 = 0 (carry - 1)
# 1 + 1 + 1(carry) = 1 (carry -1)
aa = a
bb = b
len_a = len(aa)
len_b = len(bb)
min_len = min(len_a, len_b)
carry = 0
arr = []
while min_len > 0:
last_digit_aa = int(aa[len(aa)-1])
last_digit_bb = int(bb[len(bb)-1])
add_digits = last_digit_aa + last_digit_bb + carry
carry = 0
if add_digits == 2:
add_digits = 0
carry = 1
if add_digits == 3:
add_digits = 1
carry = 1
arr.append(add_digits) # will rev this at the very end for output
aa = aa[:-1]
bb = bb[:-1]
min_len -= 1
a_len_after = len(aa)
b_len_after = len(bb)
if a_len_after > 0:
while a_len_after > 0:
while carry == 1:
if len(aa) > 0:
sum_digit = int(aa[len(aa) - 1]) + carry
if sum_digit == 2:
sum_digit = 0
carry = 1
arr.append(sum_digit)
aa = aa[:-1]
else:
carry = 0
arr.append(sum_digit)
aa = aa[:-1]
else:
arr.append(carry)
carry = 0
if carry == 0 and len(aa) > 0:
arr.append(aa[len(aa) - 1])
aa = aa[:-1]
a_len_after -= 1
if b_len_after > 0:
while b_len_after > 0:
while carry == 1:
if len(bb) > 0:
sum_digit = int(bb[len(bb) - 1]) + carry
if sum_digit == 2:
sum_digit = 0
carry = 1
arr.append(sum_digit)
bb = bb[:-1]
else:
carry = 0
arr.append(sum_digit)
bb = bb[:-1]
else:
arr.append(carry)
carry = 0
if carry == 0 and len(bb) > 0:
arr.append(bb[len(bb) - 1])
bb = bb[:-1]
b_len_after -= 1
if carry == 1:
arr.append(carry)
out_arr = reversed(arr)
out_str = "".join(str(x) for x in out_arr)
return out_str
This question already has answers here:
Why does my recursive function return None?
(4 answers)
Closed 7 months ago.
I think I did everything correctly, but the base case return None, instead of False if the value does not exists. I cannot understand why.
def binary_search(lst, value):
if len(lst) == 1:
return lst[0] == value
mid = len(lst)/2
if lst[mid] < value:
binary_search(lst[:mid], value)
elif lst[mid] > value:
binary_search(lst[mid+1:], value)
else:
return True
print binary_search([1,2,4,5], 15)
You need to return the result of the recursive method invocation:
def binary_search(lst, value):
#base case here
if len(lst) == 1:
return lst[0] == value
mid = len(lst)/2
if lst[mid] < value:
return binary_search(lst[:mid], value)
elif lst[mid] > value:
return binary_search(lst[mid+1:], value)
else:
return True
And I think your if and elif condition are reversed. That should be:
if lst[mid] > value: # Should be `>` instead of `<`
# If value at `mid` is greater than `value`,
# then you should search before `mid`.
return binary_search(lst[:mid], value)
elif lst[mid] < value:
return binary_search(lst[mid+1:], value)
Because if return nothing!
if lst[mid] < value:
binary_search(lst[:mid], value)
# hidden return None
elif lst[mid] > value:
binary_search(lst[mid+1:], value)
# hidden return None
else:
return True
You need to return from if and elif too.
def binary_search(lst, value):
#base case here
if len(lst) == 1:
return lst[0] == value
mid = len(lst) / 2
if lst[mid] < value:
return binary_search(lst[:mid], value)
elif lst[mid] > value:
return binary_search(lst[mid+1:], value)
else:
return True
>>> print binary_search([1,2,4,5], 15)
False
Binary Search:
def Binary_search(num,desired_value,left,right):
while left <= right:
mid = (left + right)//2
if desired_value == num[mid]:
return mid
elif desired_value > num[mid]:
left = mid + 1
else:
right = mid - 1
return -1
num =[12,15,19,20,22,29,38,41,44,90,106,397,399,635]
desired_value = 41
result = Binary_search(num,desired_value,0,len(num)-1)
if result != -1:
print("Number found at " + str(result),'th index')
else:
print("number not found")
def rBinarySearch(list,element):
if len(list) == 1:
return element == list[0]
mid = len(list)/2
if list[mid] > element:
return rBinarySearch( list[ : mid] , element )
if list[mid] < element:
return rBinarySearch( list[mid : ] , element)
return True
def binary_search(lists,x):
lists.sort()
mid = (len(lists) - 1)//2
if len(lists)>=1:
if x == lists[mid]:
return True
elif x < lists[mid]:
lists = lists[0:mid]
return binary_search(lists,x)
else:
lists = lists[mid+1:]
return binary_search(lists,x)
else:
return False
a = list(map(int,input('enter list :').strip().split()))
x = int(input('enter number for binary search : '))
(binary_search(a,x))
def binary_search(arr, elm):
low, high = 0, len(arr) - 1
while low <= high:
mid = (high + low) // 2
val = arr[mid]
if val == elm:
return mid
elif val <= elm:
low = mid + 1
else:
high = mid - 1
return -1
print(binary_search([2, 3, 4, 6, 12, 19, 20, 21], 12)) # 4
print(binary_search([2, 3, 4, 6, 12, 19, 20, 21], 3333)) # -1
def Binary_search(li, e, f, l):
mid = int((f+l)/2)
if li[mid] == e:
print("Found",li[mid] )
elif f == l-1 and li[mid] != e:
print("Not Found ")
elif e < li[mid]:
Binary_search(li, e, f,mid)
elif e > li[mid]:
Binary_search(li, e, mid,l)
elements = [1,2,4,6,8,9,20,30,40,50,60,80,90,100,120,130,666]
Binary_search(elements, 120, 0, len(elements))
class binar_search:
def __init__(self,arr , element):
self.arr = arr
self.element = element
def search(self):
n = len(self.arr)
low = 0
high = n-1
while(low <= high):
mid = (low+high)//2
if self.arr[mid] == self.element:
return mid
elif self.arr[mid] < self.element:
low = mid+1
else:
high = mid -1
return 0