```Here's my solution:

irr.rb:

require 'algebra'

class IRR

def self.calculate(profits)
begin
function(profits).zero
rescue Algebra::MaximumIterationsReached =3D> mir
nil
end
end

private

def self.function(profits)
Algebra::Function.new do |x|
sumands =3D Array.new
profits.each_with_index {|profit, index| sumands <<
profit.to_f / (1 + x) ** index }
sumands.inject(0) {|sum, sumand| sum + sumand }
end
end

end

puts IRR.calculate([-100, 30, 35, 40, 45])
puts IRR.calculate([-1, 1])
puts IRR.calculate([])

algebra.rb:

module Algebra

class MaximumIterationsReached < Exception
end

class NewtonsMethod

def self.calculate(function, x)
x - function.evaluated_at(x) / function.derivative_at(x)
end

end

class NewtonsDifferenceQuotient

def self.calculate(function, x, delta=3D0.1)
(function.evaluated_at(x + delta) -
function.evaluated_at(x) ).to_f / delta
end

end

class Function

attr_accessor :differentiation_method, :root_method, :maximum_iterations, :t=
olerance

def initialize(differentiation_method=3DNewtonsDifferenceQuotient,
root_method=3DNewtonsMethod, &block)
@definition =3D block
@differentiation_method, @root_method =3D differentiation_method,
root_method
@maximum_iterations =3D 1000
@tolerance =3D 0.0001
end

def evaluated_at(x)
@definition.call(x)
end

def derivative_at(x)
differentiation_method.calculate(self, x)
end

def zero(initial_value=3D0)
recursive_zero(initial_value, 1)
end

private

def recursive_zero(guess, iteration)
raise MaximumIterationsReached if iteration >=3D
@maximum_iterations

better_guess =3D @root_method.calculate(self, guess)

if (better_guess - guess).abs <=3D @tolerance
better_guess
else
recursive_zero(better_guess, iteration + 1)
end
end

end

end

On Feb 8, 9:01 am, Ruby Quiz <ja... / grayproductions.net> wrote:
> The three rules of Ruby Quiz:
>
> 1.  Please do not post any solutions or spoiler discussion for this quiz u=
ntil
> 48 hours have passed from the time on this message.
>
> 2.  Support Ruby Quiz by submitting ideas as often as you can:
>
> http://www.rubyquiz.com/
>
> 3.  Enjoy!
>
> Suggestion:  A [QUIZ] in the subject of emails about the problem helps eve=
ryone
sage,
> if you can.
>
> -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=
=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=
=3D-=3D-=3D
>
> by Harrison Reiser
>
> Internal Rate of Return (IRR -http://en.wikipedia.org/wiki/Internal_rate_o=
f_return) is a common financial
> metric, used by investment firms to predict the profitability of a company=
or
> project. Finding the IRR of a company amounts to solving for it in the equ=
ation
> for Net Present Value (NPV -http://en.wikipedia.org/wiki/Net_present_value=
),
> another valuable decision-making metric:
>
>                N      C_t
>         NPV =3D  =D3  ------------
>               t=3D0 (1 + IRR)**t
>
> This week's quiz is to calculate the IRR for any given variable-length lis=
t of
> numbers, which represent yearly cash flows, the C_t's in the formula above=
: C_0,
> C_1, etc. (C_0 is typically a negative value, corresponding to the initial=

> investment into the project.) From the example in the Wikipedia article
> (http://en.wikipedia.org/wiki/Internal_rate_of_return), for instance, you =
should
> be able to produce a rate of 17.09% (to four decimal places, let's say) fr=
om
> this or a similar command:
>
>         irr([-100,+30,+35,+40,+45])
>         =3D> 0.1709...
>
> Keep in mind that an IRR greater than 100% is possible. Extra credit if yo=
u can
> also correctly handle input that produces negative rates, disregarding the=
fact
> that they make no sense.

```