Skip to content

Instantly share code, notes, and snippets.

@fledman
Last active August 29, 2015 14:21
Show Gist options
  • Save fledman/886e463942270c36db08 to your computer and use it in GitHub Desktop.
Save fledman/886e463942270c36db08 to your computer and use it in GitHub Desktop.
Chained Arithmetic
class DotMath
NUMBERS = {
zero: 0, one: 1, two: 2, three: 3, four: 4, five: 5,
six: 6, seven: 7, eight: 8, nine: 9, ten: 10
}.freeze
OPERATORS = {
plus: [:+,1], minus: [:-,1], times: [:*,1], divide: [:/,1],
negate: [:-@,0], abs: [:abs,0], pow: [:**, 1], mod: [:%, 1]
}.freeze
OPERATORS.each do |m,op|
define_method(m) { apply(op) }
end
NUMBERS.each do |m, num|
define_method(m) { apply(num) }
Kernel.send(:define_method, m) { DotMath.new.send(m) }
end
def initialize(*ops)
@queue = ops.compact
end
def simplify
self.class.new(evaluate)
end
def to_i
evaluate
end
def to_s
to_i.to_s
end
def literal(x)
apply(x.to_i)
end
alias_method :[], :literal
private
def apply(x)
self.class.new(*@queue, x)
end
def evaluate
return if @queue.empty?
result = @queue[0].to_i
applying, args = nil, []
@queue[1..-1].each do |op|
if applying.nil?
raise "Expected an operator!" if !op.is_a?(Array)
applying = op
else
raise "Expected an operand!" if op.is_a?(Array)
args << op.to_i
end
if args.size == applying[1]
result = result.send(applying[0], *args)
applying, args = nil, []
end
end
raise "Expression is incomplete!" if !applying.nil? || !args.empty?
result
end
end
raise "expected (3+4)*5 to equal 35!" if three.plus.four.times.five.to_i != 35
raise "expected 3+(4*5) to equal 23!" if three.plus[four.times.five].to_i != 23
raise "expected (5-1)/2 to equal 2!" if five.minus.one.divide.two.to_i != 2
raise "expected 2 raised to the 4th power to equal 16!" if two.pow.four.to_i != 16
raise "expected (10+2) modulo 5 to equal 2!" if ten.plus.two.mod.five.to_i != 2
raise "expected -3 * 5 to equal -15!" if three.negate.times.five.to_i != -15
raise "expected abs(-(9*1+6) - 8) to equal 23!" if nine.times.one.plus.six.negate.minus.eight.abs.to_i != 23
raise "expected 7 to the 0th power to equal 1!" if seven.pow.zero.to_i != 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment