-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathp112.py
134 lines (108 loc) · 3.24 KB
/
p112.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
# Tree Summing
import re
class Node():
def __init__(self, value, left=None, right=None):
self.value = value
self.left = left
self.right = right
def serialize(self):
return str(self)
def preorder(self, sentinel=None):
serial = [self.value]
if self.left:
serial.extend(self.left.preorder(sentinel))
else:
serial.append(sentinel)
if self.right:
serial.extend(self.right.preorder(sentinel))
else:
serial.append(sentinel)
return serial
def inorder(self, root):
return (self.inorder(root.left) + [root.value] + self.inorder(root.right)) if root else []
def levelorder(self):
nodes = []
queue = [self]
while queue:
node = queue.pop(0)
if node:
nodes.append(node.value)
queue.extend([child for child in [node.left, node.right] if child])
return nodes
@classmethod
def deserialize(cls, source):
from ast import literal_eval as make_tuple
def _tuple_to_node(tup):
value, left, right = tup
node = cls(value)
if isinstance(left, tuple):
node.left = _tuple_to_node(left)
else:
node.left = left
if isinstance(right, tuple):
node.right = _tuple_to_node(right)
else:
node.right = right
return node
return _tuple_to_node(make_tuple(source))
@property
def children(self):
return [self.left, self.right]
def __repr__(self):
return '({!r}, {!r}, {!r})'.format(self.value, self.left, self.right)
def sum_leaves(root):
leaf_sums = []
stack = [[root.value, root.children]]
while stack:
sigma, children = stack.pop(0)
nones = 0
for child in children:
if child is None:
nones += 1
else:
stack.append([sigma + child.value, child.children])
if nones == 2:
leaf_sums.append(sigma)
return leaf_sums
def load_input():
inp = ''
while True:
try:
line = input()
except EOFError:
break
else:
inp += line + '\n'
return inp
def parse_input(string):
inp = re.sub(r'\s+', ' ', string)
cases = []
while inp:
goal, inp = inp.split(' ', 1)
counter = 0
for i, char in enumerate(inp):
if char == '(':
counter += 1
elif char == ')':
counter -= 1
if counter == 0:
end = i + 1
break
node_str = re.sub(r'\s+', '', inp[:end])
node_str = node_str[0] + node_str[1:].replace('(', ',(')
node_str = node_str.replace('()', 'None')
cases.append((int(goal), node_str))
inp = inp[end:].strip()
return cases
def main():
inputs = load_input()
cases = parse_input(inputs)
for case in cases:
goal, inp = case
if inp == 'None':
print('no')
continue
node = Node.deserialize(inp)
print('yes' if goal in sum_leaves(node) else 'no')
if __name__ == '__main__':
main()