Created
December 7, 2022 18:25
-
-
Save vharidas/0b5df1c5fea2587b7c38b81a68112fdf to your computer and use it in GitHub Desktop.
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
const fs = require('fs'); | |
const Papa = require('papaparse'); | |
const _ = require('lodash'); | |
const pay_all_proportionally = (startLoans, emi) => { | |
const loans = _.cloneDeep(startLoans); | |
let total_outstanding = _.sumBy(loans, 'outstanding'); | |
let month = 0; | |
while (total_outstanding > 0) { | |
console.log(`month ${month} outstanding ${total_outstanding}`); | |
_.forEach(loans, loan => { | |
const part = (loan.outstanding / total_outstanding); | |
const repay = _.round(emi * part); | |
loan.outstanding -= repay; | |
if (loan.outstanding > 0) { | |
loan.outstanding += loan.principal * loan.mroi * .01; | |
} | |
}) | |
month++; | |
total_outstanding = _.sumBy(loans, 'outstanding'); | |
} | |
} | |
const pay_by_high_rate_low_outstanding = (startLoans, emi) => { | |
const loans = _.cloneDeep(startLoans); | |
let total_outstanding = _.sumBy(loans, 'outstanding'); | |
let month = 0; | |
while (total_outstanding > 0) { | |
console.log(`month ${month} outstanding ${total_outstanding}`); | |
const open_loans = _.filter(_.orderBy(loans, ['mroi', 'outstanding'], ['desc', 'asc']), l => l.outstanding); | |
let available = emi; | |
for (const loan of open_loans) { | |
const need = loan.outstanding; | |
const pay = _.min([need, available]); | |
loan.outstanding -= pay; | |
available -= pay; | |
} | |
_.forEach(open_loans, loan => { | |
if (loan.outstanding > 0) { | |
loan.outstanding += loan.principal * loan.mroi * .01; | |
} | |
}) | |
month++; | |
total_outstanding = _.sumBy(loans, 'outstanding'); | |
} | |
} | |
const pay_by_low_rate = (startLoans, emi) => { | |
const loans = _.cloneDeep(startLoans); | |
let total_outstanding = _.sumBy(loans, 'outstanding'); | |
let month = 0; | |
while (total_outstanding > 0) { | |
console.log(`month ${month} outstanding ${total_outstanding}`); | |
const open_loans = _.filter(_.orderBy(loans, ['mroi', 'outstanding'], ['asc', 'desc']), l => l.outstanding); | |
let available = emi; | |
for (const loan of open_loans) { | |
const need = loan.outstanding; | |
const pay = _.min([need, available]); | |
loan.outstanding -= pay; | |
available -= pay; | |
} | |
_.forEach(open_loans, loan => { | |
if (loan.outstanding > 0) { | |
loan.outstanding += loan.principal * loan.mroi * .01; | |
} | |
}) | |
month++; | |
total_outstanding = _.sumBy(loans, 'outstanding'); | |
} | |
} | |
const pay_by_high_rate_high_outstanding = (startLoans, emi) => { | |
const loans = _.cloneDeep(startLoans); | |
let total_outstanding = _.sumBy(loans, 'outstanding'); | |
let month = 0; | |
while (total_outstanding > 0) { | |
console.log(`month ${month} outstanding ${total_outstanding}`); | |
const open_loans = _.filter(_.orderBy(loans, ['mroi', 'outstanding'], ['desc', 'desc']), l => l.outstanding); | |
let available = emi; | |
for (const loan of open_loans) { | |
const need = loan.outstanding; | |
const pay = _.min([need, available]); | |
loan.outstanding -= pay; | |
available -= pay; | |
} | |
_.forEach(open_loans, loan => { | |
if (loan.outstanding > 0) { | |
loan.outstanding += loan.principal * loan.mroi * .01; | |
} | |
}) | |
month++; | |
total_outstanding = _.sumBy(loans, 'outstanding'); | |
} | |
} | |
const pay_by_positive_rate_low_outstanding = (startLoans, emi) => { | |
const loans = _.cloneDeep(startLoans); | |
let total_outstanding = _.sumBy(loans, 'outstanding'); | |
let month = 0; | |
while (total_outstanding > 0) { | |
console.log(`month ${month} outstanding ${total_outstanding}`); | |
const [positive_loans, zero_loans] = _.partition(loans, l => l.mroi > 0); | |
const open_loans = _.filter([..._.orderBy(positive_loans, ['outstanding'], ['asc']), ...zero_loans], l => l.outstanding); | |
let available = emi; | |
for (const loan of open_loans) { | |
const need = loan.outstanding; | |
const pay = _.min([need, available]); | |
loan.outstanding -= pay; | |
available -= pay; | |
} | |
_.forEach(open_loans, loan => { | |
if (loan.outstanding > 0) { | |
loan.outstanding += loan.principal * loan.mroi * .01; | |
} | |
}) | |
month++; | |
total_outstanding = _.sumBy(loans, 'outstanding'); | |
} | |
} | |
const algos = { | |
a: pay_all_proportionally, | |
b: pay_by_high_rate_low_outstanding, | |
c: pay_by_high_rate_high_outstanding, | |
d: pay_by_positive_rate_low_outstanding, | |
e: pay_by_low_rate | |
} | |
const main = (algoText, installmentText) => { | |
const installment = +installmentText; | |
const { data: loans } = Papa.parse(fs.readFileSync('./loans.txt', 'utf8'), { header: true, dynamicTyping: true }) | |
if(!algoText) { | |
console.log(`usage ${_.keys(algos).join('|')} emi_amount`); | |
console.log(algos); | |
return; | |
} | |
const algo = algos[algoText]; | |
algo(loans, installment); | |
} | |
main(...process.argv.slice(2)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment