Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <fstream>
- #include <sstream>
- #include <vector>
- #include <cstdint>
- using namespace std;
- struct Money
- {
- int64_t cents;
- inline Money& operator+=(Money m)
- {
- cents += m.cents;
- return *this;
- }
- inline Money& operator-=(Money m)
- {
- cents -= m.cents;
- return *this;
- }
- inline Money& operator*=(int64_t multiplier)
- {
- cents *= multiplier;
- return *this;
- }
- inline Money& operator/=(int64_t divisor)
- {
- cents /= divisor;
- return *this;
- }
- };
- constexpr Money operator-(Money money)
- {
- return {-money.cents};
- }
- constexpr Money operator+(Money a, Money b)
- {
- return {a.cents + b.cents};
- }
- constexpr Money operator-(Money a, Money b)
- {
- return {a.cents - b.cents};
- }
- constexpr Money operator*(Money a, int64_t b)
- {
- return {a.cents * b};
- }
- constexpr Money operator/(Money a, int64_t b)
- {
- return {a.cents / b};
- }
- constexpr bool operator==(Money a, Money b)
- {
- return a.cents == b.cents;
- }
- constexpr bool operator!=(Money a, Money b)
- {
- return a.cents != b.cents;
- }
- constexpr bool operator<(Money a, Money b)
- {
- return a.cents < b.cents;
- }
- constexpr bool operator<=(Money a, Money b)
- {
- return a.cents <= b.cents;
- }
- constexpr bool operator>(Money a, Money b)
- {
- return a.cents > b.cents;
- }
- constexpr bool operator>=(Money a, Money b)
- {
- return a.cents >= b.cents;
- }
- ostream& operator<<(ostream& stream, Money money)
- {
- uint64_t cents = money.cents;
- if (money.cents < 0)
- {
- stream << '-';
- cents = -money.cents;
- }
- uint64_t dollars = cents / 100;
- cents -= dollars * 100;
- stream << dollars << '.';
- if (cents < 10) stream << '0';
- return stream << cents;
- }
- struct Loan
- {
- Money principal;
- int64_t interest; // 1 = 0.01%
- Money minPayment;
- };
- void RunSimulation(vector<Loan> loans, Money monthlyIncome)
- {
- static int fileId = 0;
- stringstream ss;
- ss << "loan_" << ++fileId << ".txt";
- ofstream fout(ss.str(), ofstream::binary);
- int monthCount = 0;
- Money totalPaid{0};
- Money minMonthlyIncome{0};
- for (auto loan : loans) minMonthlyIncome += loan.minPayment;
- if (monthlyIncome < minMonthlyIncome)
- {
- cout << '$' << monthlyIncome << " is not enough. Minimum income is $"
- << minMonthlyIncome << ".\n";
- monthlyIncome = minMonthlyIncome;
- }
- bool keepPaying = true;
- int n = 0;
- while (keepPaying)
- {
- auto income = monthlyIncome;
- ++monthCount;
- // Pay minimum amounts.
- fout << "Month " << monthCount << '\n';
- for (auto& loan : loans)
- {
- loan.principal -= loan.minPayment;
- income -= loan.minPayment;
- totalPaid += loan.minPayment;
- if (loan.principal.cents < 0)
- {
- income -= loan.principal;
- totalPaid += loan.principal;
- loan.principal = {0};
- }
- fout << "principal: " << loan.principal << '\n';
- }
- // Apply excess.
- for (size_t i = loans.size(); i > 0 && income.cents > 0; --i)
- {
- auto& loan = loans[i - 1];
- loan.principal -= income;
- totalPaid += income;
- if (loan.principal.cents < 0)
- {
- income -= loan.principal;
- totalPaid += loan.principal;
- loan.principal = {0};
- }
- }
- // Apply interest.
- keepPaying = false;
- for (auto& loan : loans)
- {
- auto interest = loan.principal * loan.interest / 120000;
- fout << "interest: " << interest << '\n';
- keepPaying |= loan.principal.cents > 0;
- loan.principal += interest;
- }
- }
- cout << "paid $" << totalPaid << " over " << monthCount << " months\n";
- fout.close();
- }
- int main(int argc, char** argv)
- {
- vector<Loan> loans;
- loans.push_back({{2000000}, 800, {19113}});
- loans.push_back({{200000}, 800, {4055}});
- loans.push_back({{500000}, 1800, {12697}});
- cout << "HIL first\n";
- RunSimulation(loans, {});
- loans.clear();
- loans.push_back({{2000000}, 800, {19113}});
- loans.push_back({{500000}, 1800, {12697}});
- loans.push_back({{200000}, 800, {4055}});
- cout << "LPL first\n";
- RunSimulation(loans, {});
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement