Skip to content

Instantly share code, notes, and snippets.

@zachdaniel
Created May 16, 2015 00:27
Show Gist options
  • Save zachdaniel/a90d69d159cea410de65 to your computer and use it in GitHub Desktop.
Save zachdaniel/a90d69d159cea410de65 to your computer and use it in GitHub Desktop.
Calculator
class Calculator
def initialize(value="")
@value ||= value
end
def method_missing(method, *args, &block)
@value += tokenize(method.to_s)
self
end
def tokenize(token)
Calculator.numbers.merge(Calculator.operators)[token]
end
def ==(other_object)
eval(@value) == other_object
end
def self.method_strings
Calculator.numbers.map do |key, value|
"def #{key}; Calculator.new('#{value}'); end"
end
end
def self.numbers
numbers = ["zero", "one", "two", "three", "four",
"five", "six", "seven", "eight", "nine"]
Hash[numbers.map.with_index { |value, index| [value, index.to_s] }]
end
def self.operators
{"plus" => "+",
"minus" => "-",
"divided_by" => "/",
"times" => "*"}
end
end
Calculator.method_strings.map {|x| eval(x)}
fail unless one.plus.two == 3
fail unless two.divided_by.four.plus.nine.times.three == 27
fail unless one.four.four.divided_by.one.two == 12
#The benefits of the above are that we can very easily add or modify operations. For instance, we can easily do this
class Calculator
def initialize(value="")
@value ||= value
end
def method_missing(method, *args, &block)
raise("bad token: #{method}") unless token = tokenize(method.to_s)
@value += tokenize(method.to_s)
self
end
def tokenize(token)
Calculator.numbers.merge(Calculator.operators)[token]
end
def ==(other_object)
eval(@value) == other_object
end
def self.method_strings
Calculator.numbers.map do |key, value|
"def #{key}; Calculator.new('#{value}'); end"
end
end
def self.numbers
numbers = ["zero", "one", "two", "three", "four",
"five", "six", "seven", "eight", "nine", "ten",
"eleven", "twelve", "thirteen", "fourteen", "fifteen",
"sixteen", "seventeen", "eighteen", "nineteen", "twenty"]
Hash[numbers.map.with_index { |value, index| [value, index.to_s] }]
end
def self.operators
{"plus" => "+",
"minus" => "-",
"divided_by" => "/",
"over" => "/",
"times" => "*",
"open_paren" => "(",
"close_paren" => ")",
"to_the_power_of" => "**"}
end
end
Calculator.method_strings.map {|x| eval(x)}
fail unless eighteen.to_the_power_of.two.times.open_paren.twelve.minus.four.close_paren.over.nine == 288
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment