Skip to content

Instantly share code, notes, and snippets.

@kirikiriyamama
Created April 20, 2015 16:10
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 kirikiriyamama/360694ca3868635aeabb to your computer and use it in GitHub Desktop.
Save kirikiriyamama/360694ca3868635aeabb to your computer and use it in GitHub Desktop.
class RPN
def initialize(expression)
@tree = Tree.new(expression)
end
def calculate
@tree.calculate
end
class Tree
def initialize(expression)
@root = Node.new(expression)
@root.partition
end
def calculate
@root.calculate
end
class Node
attr_reader :token, :left, :right
def initialize(token, left = nil, right = nil)
@token = token
@left = self.class.new(left) if left
@right = self.class.new(right) if right
end
def partition
if expression?
regexp =
case @token
when /[+\-]/; /[+\-]/
when /[*\/]/; /[*\/]/
end
l, t, r = @token.partition(regexp)
@token = t
@left = self.class.new(l)
@right = self.class.new(r)
@left.partition
@right.partition
end
self
end
def calculate
l = @left.operator? ? @left.calculate : @left.token.to_f
r = @right.operator? ? @right.calculate : @right.token.to_f
l.send(@token.intern, r)
end
def expression?
!(operand? || operator?)
end
def operand?
Float(@token)
rescue
false
else
true
end
def operator?
!!(@token =~ /\A[+\-*\/]\z/)
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment