Skip to content

Instantly share code, notes, and snippets.

@t8g
Last active February 16, 2018 11:46
Show Gist options
  • Save t8g/e1036fdd95e49043bb9be2eb556a3750 to your computer and use it in GitHub Desktop.
Save t8g/e1036fdd95e49043bb9be2eb556a3750 to your computer and use it in GitHub Desktop.
Partage des frais
interface Friend {
id: number;
name: string;
expense: number;
}
interface Transaction {
from: number;
to: number;
value: number;
}
const friends: Array<Friend> = [
{ id: 1, name: "paul", expense: 13 },
{ id: 2, name: "marc", expense: 21 },
{ id: 3, name: "marie", expense: 30 },
{ id: 4, name: "jane", expense: 15 },
{ id: 5, name: "cresus", expense: 77 }
];
function averageExpense(friends: Array<Friend>): number {
return friends.reduce(
(acc: number, friend: Friend) => acc + friend.expense / friends.length,
0
);
}
function addExpense(friend: Friend, expense: number): Friend {
return { ...friend, expense: friend.expense + expense };
}
function groupById(friends: Array<Friend>): { [id: number]: Friend } {
return friends.reduce(
(acc, friend) => ({
...acc,
[friend.id]: friend
}),
{}
);
}
function friendTransactions(
friend: Friend,
friends: { [id: number]: Friend },
avg: number
): { transactions: Array<Transaction>; friends: { [id: number]: Friend } } {
let due = avg - friend.expense;
if (due <= 0) return { transactions: [], friends };
let transactions = [];
friends = Object.keys(friends)
.map(id => parseInt(id, 10))
.reduce((acc, fid) => {
const value = Math.min(
avg - acc[friend.id].expense,
acc[fid].expense - avg
);
if (acc[fid].expense < avg || value === 0) return acc;
transactions = [...transactions, { from: friend.id, to: fid, value }];
return {
...acc,
[fid]: addExpense(acc[fid], -value),
[friend.id]: addExpense(acc[friend.id], value)
};
}, friends);
return { transactions, friends };
}
function transactions(friends: Array<Friend>): Array<Transaction> {
let transactions = [];
const avg = averageExpense(friends);
let fdb = groupById(friends);
friends.forEach((friend: Friend) => {
let tf = friendTransactions(friend, fdb, avg);
fdb = tf["friends"];
transactions = [...transactions, ...tf["transactions"]];
});
return transactions;
}
console.log(friends, transactions(friends));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment