Home > Software design >  Ruby mathematical formula from string with 'x'
Ruby mathematical formula from string with 'x'

Time:10-27

In order not to get rusty I want to refresh my knowledge of pure ruby by solving some algorithms. I can't solve a larger algorithm without solving a smaller one like the example below.

Have the function missing_digit(str) take the str parameter, which will be a simple mathematical formula with three numbers, a single operator ( , -, *, or /) and an equal sign (=) and return the digit that completes the equation. In one of the numbers in the equation, there will be an x character, and your program should determine what digit is missing. For example, if str is "3x 12 = 46" then your program should output 4.

Examples
Input: "4 - 2 = x"
Output: 2
Input: "1x0 * 12 = 1200"
Output: 0

I think I found the solution for python but I can't find the corresponding Ruby code anywhere.

CodePudding user response:

Python and Ruby are quite similar, though trying to convert this without some basic TDD would have been difficult. Here is the converted to Ruby file from your python example. I would refactor this code but the simple tests here pass, those given in your linked example.

string_math_x.rb

class StringMathX
  def self.calculate(str)
    exp = str.split()

    first_operand = exp[0]
    operator = exp[1]
    second_operand = exp[2]
    resultant = exp[-1]

    # If x is present in resultant
    if resultant[/x/]
      first_operand = first_operand.to_i
      second_operand = second_operand.to_i

      if operator == ' '
        res = first_operand   second_operand
      elsif operator == '-'
        res = first_operand - second_operand
      elsif operator == '*'
        res = first_operand * second_operand
      else
        res = first_operand / second_operand
      end
      return res
    end

    # If x in present in operands

    # If x in the first operand
    if first_operand == 'x'
      x = first_operand.to_i
      second_operand = second_operand.to_i

      if operator == ' '
        res = resultant - second_operand
      elsif operator == '-'
        res = resultant   second_operand
      elsif operator == '*'
        res = resultant / second_operand
      else
        res = resultant / second_operand
      end
    # If x is in the second operand
    else
      x = second_operand.to_i
      first_operand = first_operand.to_i
      if operator == ' '
        res = resultant-first_operand
      elsif operator == '-'
        res = first_operand - second_operand
      elsif operator == '*'
        res = resultant.to_i / first_operand.to_i
      else
        res = first_operand.to_i / resultant.to_i
      end
    end
    res = res.to_s
    k = 0
    for i in [*0..x]
      if i == x
        result = res[k]
        break
      else
        k  = 1
      end
    end
    result.to_i
  end
end

./test/test.rb

require 'minitest/autorun'
require_relative '../lib/string_math_x'
class StringMathXTest < Minitest::Test
  def test_basic_subtration
    input = '4 - 2 = x'
    assert(StringMathX.calculate(input) == 2, 'outputs 2')
  end
  def test_whats_up_returns_doc
    input = '1x0 * 12 = 1200'
    assert(StringMathX.calculate(input) == 0, 'outputs 0')
  end
end

To run this you may need to gem install minitest

Then run ruby test/test.rb

CodePudding user response:

def findx(str)
  s = str.sub('=', '==')
  i = s.index('x')
  pre = s[0,i]
  post = s[i 1..-1]
  ('0'..'9').find { |d| eval(pre d post) rescue nil }&.to_i
end
findx("4 - 2 = x")        #=> 2
findx("1x0 * 12 = 1200")  #=> 0
findx("3**x = 81")        #=> 4
findx("1/x == 2.0").nil?  #=> true

rescue nil is needed in case division by zero is performed. & is the safe harbor operator. It returns nil, disregarding all that follows, if the part before it returns nil.

  • Related