Related
I was trying to get this recursion faster but when I use numbers 50 and 44.4 it takes too long my desired outcome for those numbers is -800555.6302016332
z = int(input())
x = float(input())
def rec(n):
global x
l = {}
if n == 0:
return -1
elif n == 1:
return x
elif n == 2:
return -(x+1)/3
else:
if n in l:
return l[n]
value = float((n/x)*rec(n-1) + ((-1)**n)*((n+1)/(n-1)) * rec(n-2) + ((n-1)/(2*x))*rec(n-3))
l[n] = value
return value
print(rec(z))
You are reinitializing your dictionary l = {} each time you recurse. Making l a global var should fix your problem:
l = {}
def rec(n):
global x
global l
if n == 0:
return -1
elif n == 1:
return x
elif n == 2:
return -(x+1)/3
else:
if n in l:
return l[n]
value = float((n/x)*rec(n-1) + ((-1)**n)*((n+1)/(n-1)) * rec(n-2) + ((n-1)/(2*x))*rec(n-3))
l[n] = value
return value
You could also use functools.lru_cache which does memoization for you:
import functools
#functools.lru_cache
def rec(n):
global x
if n == 0:
return -1
elif n == 1:
return x
elif n == 2:
return -(x+1)/3
else:
return float((n/x)*rec(n-1) + ((-1)**n)*((n+1)/(n-1)) * rec(n-2) + ((n-1)/(2*x))*rec(n-3))
I would also suggest avoiding the use of global variables:
import functools
def rec(n, x):
#functools.lru_cache
def recurse(n):
if n == 0:
return -1
elif n == 1:
return x
elif n == 2:
return -(x+1)/3
else:
return float((n/x)*recurse(n-1) + ((-1)**n)*((n+1)/(n-1)) * recurse(n-2) + ((n-1)/(2*x))*recurse(n-3))
return recurse(n)
def main():
n = int(input())
x = float(input())
print(rec(n, x))
if __name__ == "__main__":
main()
class TN:
def __init__(self,value,left=None,right=None):
self.value = value
self.left = left
self.right = right
def list_to_tree(alist):
if alist == None:
return None
else:
return TN(alist[0],list_to_tree(alist[1]),list_to_tree(alist[2]))
def str_tree(atree,indent_char ='.',indent_delta=2):
def str_tree_1(indent,atree):
if atree == None:
return ''
else:
answer = ''
answer += str_tree_1(indent+indent_delta,atree.right)
answer += indent*indent_char+str(atree.value)+'\n'
answer += str_tree_1(indent+indent_delta,atree.left)
return answer
return str_tree_1(0,atree)
def count(t,value):
nodes = []
num = 0
nodes.append(t)
while len(nodes) > 0:
if nodes[0] == value:
num += 1
next = nodes.pop(0)
count(next,value)
return num
I need to write a recursive function count (other three functions cannot be changed); it is passed balanced binary tree and a value as arguments. It returns the number of times the values is in the tree. In the binary tree below, count(tree,1) returns 1, count(tree,2) returns 2, count(tree,3) returns 4
..1
....3
3
....3
..2
......2
....3
I called the following functions
tree = list_to_tree([3, [2, None, [3, None, None]], [1, [3, None, None], None]])
print('\nfor tree = \n',str_tree(tree))
for i in irange(1,3):
print('count(tree,'+str(i)+') = ', count(tree,i))
but it shows the error that "RecursionError: maximum recursion depth exceeded in comparison"
can someone help me to fix the count function? Thanks in advance.
If you look carefully at your code you'll see that you set up an empty nodes list, fill it with t, so the while loop is always entered you'll always pop t into next and always call the function with precisely the same parameters. That is of course an infinite recursion.
Here is one simple way of setting it up correctly:
def count(tree, number):
if tree is None:
return 0
else:
return (number == tree.value) + count(tree.left, number) \
+ count(tree.right, number)
Another way to go about it is using transversal, in a typical tree there is a root and a node subclass. Your tree is missing that structure so it looks a bit weird. To use transversal I'm using a global var to keep track of the counter.
class TN:
def __init__(self,value,left=None,right=None):
self.value = value
self.left = left
self.right = right
def list_to_tree(alist):
if alist == None:
return None
else:
return TN(alist[0],list_to_tree(alist[1]),list_to_tree(alist[2]))
def str_tree(atree,indent_char ='.',indent_delta=2):
def str_tree_1(indent,atree):
if atree == None:
return ''
else:
answer = ''
answer += str_tree_1(indent+indent_delta,atree.right)
answer += indent*indent_char+str(atree.value)+'\n'
answer += str_tree_1(indent+indent_delta,atree.left)
return answer
return str_tree_1(0,atree)
NUM = 0
def count(t,value):
global NUM
NUM = 0
if t != None:
if t.left == None and t.right == None:
if t.value == value:
return 1
else:
return 0
else:
_count(t, value)
return NUM
def _count(t, value):
if t.left != None:
_count(t.left, value)
if t.value == value:
global NUM
NUM += 1
if t.right != None:
_count(t.right, value)
tree = list_to_tree([3, [2, None, [3, None, None]], [1, [3, None, None], None]])
print(str_tree(tree))
print("count 1", count(tree, 1))
print("count 2", count(tree, 2))
print("count 3", count(tree, 3))
I am solving a puzzle (Finding if there exists an input for a given automata for which no matter what the starting state is, final state would be same everytime) and have written following python code. A few testcases are written in check method in the code. For these cases program is running fairly fast. However, for testcases where 50 lists(nodes) are present, the programis taking forever to execute. I am storing intermediate results to use further as well. Can someone please review the code and give suggestions on how to increase the performance of the code?
from itertools import product
from copy import deepcopy
class Node:
def __init__(self,id):
self.id = id
self.dict = {}
def __str__(self):
return str(id) + " : " + str(self.dict)
def __repr__(self):
return str(id) + " : " + str(self.dict)
def tryDelete(nodes,_len):
for id in nodes:
y = deepcopy(nodes)
x = y[id]
del y[id]
for id,node in y.items():
for input,result in node.dict.items():
if result == x:
if x.dict[input] == x:
node.dict[input] = node
else:
node.dict[input] = x.dict[input]
pass
if pathPossible(y,_len ,False) == -1:
return x.id
return -2
target = {}
def FindTarget(node,p):
if len(p) == 1:
return node.dict[p[0]]
if node not in target or p not in target[node]:
x = FindTarget(node,p[:-1]).dict[p[-1]]
if node not in target:
target[node] = {}
target[node][p] = x
return target[node][p]
def allSatisy(nodes,p):
x = None
for key,node in nodes.items():
if x is None:
x = FindTarget(node,p)
elif FindTarget(node,p) != x:
return False
return True
def allPossiblePaths(l,n):
#x = int(((l+1)*(l+2))/2)
for i in range(1, n+1):
for p in product(range(l),repeat=i):
yield p
def pathPossible(nodes,_len ,isItereate=True):
i = 1
isFound = False
for p in allPossiblePaths(_len,len(nodes)):
if allSatisy(nodes,p):
isFound = True
break
if isFound:
return -1
elif not isItereate:
return -2
else:
return tryDelete(nodes,_len)
def answer(li):
nodes = {}
for i in range(len(li)):
nodes[i] = Node(i)
for i in range(len(li)):
for j in range(len(li[i])):
nodes[i].dict[j] = nodes[li[i][j]]
return pathPossible(nodes,len(nodes[0].dict))
def check(li,ans):
# each item in the list is a node, each item i-th in the inner list tells to what node the transition happens for input i
x = answer(li)
print(str(li) + " : " + str(ans) + " : " + str(x))
def main():
check([[2,1],[2,0],[3,1],[1,0]],-1)
check([[1,2],[1,1],[2,2]],1)
check([[1,3,0],[1,0,2],[1,1,2],[3,3,3]],-1)
if __name__ == '__main__':
main()
UPDATE: I have done few code changes, but still this needs some review from you guys. Changed code:
from itertools import product
from copy import deepcopy
class Node:
def __init__(self,id):
self.id = id
self.dict = {}
def __str__(self):
return str(self.id) + " : " + str(self.dict)
def __repr__(self):
return str(self.id) + " : " + str(self.dict)
def tryDelete(nodes,_len):
for i in range(len(nodes)):
y = nodes[:]
x = y[i]
del y[i]
tNodes = []
for node in y:
for input,result in node.dict.items():
if result == x:
node.tDict = deepcopy(node.dict)
if x.dict[input] == x.id:
node.dict[input] = node
else:
node.dict[input] = x.dict[input]
if pathPossible(y,_len ,False) == -1:
return x.id
for n in tNodes:
n.dict = n.tDict
del n.tDict
return -2
target = {}
def FindTarget(node,p):
if len(p) == 1:
return node.dict[p[0]]
if node not in target or p not in target[node]:
x = Gnodes[FindTarget(node,p[:-1])].dict[p[-1]]
if node not in target:
target[node] = {}
target[node][p] = x
return target[node][p]
def allSatisy(nodes,p):
x = None
for node in nodes:
if x is None:
x = FindTarget(node,p)
elif FindTarget(node,p) != x:
return False
return True
def allPossiblePaths(l,n):
#x = int(((l+1)*(l+2))/2)
for i in range(1, n + 1):
for p in product(range(l),repeat=i):
yield p
def pathPossible(nodes,_len ,isItereate=True):
i = 1
isFound = False
for p in allPossiblePaths(_len,len(nodes)):
if allSatisy(nodes,p):
isFound = True
break
if isFound:
return -1
elif not isItereate:
return -2
else:
return tryDelete(nodes,_len)
Gnodes = []
def answer(li):
Gnodes[:] = []
for i in range(len(li)):
Gnodes.append(Node(i))#[i] = Node(i)
for i in range(len(li)):
for j in range(len(li[i])):
Gnodes[i].dict[j] = li[i][j]
return pathPossible(Gnodes,len(Gnodes[0].dict))
def check(li,ans):
x = answer(li)
print(str(li) + " : " + str(ans) + " : " + str(x))
def main():
check([[2,1],[2,0],[3,1],[1,0]],-1)
check([[1,2],[1,1],[2,2]],1)
check([[1,3,0],[1,0,2],[1,1,2],[3,3,3]],-1)
if __name__ == '__main__':
main()
There is a wonderful graph library called NetworkX. It deals with creating graphs and path finding. You specify what edges or paths exist in your Graph and you can find paths using a plethora of algorithms like breadth first search, or A*, and many others in the algorithms section. The best way to optimize your time is code reuse.
https://networkx.github.io
This is my first time asking a question on here, and I am only doing this because I have spent the past week trying to figure this out and haven't been able to. I found similar questions, but the results did not help me. I have to take an infix expression and calculate the results using two stacks, one for the operator and one for the numbers. An example would be 6 - ( 5 - 3 ) * ( 4 + 2 ) = -6 or 3 * 11 / 8 + 5 – 4 * 7 = -18.875. I just cannot figure out how to get this to work. Currently my code is this:
class NumStack:
def __init__(self):
"""Create an empty stack."""
self._data = [] #nonpublic list instance
def __len__(self):
"""Return the number of elements in the stack."""
return len(self._data)
def is_empty(self):
"""Return True if the stack is empty."""
return len(self._data) == 0
def push(self,e):
"""Add element e to the top of the stack."""
self._data.append(e) #new item stored at end of list
print(self._data)
def top(self):
"""Return (but do not remove) the element at the top of the stack.
Raise Empty exception if the stack is empty"""
if self.is_empty():
return
return self._data[-1] #the last item in the list
def pop(self):
"""Remove and return the element from the top of the stack (i.e, LIFO)
Raise Empty exception if the stack is empty."""
if self.is_empty():
return "empty"
return self._data.pop() #remove last item from list
def str(self):
return self._data
class OperatorStack:
def __init__(self):
"""Create an empty stack."""
self._data = [] #nonpublic list instance
def __len__(self):
"""Return the number of elements in the stack."""
return len(self._data)
def is_empty(self):
"""Return True if the stack is empty."""
length = len(self._data)
if length == 0:
return True
else:
return False
def push(self,e):
"""Add element e to the top of the stack."""
self._data.append(e) #new item stored at end of list
print(self._data)
def top(self):
"""Return (but do not remove) the element at the top of the stack.
Raise Empty exception if the stack is empty"""
if self.is_empty():
return
return self._data[-1] #the last item in the list
def pop(self):
"""Remove and return the element from the top of the stack (i.e, LIFO)
Raise Empty exception if the stack is empty."""
length = len(self)
if length == 0:
print("list is empty")
else:
if self.is_empty():
return
return self._data.pop()
def str(self):
return self._data
def main():
expression = str(input("Enter an expression: "))
expression = expression.split()
print(expression)
N = NumStack()
O = OperatorStack()
new = []
NewOP = []
NewNum = [0,0]
for e in expression:
if e == '(' or e == ')' or e == '+' or e == '-' or e == '*' or e == '/':
O.push(e)
else:
N.push(e)
while O.is_empty() == False or N.is_empty() == False:
TmpOp = O.top()
if TmpOp == ')':
O.pop()
elif TmpOp == '(':
O.pop()
if TmpOp != '(' and TmpOp != ')':
new.append(N.pop())
new.append(O.pop())
print(TmpOp)
while TmpOp == ')':
if N.top() != "empty":
NewNum[1] = N.pop()
if N.top() != "empty":
NewNum[0] = N.top()
print(NewNum[0],NewNum[1])
if O.pop() == '+':
num = float(NewNum[1]) + float(NewNum[0])
new.append(num)
print(num)
O.pop()
break
elif O.pop() == '-':
num = float(NewNum[0]) - float(NewNum[1])
new.append(num)
print(num)
O.pop()
break
elif O.pop() == '*':
num = NewNum[1]*NewNum[0]
new.append(num)
print(num)
# O.pop()
break
elif O.pop() == '/':
num = NewNum[1]/NewNum[0]
new.append(num)
print(num)
# O.pop()
break
if O.top() == ')':
O.pop()
break
if O.__len__() == 0 and N.__len__() == 0:
break
continue
while TmpOp != ')' and TmpOp != '(':
new.append(N.pop())
new.append(O.pop())
print(new)
if O.__len__() == 0 and N.__len__() == 0:
break
print(new)
main()
I believe my classes to be correct, I just cannot find a way of extracting the needed information correctly. I am trying to pop the items into a list and when I get to a parenthesis I go ahead and perform the calculation. If I could just get the correct numbers into my list then I know I can get it to work. I just need to get the "new" to contain the correct numbers. With the problem: "6 - ( 5 - 3 ) * ( 4 + 2 )" I should get [6.0, '*', 2.0, '-', 6]. It is not coming out to that. I really appreciate any help that can be given.
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