Last active
March 4, 2020 22:32
-
-
Save macedd/c532a2577af0275335093f52d6c2b03b to your computer and use it in GitHub Desktop.
Python Brackets Balancing Excercise
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class UnbalancedBlockException(Exception): | |
pass | |
'''Representation of a brackets block and a node in the tree''' | |
class Block(object): | |
def __init__(self, char, parent): | |
self.initiator = char | |
self.children = [] | |
self.parent = parent | |
# attach to the parent block | |
if parent: | |
parent.children.append(self) | |
def __repr__(self): | |
return '%s=>%s' % (self.initiator, len(self.children)) | |
def __eq__(self, other): | |
return self.initiator == other.initiator | |
def closeBlock(self, char): | |
if ((self.initiator == '[' and char != ']') | |
or (self.initiator == '(' and char != ')') | |
or (self.initiator == '{' and char != '}')): | |
raise UnbalancedBlockException('cant close because thats not right spot') | |
# remove from parent (if not the root itself) | |
if self.parent: | |
self.parent.children.remove(self) | |
class TreeBuilder(object): | |
'''The current node pointer''' | |
current = None | |
'''Creates a node inside the tree under the current pointer. Also set the new node as current pointer.''' | |
def insertNode(self, char): | |
node = Block(char, self.current) | |
self.current = node | |
'''Closes and removes node from tree and set it's parent node as current pointer.''' | |
def closeNode(self, char): | |
if self.current: | |
self.current.closeBlock(char) | |
self.current = self.current.parent | |
else: | |
raise UnbalancedBlockException('cant close because there is nothing open') | |
'''Should determine a tree is open or completly parsed (and balanced)''' | |
def isOpen(self): | |
return self.current | |
class Interpreter(object): | |
def __init__(self, s): | |
self.string = s | |
self.tree = TreeBuilder() | |
def parse(self): | |
print('parsing', self.string) | |
for i, ch in enumerate(self.string): | |
if ch in ['[', '{', '(']: | |
# opening block instance | |
self.tree.insertNode(ch) | |
elif ch in [']', '}', ')']: | |
# closing block instance | |
self.tree.closeNode(ch) | |
if self.tree.isOpen(): | |
raise UnbalancedBlockException('tree failed because its not complete') | |
return True | |
def is_match(s): | |
try: | |
runtime = Interpreter(s) | |
return runtime.parse() | |
except UnbalancedBlockException as e: | |
return False | |
if __name__ == '__main__': | |
assert is_match('(a[0]+b[2c[6]]) {24 + 53}') | |
assert is_match('f(e(d))') | |
assert is_match('[()]{}([])') | |
assert not is_match('((b)') | |
assert not is_match('(c]') | |
assert not is_match('{(a[])') | |
assert not is_match('([)]') | |
assert not is_match('[({{}}])') | |
assert not is_match(')(') | |
print("All tests pass") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment