Home > Blockchain >  Perform arithmetic operations on string in Ruby
Perform arithmetic operations on string in Ruby

Time:05-11

input: "20 10/5-1*2"

I want to perform arithmetic operations on that string how can I do it without using eval method in ruby?

expected output: 20

CodePudding user response:

While I hesitate to answer an interview question, and I am completely embarrassed by this code, here is one awful way to do it. I made it Ruby-only and avoided Rails helpers because it seemed more of a Ruby task and not a Rails task.

#
# Evaluate a string representation of an arithmetic formula provided only these operations are expected:
#     | Addition
#   - | Subtraction
#   * | Multiplication
#   / | Division
#
# Also assumes only integers are given for numerics.
# Not designed to handle division by zero.
#
# Example input:   '20 10/5-1*2'
# Expected output: 20.0
#
def eval_for_interview(string)
  add_split      = string.split(' ')
  subtract_split = add_split.map{ |v| v.split('-') }
  divide_split   = subtract_split.map do |i|
    i.map{ |v| v.split('/') }
  end
  multiply_these = divide_split.map do |i|
    i.map do |j|
      j.map{ |v| v.split('*') }
    end
  end

  divide_these = multiply_these.each do |i|
    i.each do |j|
      j.map! do |k, l|
        if l == nil
          k.to_i
        else
          k.to_i * l.to_i
        end
      end
    end
  end

  subtract_these = divide_these.each do |i|
    i.map! do |j, k|
      if k == nil
        j.to_i
      else
        j.to_f / k.to_f
      end
    end
  end

  add_these = subtract_these.map! do |i, j|
    if j == nil
      i.to_f
    else
      i.to_f - j.to_f
    end
  end

  add_these.sum
end

Here is some example output:

eval_for_interview('1 1')
=> 2.0
eval_for_interview('1-1')
=> 0.0
eval_for_interview('1*1')
=> 1.0
eval_for_interview('1/1')
=> 1.0
eval_for_interview('1 2-3*4')
=> -9.0
eval_for_interview('1 2-3/4')
=> 2.25
eval_for_interview('1 2*3/4')
=> 2.5
eval_for_interview('1-2*3/4')
=> -0.5
eval_for_interview('20 10/5-1*2')
=> 20.0
eval_for_interview('20 10/5-1*2*4-2/6 12-1-1-1')
=> 31.0
  • Related