Skip to content

Instantly share code, notes, and snippets.

@darkleaf
Created July 18, 2012 16:11
Show Gist options
  • Save darkleaf/3137207 to your computer and use it in GitHub Desktop.
Save darkleaf/3137207 to your computer and use it in GitHub Desktop.
ReversePolishNotation
module ReversePolishNotation
class << self
def calc(formula)
chain = prepare formula
stack = []
while chain.any? do
item = chain.shift
if item.kind_of? Float
stack.push item
else
b = stack.pop
a = stack.pop
res = a.send item, b
stack.push res
end
puts stack.inspect
end
stack.pop
end
private
def prepare(formula)
chain = parse formula
result = []
stack = []
while chain.any? do
c = chain.shift
case c
when Float
result << c
when '+', '-', '*', '/'
op1 = c
while (op2 = stack.last) && (op2 != '(') && (precedence(op1) <= precedence(op2))
stack.pop
result << op2
end
stack << op1
when '('
stack << c
when ')'
while (h = stack.pop) != '('
raise 'Error' unless h
result << h
end
end
end
result << stack.reverse
result.flatten
end
def parse(string)
raw = string.gsub /([\+\-\*\/\(\)])/, ' \1 '
array = raw.split ' '
chain = array.delete_if{ |i| i.empty? }
chain.map { |i| i[/\d+/] ? i.to_f : i }
end
def precedence(op)
case op
when '+', '-'
1
when '*', '/'
2
end
end
end
end
puts ReversePolishNotation.calc '(8+2*5)/(1+3*2-4)'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment