Created
April 20, 2015 16:10
-
-
Save kirikiriyamama/360694ca3868635aeabb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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