diff --git a/kata/6-kyu/financing-a-purchase/README.md b/kata/6-kyu/financing-a-purchase/README.md new file mode 100644 index 00000000..c8e505f2 --- /dev/null +++ b/kata/6-kyu/financing-a-purchase/README.md @@ -0,0 +1,76 @@ +# [Financing a purchase](https://www.codewars.com/kata/financing-a-purchase "https://www.codewars.com/kata/59c68ea2aeb2843e18000109") + +The description is rather long, but it tries to explain what a financing plan is. + +The fixed monthly payment for a fixed rate mortgage is the amount paid by the borrower every month that ensures +that the loan is paid off in full, with interest at the end of its term. + +The monthly payment formula is based on the annuity formula. +The monthly payment `c` depends upon: + +- `rate` - the monthly interest rate is expressed as a decimal, not a percentage. + The monthly rate is simply the **given** yearly percentage rate divided by 100 and then by 12. + +- `term` - the number of monthly payments, called the loan's `term`. +- `principal` - the amount borrowed, known as the loan's principal (or `balance`). + +First we have to determine `c`. + +We have: `c = n /d` with `n = r LICENSE build.gradle.kts docs gradle gradle.properties gradlew gradlew.bat kata settings.gradle.kts balance` +and `d = 1 - (1 + r)**(-term)` where `**` is the `power` function (you can look at the reference below). + +The payment `c` is composed of two parts. The first part pays the interest (let us call it `int`) +due for the balance of the given month, the second part repays the balance (let us call this part `princ`) hence for the following month we +get a `new balance = old balance - princ` with `c = int + princ`. + +Loans are structured so that the amount of principal returned to the borrower starts out small and increases with each mortgage payment. +While the mortgage payments in the first years consist primarily of interest payments, the payments in the final years consist primarily of +principal repayment. + +A mortgage's amortization schedule provides a detailed look at precisely what portion of each mortgage payment is dedicated to each +component. + +In an example of a $100,000, 30-year mortgage with a rate of 6 percents the amortization schedule consists of 360 monthly payments. +The partial amortization schedule below shows with 2 decimal floats +the balance between principal and interest payments. + +| -- | num_payment | c | princ | int | Balance | +|----|-------------|--------|--------|--------|-----------| +| -- | 1 | 599.55 | 99.55 | 500.00 | 99900.45 | +| -- | ... | 599.55 | ... | ... | ... | +| -- | 12 | 599.55 | 105.16 | 494.39 | 98,771.99 | +| -- | ... | 599.55 | ... | ... | ... | +| -- | 360 | 599.55 | 596.57 | 2.98 | 0.00 | + +#### Task: + +Given parameters + +``` +rate: annual rate as percent (don't forgent to divide by 100*12) +bal: original balance (borrowed amount) +term: number of monthly payments +num_payment: rank of considered month (from 1 to term) +``` + +the function `amort` will return a formatted string (for example): + +`"num_payment %d c %.0f princ %.0f int %.0f balance %.0f" (with arguments num_payment, c, princ, int, balance`) + +***In Common Lisp:*** +return a list with num-payment, c, princ, int, balance each rounded. + +#### Examples: + +``` +amort(6, 100000, 360, 1) -> +"num_payment 1 c 600 princ 100 int 500 balance 99900" + +amort(6, 100000, 360, 12) -> +"num_payment 12 c 600 princ 105 int 494 balance 98772" + +``` + +#### Ref + + \ No newline at end of file diff --git a/kata/6-kyu/financing-a-purchase/main/Finance.java b/kata/6-kyu/financing-a-purchase/main/Finance.java new file mode 100644 index 00000000..506ac846 --- /dev/null +++ b/kata/6-kyu/financing-a-purchase/main/Finance.java @@ -0,0 +1,13 @@ +interface Finance { + static String amort(double rate, double bal, int term, int numPayment) { + rate /= 1200; + double c = rate * bal / (1 - Math.pow(1 + rate, -term)); + double principal = (c - bal * rate) * Math.pow(1 + rate, numPayment - 1.); + return String.format("num_payment %d c %.0f princ %.0f int %.0f balance %.0f", + numPayment, + c, + principal, + c - principal, + bal * (1 - (Math.pow(1 + rate, numPayment) - 1) / (Math.pow(1 + rate, term) - 1))); + } +} \ No newline at end of file diff --git a/kata/6-kyu/financing-a-purchase/test/FinanceTest.java b/kata/6-kyu/financing-a-purchase/test/FinanceTest.java new file mode 100644 index 00000000..828b14d7 --- /dev/null +++ b/kata/6-kyu/financing-a-purchase/test/FinanceTest.java @@ -0,0 +1,17 @@ +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +class FinanceTest { + @ParameterizedTest + @CsvSource(textBlock = """ + 7.4, 10215, 24, 20, num_payment 20 c 459 princ 445 int 14 balance 1809 + 7.9, 107090, 48, 41, num_payment 41 c 2609 princ 2476 int 133 balance 17794 + 6.8, 105097, 36, 4, num_payment 4 c 3235 princ 2685 int 550 balance 94447 + 3.8, 48603, 24, 10, num_payment 10 c 2106 princ 2009 int 98 balance 28799 + """) + void sample(double rate, int bal, int term, int numPayments, String expected) { + assertEquals(expected, Finance.amort(rate, bal, term, numPayments)); + } +} \ No newline at end of file diff --git a/kata/6-kyu/index.md b/kata/6-kyu/index.md index c4150b9e..22303297 100644 --- a/kata/6-kyu/index.md +++ b/kata/6-kyu/index.md @@ -139,6 +139,7 @@ - [Fibonacci Rabbits](fibonacci-rabbits "5559e4e4bbb3925164000125") - [Fibonacci, Tribonacci and friends](fibonacci-tribonacci-and-friends "556e0fccc392c527f20000c5") - [Figurate Numbers #1 - Pentagonal Number](figurate-numbers-number-1-pentagonal-number "55ab9eee6badbdaf72000075") +- [Financing a purchase](financing-a-purchase "59c68ea2aeb2843e18000109") - [Financing Plan on Planet XY140Z-n](financing-plan-on-planet-xy140z-n "559ce00b70041bc7b600013d") - [Find last Fibonacci digit [hardcore version]](find-last-fibonacci-digit-hardcore-version "56b7771481290cc283000f28") - [Find Numbers with Same Amount of Divisors](find-numbers-with-same-amount-of-divisors "55f1614853ddee8bd4000014")