Created
May 9, 2022 17:34
-
-
Save AleksandrHovhannisyan/46cee5f65d3114e44988422f5654c564 to your computer and use it in GitHub Desktop.
cassidoo-may-2022-challenge
This file contains 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
let receipts = [ | |
{ name: "Ximena", paid: 45 }, | |
{ name: "Clara", paid: 130 }, | |
{ name: "Ximena", paid: 100 }, | |
{ name: "Cassidy", paid: 140 }, | |
{ name: "Cassidy", paid: 76 }, | |
{ name: "Clara", paid: 29 }, | |
{ name: "Ximena", paid: 20 }, | |
]; | |
const whoOwes = (receipts) => { | |
// Restructure the data for convenience. Get the total amounts paid by person as well as the total overall. | |
// Example: { total: 540, payments: { Clara: 159, Ximena: 165, Cassidy: 216 } } | |
const bill = receipts.reduce( | |
(bill, receipt) => { | |
if (!bill.payments[receipt.name]) { | |
bill.payments[receipt.name] = 0; | |
} | |
bill.total += receipt.paid; | |
bill.payments[receipt.name] += receipt.paid; | |
return bill; | |
}, | |
{ total: 0, payments: {} } | |
); | |
// We'll need this to distribute the total payments among the payers. | |
const numPeople = Object.keys(bill.payments).length; | |
// Sort payments in ascending order to match the expected output (Clara before Ximena). Smaller payments first. | |
const paymentsSorted = Object.fromEntries( | |
Object.entries(bill.payments).sort( | |
([_name1, payment1], [_name2, payment2]) => payment1 - payment2 | |
) | |
); | |
// Find the largest payment. This person is owed money by the remaining people. | |
// NOTE: This assumes that there is only one person owed money. | |
const maxPayment = { | |
name: Object.entries(paymentsSorted)[numPeople - 1][0], | |
amount: Object.entries(paymentsSorted)[numPeople - 1][1], | |
}; | |
// The amount each person should've actually paid if it had been distributed evenly | |
const evenPaymentPerPerson = bill.total / numPeople; | |
// Identify the people who owe money as well as the amounts they owe. Store in an intermediate result | |
// for further processing/logging. Example: { Clara: 21, Ximena: 15 }. | |
const amountsOwedByName = Object.keys(paymentsSorted).reduce( | |
(amountsOwedByName, name) => { | |
if (name === maxPayment.name) return amountsOwedByName; | |
const amountPaid = bill.payments[name]; | |
const amountOwed = evenPaymentPerPerson - amountPaid; | |
amountsOwedByName[name] = amountOwed; | |
return amountsOwedByName; | |
}, | |
{} | |
); | |
return Object.entries(amountsOwedByName) | |
.map( | |
([name, amountOwed]) => `${name} owes ${maxPayment.name} $${amountOwed}` | |
) | |
.join(", "); | |
}; | |
// 'Clara owes Cassidy $21, Ximena owes Cassidy $15' | |
console.log(whoOwes(receipts)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment