Perform arithmetic operations on string in Ruby

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

1 answer

  • answered 2022-05-05 14:39 BenFenner

    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
    

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum