Created
January 24, 2017 00:55
-
-
Save tippenein/428d15677b1403d1f94f793f63979a7a to your computer and use it in GitHub Desktop.
naive amortization
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# naive amortization implementation using enumerators. | |
# used for a possible answer to compare against candidate solutions | |
# intended to determine how a candidate breaks up a problem | |
# similar haskell implementation - https://gist.github.com/tippenein/8dceb2d50272ec24ce13fe83f3a57bfa | |
module Amortizable | |
include Enumerable | |
def estimated_monthly | |
r = apr / 100 / 12 # percent per period | |
top = r * (1 + r) ** term | |
bottom = ((1 + r) ** term) - 1 | |
principal * (top / bottom) | |
end | |
def amortization | |
principal_month_pairs.map do |pair| | |
Amortization.new(*pair, apr) | |
end | |
end | |
private | |
def principal_month_pairs | |
principals = principal_enumerator_from(principal).take(self.term) | |
months = month_enumerator_from(self.created_at).take(self.term) | |
principals.zip(months) | |
end | |
def principal_enumerator_from(initial_principal) | |
Enumerator.new do |g| | |
s = initial_principal | |
while s > 0 do | |
next_principal = s - estimated_monthly | |
g.yield next_principal | |
s = next_principal | |
end | |
end | |
end | |
def month_enumerator_from(start) | |
Enumerator.new do |g| | |
s = start | |
loop do | |
next_month = 1.month.since(s) | |
g.yield next_month | |
s = next_month | |
end | |
end | |
end | |
class Amortization | |
attr_accessor :date, :principal, :interest, :apr | |
def initialize(principal, date, apr) | |
@principal = principal > 0 ? principal : 0 | |
@date = date | |
@apr = apr | |
@interest = interest_from(@principal) | |
end | |
def interest_from(principal) | |
apr_percent = apr / 100 | |
(principal * (apr_percent / 365) * 30).round(2) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment