Advertisement
t_a_w

Simple calculator (no parentheses support)

Jul 18th, 2017
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 1.47 KB | None | 0 0
  1. class Calculator
  2.   def tokenize(input)
  3.     input.split.map do |token|
  4.       Float(token) rescue token
  5.     end
  6.   end
  7.  
  8.   # operation(3.0, "+", 4.0) returns 7.0 etc.
  9.   def operation(a, op, b)
  10.     raise "Expected A and B to be numbers" unless a.is_a?(Float) and b.is_a?(Float)
  11.     case op
  12.     when "+"
  13.       a + b
  14.     when "-"
  15.       a - b
  16.     when "*"
  17.       a * b
  18.     when "/"
  19.       a / b
  20.     else
  21.       raise "Unknown operator #{op}"
  22.     end
  23.   end
  24.  
  25.   # turn [..., 3, "+", 4, ...]
  26.   # into [..., 7, ...]
  27.   # where index_op points at operator
  28.   def replace_expr_with_result(tokens, index_op)
  29.     a, op, b = tokens[index_op-1..index_op+1]
  30.     result = operation(a, op, b)
  31.     tokens[index_op-1..index_op+1] = [result]
  32.   end
  33.  
  34.   def calculate(input)
  35.     tokens = tokenize(input)
  36.  
  37.     # First do all * and /
  38.     loop do
  39.       index_op = tokens.index do |token|
  40.         token == "*" or token == "/"
  41.       end
  42.       break unless index_op
  43.       replace_expr_with_result(tokens, index_op)
  44.     end
  45.  
  46.     # Then do all + and -
  47.     loop do
  48.       index_op = tokens.index do |token|
  49.         token == "+" or token == "-"
  50.       end
  51.       break unless index_op
  52.       replace_expr_with_result(tokens, index_op)
  53.     end
  54.  
  55.     raise "Extra stuff after all operations: #{tokens.inspect}" if tokens.size > 1
  56.  
  57.     tokens[0]
  58.   end
  59. end
  60.  
  61. input = "2 + 3 * 4 - 8 / 4 * 3 - 6 - 8"
  62. result = Calculator.new.calculate(input)
  63. expected = eval(input)
  64.  
  65. p [result, expected]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement