class Calculator
def initialize(arr)
@arr = arr
end
def add; binary(:+); end
def subtract; binary(:-); end
def multiply; binary(:*); end
def divide; binary(:/); end
def power; binary(:**); end
def modulo; binary(:%); end
# ... (others)
def negate; unary(:-@); end
def odd?; unary(:odd?); end
def even?; unary(:even?); end
def to_f; unary(:to_f); end
# ... (others)
private
def binary(op)
raise ArgumentError, 'Too few elements' if @arr.length < 2
@arr.pop.send(op, @arr.pop)
end
def unary(op)
raise ArgumentError, 'Too few elements' if @arr.length.zero?
@arr.pop.send(op)
end
end
# add neg mod pow div mult sub add
calc = Calculator.new [ 1, 5, 2,3, 4,5, 6,7, 8,9, 10,11, 12,13]
#=> #<Calculator:0x007fa192030968 @arr=[1, 5, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]>
calc.add #=> 25 (13+12)
calc.subtract #=> 1 (11-10)
calc.multiply #=> 72 (8*9)
calc.divide #=> 1 (7/6)
calc.power #=> 625 (5**4)
calc.modulo #=> 1 (3%2)
calc.negate #=> -5 (5)
calc.add #=> ArgumentError: Too few elements
It appears that you are constructing an RPN calculator. If so, you probably want to push the result of each calculation back onto the stack. For binary operators you could change the method binary
as follows:
def binary(op)
raise ArgumentError, 'Too few elements' if @arr.length < 2
@arr << @arr.pop.send(op, @arr.pop)
@arr[-1]
end
@arr[-1]
, the result of the calculation, is the return value. The modification of unary
is similar.
You may wish to add some stack manipulation methods, such as
def pop
@arr.pop
end
def push(n)
@arr << n
end
def swap
@arr[-1], @arr[-2] = @arr[-2], @arr[-1]
end
def rotate
@arr.rotate
end
Lastly, you might find it it clearer to make the beginning (rather than end) of @arr
the top of the stack, in which you would use unshift/shift
rather than push/pop
.