On Feb 8, 4:01 pm, Ruby Quiz <ja... / grayproductions.net> wrote: > > This week's quiz is to calculate the IRR for any given variable-length list of > numbers... Here is my solution. I'm too lazy to use Newton's method, so I've employed a binary search. The most difficult part was, no surprise, determining the bounds of search. :-) #!/usr/bin/env ruby def npv(ct, i) sum = 0 ct.each_with_index{ |c,t| sum += c/(1 + i.to_f)**t } sum end def irr(ct) l = -0.9999 sign = npv(ct, l) # p sign r = 1.0 while npv(ct, r)*sign > 0 do # p npv(ct, r) r *= 2 break if r > 1000 end if r > 1000 l = -1.0001 sign = npv(ct, l) r = -2.0 while npv(ct, r)*sign > 0 do r *= 2 return 0.0/0.0 if r.abs > 1000 end end m = 0 loop do m = (l + r)/2.0 v = npv(ct, m) # p v break if v.abs < 1e-8 if v*sign < 0 r = m else l = m end end m end if __FILE__ == $0 p irr([-100,+30,+35,+40,+45]) p irr([-100,+10,+10,+10]) p irr([+100,+10,+10,+10]) p irr([+100,-90,-90,-90]) p irr([+0,+10,+10,+10]) end -- Alex