MIN_RATE = 8.0 RATE_WINDOW = 12.0 INITIAL_PRINCIPLE = 50.0 PERIODS = 36 def get_new_rate return MIN_RATE + rand(RATE_WINDOW) end def add_loans(loans, account_balance) new_loan_count = account_balance / INITIAL_PRINCIPLE new_loan_count.to_i.times do rate = get_new_rate loans << {:principle => INITIAL_PRINCIPLE, :rate => rate, :min_payment => calc_minimum_payment(INITIAL_PRINCIPLE,rate)} account_balance -= INITIAL_PRINCIPLE end account_balance end def calc_minimum_payment(principle, interest) per_int = interest / 12.0 / 100 (per_int * principle * (1 + per_int)**PERIODS) / ((1 + per_int)**PERIODS - 1) end def calc_payment(loan, months=1) if loan[:principle] < loan[:min_payment] payment = loan[:principle] loan[:principle] = 0 return payment end interest = loan[:principle] * loan[:rate] / 100.0 / 12 loan[:principle] -= loan[:min_payment] - interest return loan[:min_payment] end def calc_average(coll) sum = coll.inject(0) {|sum, n| sum + n} sum / coll.size end account_balance = ARGV[0].to_f if ARGV[0] account_balance ||= 0.0 monthly_deposit = ARGV[1].to_f if ARGV[1] monthly_deposit ||= 100.0 number_of_years = ARGV[2].to_i if ARGV[2] number_of_years ||= 1 loans = [] for i in (1..number_of_years*12) old_loans = loans.size account_balance = add_loans loans, account_balance print "Month #{i}\n" print "Number of loans: #{loans.size} (#{loans.size - old_loans})\n" print "Average Rate: #{calc_average(loans.collect {|i| i[:rate]})}\n" income= loans.inject(0) {|bal, i| bal + calc_payment(i)} print "Account balance: #{account_balance}\n" print "Income: #{income}\n" account_balance += income + monthly_deposit print "Account value: #{loans.collect {|i| i[:principle]}.inject(account_balance) {|sum, i| sum + i}}\n" print "\n" loans.delete_if {|item| item[:principle] == 0} end