--Boundary-00ywrHn/OeCBxkgG
Content-Type: Multipart/Mixed;
  boundaryoundary-00ywrHn/OeCBxkgG"

--Boundary-00ywrHn/OeCBxkgG
Content-Type: text/plain;
  charsettf-8"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

Here's my first solution, attached and pastied here:
http://pastie.caboo.se/149976

Its basically a binary search, repeatedly calculating the NVP and adjusting 
lower and upper bounds. Not too complicated, so let me just note a couple 
things:

* Line 12 could have been a mirror of line 10, but I wanted to emphasize the 
symmetry.
* Rationals are used throughout to ensure accuracy.
* The "+ 1" on line 10 prevents 0 from being a fixed point.
* The given accuracy guarantees the result will be within 1 / 10 ** [accuracy] 
of the true answer. This is not the same thing as having [accuracy] number of 
correct digits. (Though the program could be made to do that if the guesses 
fell on negative powers of ten).

I haven't done all that many quizzes, but those I have were very enjoyable. 
Thank you James.

-Jesse Merriman

--Boundary-00ywrHn/OeCBxkgG
Content-Type: application/x-ruby;
  namerr.rb"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filenamerr.rb"

#!/usr/bin/env ruby
# Ruby Quiz 156: Internal Rate of Return
# Jesse Merriman

require 'rational'

# Guess a new number between a lower and upper bound.
def guess lower, upper
  if upper 1.0/0.0
    lower < 0 ? 0.to_r : (lower + 1) * 2
  elsif lower 1.0/0.0
    - guess(-upper, -lower)
  else
    (lower + upper) / 2
  end
end

# Calculate the IRR to within 1 / 10**accuracy
def irr cash_flows, accuracy  
  nvp  ambda do |irr|
          t  
          cash_flows.inject { |sum, c| t + ; sum + c / (1 + irr) ** t }
        end

  lower, upper  1.to_r, 1.0/0.0

  while (lower - upper).abs > Rational(1, 10 ** accuracy)
    g  uess lower, upper
    nvp[g] > 0 ? lower   : upper  
  end

  (lower + upper) / 2
end

class String
  def to_r
    if m  ^(\-?\d+)$/.match(self)
      m[1].to_i.to_r
    elsif m  ^(\-?\d+)\.(\d+)$/.match(self)
      m[1].to_i + Rational(m[2].to_i, 10 ** m[2].length)
    elsif m  ^(\-?\d+)\s*\/\s*(\d+)$/.match(self)
      Rational m[1].to_i, m[2].to_i
    else
      raise StandardError, "Can't parse #{self} to a Rational"
    end
  end
end

if __FILE__ $0
  cash_flows  RGV[0..-2].map { |x| x.to_r }
  accuracy  RGV[-1].to_i

  if cash_flows.inject { |sum, x| sum + x } < 0
    puts 'Cannot solve with net negative.'
  else
    i  rr cash_flows, accuracy
    puts "irr: #{i} (#{i.to_f})"
  end
end


--Boundary-00ywrHn/OeCBxkgG--
--Boundary-00ywrHn/OeCBxkgG--