-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcodechallenge_035.py
155 lines (126 loc) · 3.96 KB
/
codechallenge_035.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
'''
Date: 10/18/2019
Problem description:
===================
This problem was asked by Microsoft.
Suppose an arithmetic expression is given as a binary tree. Each leaf is an integer and each internal node is one of '+', '−', '∗', or '/'.
Given the root to such a tree, write a function to evaluate it.
For example, given the following tree:
*
/ \
+ +
/ \ / \
3 2 4 5
You should return 45, as it is (3 + 2) * (4 + 5).
Algorithm:
==========
!!! WARNING: This is a complex, time consuming interview question.
Assume the tree is not ballanced. Hence, expect expressions such as 3*4+5 or 3-2+4+5 or 3*4+5*6.
The root determines where to place the parenthesis.
Topdown tasks:
On whiteboard, make the assumption that the rooted tree exists (to save time)
1. Retrieve
2. Parse
3. Evaluate
Here, we have to construct the tree, fill it before we can get the answer out.
1. Construct class Tree
2. Fill
3. Retrieve
4. Parse
5. Evaluate
Input: a rooted tree containing a mathematical expression
Output: A numer
Pseudo code:
1. Construct a root tree class including insert method
2. Write a function to traverse and return a string representing the mathematical expression
3. Import modules SymPy [https://docs.sympy.org/latest/tutorial/manipulation.html#understanding-expression-trees]
4. Write a function to evaluate the string expression
'''
import sympy
import ast
import operator as op
class Tree:
def __init__(self, item, left=None, right=None):
self.item = item
self.right = right
self.left = left
def insert(self, item, ):
if self.item:
# left branches
if self.left is None:
self.left = Tree(item)
else:
self.left.insert(item)
# right branches
if self.right is None:
self.right = Tree(item)
else:
self.right.insert(item)
else:
# root
self.item = item
def tree_to_str(self, mystr=""):
if self.left:
self.left.tree_to_str(mystr)
mystr += str(self.item)
if self.right:
self.right.tree_to_str(mystr)
return mystr
def parse_assemble_str(mystr):
# expect mystr === 3+4*5+6
# transform to subs = {a:3, b:4, c:5, d:6}
# and ops = "(a + b) * (c + d)"
s_cnt = 0
o_cnt = 0
symbols = "abcdefghijklmnopqrstuvwxyz"
sub_str = ""
for char in mystr:
if char.isdigit():
sub_str += symbols[s_cnt]
sub_str += ':'
sub_str += str(char)
sub_str += ','
s_cnt += 1
if char.ispace:
pass
if char.isalpha():
ops_str += str(char) + symbols[o_cnt]
sub_str
# supported operators
operators = {ast.Add: op.add, ast.Sub: op.sub, ast.Mult: op.mul,
ast.Div: op.truediv, ast.Pow: op.pow, ast.BitXor: op.xor,
ast.USub: op.neg}
def eval_(node):
if isinstance(node, ast.Num): # <number>
return node.n
elif isinstance(node, ast.BinOp): # <left> <operator> <right>
return operators[type(node.op)](eval_(node.left), eval_(node.right))
elif isinstance(node, ast.UnaryOp): # <operator> <operand> e.g., -1
return operators[type(node.op)](eval_(node.operand))
else:
raise TypeError(node)
def eval_expr(expr):
"""
>>> eval_expr('2^6')
4
>>> eval_expr('2**6')
64
>>> eval_expr('1 + 2*3**(4^5) / (6 + -7)')
-5.0
"""
return eval_(ast.parse(expr, mode='eval').body)
def demo_eval_expr(my_expr=[]):
# define a whitelist of symbols
a, b, c, d = sympy.symbols('a b c d')
# let say my_expr = "(2 + 5) * (3 + 9)"
# construct d_expr = {a:2, b:5, c:3, d:9}
return int(sympy.sympify("(a + b) * (c + d)").evalf(subs={a:2, b:5, c:3, d:9}))
print(demo_eval_expr())
EXPR=Tree('*')
EXPR.insert(3)
EXPR.insert('+')
EXPR.insert(4)
EXPR.insert(5)
EXPR.insert('+')
EXPR.insert(6)
print(EXPR.tree_to_str())