Skip to content

Instantly share code, notes, and snippets.

@inesusvet
Created March 14, 2019 22:54
Show Gist options
  • Save inesusvet/f0ac4e665703ceee485a107be1924a8d to your computer and use it in GitHub Desktop.
Save inesusvet/f0ac4e665703ceee485a107be1924a8d to your computer and use it in GitHub Desktop.
Coding dojo session result from 2019-03-14
"""
See https://www.codewars.com/kata/reverse-polish-notation-calculator
Your job is to create a calculator which evaluates expressions in Reverse Polish notation.
For example expression 5 1 2 + 4 * + 3 - (which is equivalent to 5 + ((1 + 2) * 4) - 3 in normal notation) should evaluate to 14.
For your convenience, the input is formatted such that a space is provided between every token.
Empty expression should evaluate to 0.
Valid operations are +, -, *, /.
You may assume that there won't be exceptional situations (like stack underflow or division by zero).
"""
from operator import add, sub, truediv, mul
class Node(object):
def __init__(self, val):
self.val = val
def evaluate(self):
return self.val
class OpNode(object):
def __init__(self, op, a, b):
self.op = op
self.a = a
self.b = b
def evaluate(self):
res_a = self.a.evaluate()
res_b = self.b.evaluate()
if self.op == '+':
return res_a + res_b
if self.op == '-':
return res_a - res_b
if self.op == '*':
return res_a * res_b
if self.op == '/':
return float(res_a) / res_b
else:
raise RuntimeError('i am a dumb')
def parse_expr(tokens):
next_token = tokens.pop()
if next_token not in set('*-/+'):
val = int(next_token) if next_token.isdigit() else float(next_token)
return Node(val)
else:
op = next_token
b = parse_expr(tokens)
a = parse_expr(tokens)
return OpNode(op, a, b)
op_map = {'+': add, '-': sub, '*': mul, '/': truediv}
def parse_expr_no_classes(tokens):
next_token = tokens.pop()
if next_token not in set('*-/+'):
val = int(next_token) if next_token.isdigit() else float(next_token)
return val
else:
op = next_token
b = parse_expr_no_classes(tokens)
a = parse_expr_no_classes(tokens)
return op_map[op](a, b)
def calc(expr):
"""
>>> calc("")
0
>>> calc("3")
3
>>> calc("3.5")
3.5
>>> calc("1 3 +")
4
>>> calc("1 3 *")
3
>>> calc("1 3 -")
-2
>>> calc("4 2 /")
2
>>> calc("5 1 2 + 4 * + 3 -")
14
>>> calc("1 2 + 3 * 4 - 5 /")
1
"""
if not expr:
return 0
tokens = expr.split(' ')
res = parse_expr_no_classes(tokens)
if res % 1 == 0:
return int(res)
return res
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment