Skip to content

Instantly share code, notes, and snippets.

@realmyst
Created July 18, 2012 13:05
Show Gist options
  • Save realmyst/3136111 to your computer and use it in GitHub Desktop.
Save realmyst/3136111 to your computer and use it in GitHub Desktop.
Reverse Polish Notation, first try
#
# Requirement: delimiter ',' after each operands
# Example:
#
# ~> ruby polish '8,2,5,*+1,3,2,*+4,-/'
# result: 6
#
class ReversePolishTypeError < StandardError; end
class ReversePolish
def initialize
@result_stack = []
@buffer = ""
end
def calculate(str)
str.each_char do |char|
if operator?(char)
b, a = @result_stack.pop, @result_stack.pop
@result_stack.push(operate(char, a, b))
elsif delimiter?(char)
@result_stack.push @buffer.to_i
@buffer.clear
elsif operand_path?(char)
@buffer += char
else
raise ReversePolishTypeError
end
end
@result_stack.pop
end
def delimiter?(char)
[","].include?(char)
end
def operator?(char)
["+", "-", "*", "/"].include?(char)
end
def operand_path?(char)
!!char.match(/[0-9]/)
end
def operate(operator, a, b)
case operator
when "+"; return a + b
when "-"; return a - b
when "/"; return a / b
when "*"; return a * b
end
end
class << self
def calculate(str)
obj = new
result = obj.calculate(str)
puts "result: #{result}"
rescue ReversePolishTypeError => e
puts "operands must be an integer"
end
end
end
str = ARGV.first
ReversePolish.calculate(str)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment