Radu Andrei
Radu Andrei

Reputation: 61

algorithm that calculates a minimum amount to be paid to pay off a balance in 12 months

I'm struggling with a problem that calculates the minimum fixed monthly payment needed in order pay off a credit card balance within 12 months. By a fixed monthly payment, I mean a single number which does not change each month, but instead is a constant amount, multiple of 10 and the same for all months, that will be paid each month. ( it is possible for the balance to become negative using this payment scheme, which is OK)

So as input I have

original_balance = 3329

annualInterestRate = 0.2

From this I'm calculating the followings :

after_12_months_interest = original_balance
monthlyInterestRate = round(annualInterestRate/12.0,2)
monthly_payment = 10
total_paid = 0

for i in range(0,12):
    after_12_months_interest = after_12_months_interest + (annualInterestRate/12.0)*after_12_months_interest

while total_paid < after_12_months_interest:
    new_balance = 0
    unpaid_balance = original_balance - monthly_payment 
    total_paid = 0
    for i in range(0, 13):
        total_paid = total_paid + monthly_payment
    if total_paid < after_12_months_interest:
        monthly_payment = monthly_payment + 10

print "Lowest Payment: ", monthly_payment

My problem I have is that I end up having a monthly_payment just a little more than I should have it. In this case the return for the monthly_payment is 320 instead of 310. For all use cases I've tried the monthly_payment it's slightly more than it should be.

Anyone can give me a hint or an idea on what I'm doing wrong please. Thank you

Upvotes: 1

Views: 277

Answers (1)

njzk2
njzk2

Reputation: 39406

Mandatory one-liner

from itertools import count

print(next(payment for payment in count(0, 10) 
    if sum(payment*(1+monthly)**i for i in range(12)) > original_balance*(1+annual)))

What this does:

  • next takes the first element of an iterator.
  • count tries values from 0 to infinity (only each time next is called, and only until a value is returned)
  • sum(payment*(1+monthly)**i for i in range(12)) That's the combined value of the payments. Each payment is worth itself plus all the saved interests (the earlier you repay, the less interest you'll owe later)
  • original_balance*(1+annual) is indeed the total value if nothing is repayed.

Alternative

print(next(payment for payment in count(0, 10) 
    if reduce(lambda x,_:(x - payment)*(1+monthly), range(12), original_balance) <= 0))

This one computes the combined remainder of the debt by reduceing the original_balance 12 times.

Upvotes: 1

Related Questions