Skip to content

Instantly share code, notes, and snippets.

@macedd
Last active March 4, 2020 22:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save macedd/c532a2577af0275335093f52d6c2b03b to your computer and use it in GitHub Desktop.
Save macedd/c532a2577af0275335093f52d6c2b03b to your computer and use it in GitHub Desktop.
Python Brackets Balancing Excercise
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