From: Carl Porth Date: 2008-02-11T01:50:36+09:00 Subject: Re: Internal Rate of Return (#156) Here's my binary search solution. It can return negative values (extra credit) and returns nil for undefined behavior. require "enumerator" require "rubygems" require "facets/numeric/round" def npv(irr, cash_flows) cash_flows.enum_with_index.inject(0) do |sum, (c_t, t)| sum + c_t / (1+irr)**t end end def irr(cash_flows, precision=10 ** -4) # establish an upper bound, return nil if none max = 1.0 max *= 2 until npv(max, cash_flows) < 0 or max.infinite? return nil if max.infinite? # initialize search variables last_irr, irr, radius = max, 0.0, max # binary search until precision is met until irr.approx?(last_irr, precision/10) last_irr = irr # improve approximation of irr if npv(irr, cash_flows) < 0 irr -= radius else irr += radius end # reduce the search space by half radius /= 2 end irr.round_to(precision) end if __FILE__ == $PROGRAM_NAME puts irr(ARGV.map { |e| Float(e) }) || "Undefined" end On Feb 8, 6:01 am, Ruby Quiz wrote: > The three rules of RubyQuiz: > > 1. Please do not post any solutions or spoiler discussion for thisquizuntil > 48 hours have passed from the time on this message. > > 2. Support RubyQuizby 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 everyone > on Ruby Talk follow the discussion. Please reply to the originalquizmessage, > if you can. > > -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- =-=-= > > by Harrison Reiser > > Internal Rate of Return (IRR -http://en.wikipedia.org/wiki/Internal_rate_of_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 equation > for Net Present Value (NPV -http://en.wikipedia.org/wiki/Net_present_value), > another valuable decision-making metric: > > N C_t > NPV = Ó ------------ > t=0 (1 + IRR)**t > > This week'squizis to calculate the IRR for any given variable-length list 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) from > this or a similar command: > > irr([-100,+30,+35,+40,+45]) > => 0.1709... > > Keep in mind that an IRR greater than 100% is possible. Extra credit if you can > also correctly handle input that produces negative rates, disregarding the fact > that they make no sense.