# Polynomial equation solver in Ruby

I've written a small function for solving simple quadratic equations:

class EquationSolver
def solve(x, *args)
args.reverse.map.with_index { |coefficient, index| coefficient * x ** index }.reduce { |result, element| result + element }
end
end


To calculate f(3) for f(x)=3x3−2x2−x+5, one would write:

puts EquationSolver.new.solve(3, 3, -2, -1, 5)


However, is there a more elegant version of my function, more like reduce.with_index or something similar?

Some notes:

• If you use a OOP approach, it seems more logical to use methods.
• Use arrays to group values that go together.
• I don't think solve is the correct term, that's when you are finding the roots of a function, here you're just evaluating it at a given point.

I'd write:

class Polynomial
attr_accessor :coefficients

def initialize(coefficients)
self.coefficients = coefficients.reverse
end

def evaluate(x)
coefficients.map.with_index { |k, power| k * (x**power) }.reduce(0, :+)
end
end

polynomial = Polynomial.new([3, -2, -1, 5])
puts polynomial.evaluate(3) #=> 65

• Pretty good. Btw, I think you don't need the 0 in reduce(0, :+). Nov 21 '13 at 10:38
• @AlexPopov: Well, it's just to consider the case f(x) = 0. Nov 21 '13 at 10:46
• Good point, didn't think about that. Nov 21 '13 at 10:50
• Btw, if you have zero = Polynomial.new 0, the code throws undefined method reverse' for 0:Fixnum (NoMethodError). Nov 21 '13 at 10:59
• @Alex: Yes. Personally I don't like this because it makes difficult to add extra arguments. IMHO the coefficients should be grouped, and an array is the most obvious way to do it. Nov 21 '13 at 14:40

Yes, there is a more elegant version. Here it is:

class EquationSolver
def solve(x, *args)
args.reverse.each_with_index.reduce(0) { |result, (coefficient, index)| result + coefficient * x ** index }
end
end


It's possible to do this because iterator methods like each_with_index, when called without a block, return an Enumerator object on which you can call all the methods of the Enumerable.

In fact, an even shorter solution is obtained by using a variation of reduce to use a symbolic operator:

class EquationSolver
def solve(x, *args)
args.reverse.map.with_index { |coefficient, index| coefficient * x ** index }.inject(:+)
end
end

• 10x, I had figured out the first version you proposed, but I didn't pass a 0 to reduce as a starting parameter, so it was giving me no implicit conversion of Fixnum into Array` Nov 21 '13 at 9:32
• Yep, it tends to happen. I'd any day prefer my second variation since it makes for an easy reading. Nov 21 '13 at 9:36