ruby - Improving calculate function where input string does not follow normal computational order -
i working through sample interview questions , came across problem have write calculate function. caveat input string isn't written in computational order - instead numbers first , operators come after.
test cases:
calculate("2 3 +") # => 5
calculate("12 2 /") #=> 6
calculate("48 4 6 * /") # => 2
def calculate(string) numbers = string.scan(/\d+/) operators = string.scan(/\d\w/).map{|o|o.gsub(" ","")} #todo better regex remove space without having map formatted_string = numbers.inject(""){|string, b| string+"#{b}#{operators.shift}" } eval(formatted_string) end
i able come solution, wondering if there more efficient/better way solve problem. don't come programming background not familiar tools/algorithms may help.
any feedback appreciated.
ooh, fun! syntax called reverse polish notation (rpn), aka "postfix notation" , still used powerful calculators (the hp-48g made me fall in love programming!).
the typical way parse , calculate rpn split input string whitespace-separated tokens, , each token, push onto stack if it's integer, otherwise perform arithmetic operation designated token using last 2 items on stack operands , push result on.
here solution came quickly:
def calculate(str) stack = [] tokens = str.split(/\s+/) # split tokens whitespace. tokens.each |token| if token =~ /^\d+$/ # it's number stack.push(token.to_i) # ...push on stack. elsif %w(+ - * /).include? token # it's operator a, b = stack.pop(2) # ...grab last 2 numbers c = a.send(token, b) # ...perform operation stack.push(c) # ...and push resulting value. else raise "invalid token: #{token}" # punt! end end stack.pop # return last value pushed stack. end calculate("2 3 +") # => 5, since 2+3 = 5 calculate("12 2 /") # => 6, since 12/2 = 6 calculate("48 4 6 * /") # => 2, since 48/(4*6) = 2
Comments
Post a Comment