tags:

views:

183

answers:

3

I need a special behavior from eval, to evaluate strings like:

'5a + 6b + 3a + 11b'

into

'8a + 17b'

Is it possible? If it is, can you give a proper example? I found this example recently, where the talk was about evaluating strings with meters and inches.

+1  A: 

I guess depending on your problem this might be very complex. I do not know a library for mathematical optimization in ruby. I fear it is not possible with ruby eval. But you probably could write your own optimizer. If you think of the expression that way:

  • +
    • *
      • 5
      • a
    • *
      • 6
      • b
    • *
      • 3
      • a
    • *
      • 11
      • b

You can group summands with equal variable, summarize the numbers and create a new expression string. For the parsing Treetop could be worth a look.

Thomas
+1 for treetop, never heard of it before.
khelll
Parsing an arithmetic expression is the introductory example in the Treetop docu, if I remember correctly. Good luck with your computer algebra system, though!
Jörg W Mittag
+2  A: 

Well, the problem here is not related to Ruby's eval. You need a simple interpreter (parser+evaluator) to interpret the above mentioned expressions. There are some solutions for your problem but you need to give a proper explanation for the syntax you are trying to parse.

For example in your case I would do something like this:

res = ['a','b'].map do |sym| 
  '5a + 6b + 3a + 11b'.scan(/(\d+)#{sym}/).flatten.inject(0){|sum,x| sum + x.to_i}.to_s + sym
end.join(" + ")
puts res #=> 8a + 17b
khelll
Regexps are still a kind of 'dark forest' for me. Still, will try to look deeper into your example. Thanks!
gmile
+4  A: 

The way it is written, that's not valid ruby syntax, so it can't be evaled.

You have two options:

a) Don't use eval. I would think that this is the best option, but I supposed that depends on the context.

b) Change the syntax to 5.a + 6.b + 3.a + 11.b and define appropriate a and b methods, like so:

class Expr
  attr_accessor :a,:b
  def initialize(a,b)
    @a, @b = a,b
  end

  def +(other)
    Expr.new(a + other.a, b + other.b)
  end

  def inspect
    "<expr: #{a}a + #{b}b>"
  end
end

class Numeric
  def a
    Expr.new(self, 0)
  end

  def b
    Expr.new(0, self)
  end
end

5.a + 6.b + 3.a + 11.b #=> <expr: 8a + 17b>
sepp2k
In general, I'm trying to find a way of oversimplifying mathematical algebraic linear equations. So basically there will be N of unknown variables. I've already found a solution to avoid this unnecessary and complicated evaluation. Still thanx for your answer! Will try to generalize it in my leisure time.
gmile