Skip to content

Instantly share code, notes, and snippets.

@AleksandrHovhannisyan
Created May 9, 2022 17:34
Show Gist options
  • Save AleksandrHovhannisyan/46cee5f65d3114e44988422f5654c564 to your computer and use it in GitHub Desktop.
Save AleksandrHovhannisyan/46cee5f65d3114e44988422f5654c564 to your computer and use it in GitHub Desktop.
cassidoo-may-2022-challenge
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