Skip to content

Instantly share code, notes, and snippets.

@SiestaMadokaist
Created February 13, 2018 08:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SiestaMadokaist/e93742e31f7d9f0eb2d2cc2a19dfd9f8 to your computer and use it in GitHub Desktop.
Save SiestaMadokaist/e93742e31f7d9f0eb2d2cc2a19dfd9f8 to your computer and use it in GitHub Desktop.
FundBalancing
const FundData = require('./FundData');
class FundBalancer {
constructor(){
this.state = { data: [] }
};
insert({ owner, current, expected }){
const fd = new FundData({ owner, current, expected });
this.data().push(fd);
}
data(){
return this.state.data;
}
transferables(){
return this.data().sort(FundData.compare);
}
static isEquilibrium(transferables){
for(let t of transferables){
if(t.hasTransferable()){ return false; }
}
return true;
}
transferActions(){
const transferables = this.transferables();
const actions = [];
while(!FundBalancer.isEquilibrium(transferables)){
let source = transferables.shift();
let destination = transferables.pop();
let transferValue = Math.min(source.transferValue(), destination.transferValue())
let action = { source: source.owner(), destination: destination.owner(), transferValue }
let sourceAfter = source.afterAction(action);
let destinationAfter = destination.afterAction(action);
actions.push(action);
transferables.push(sourceAfter);
transferables.push(destinationAfter);
transferables.sort(FundData.compare);
};
return { actions, transferables};
}
}
module.exports = FundBalancer;
class FundData {
static compare(fd1, fd2){
return fd2.transferable() - fd1.transferable();
}
constructor({ owner, current, expected, buffer = 0 }){
this.props = { owner, current, expected, buffer };
}
current(){
return this.props.current;
}
expected(){
return this.props.expected;
}
owner(){
return this.props.owner;
}
buffer(){
return this.props.buffer;
}
hasTransferable(){
return this.transferable() > this.buffer();
}
transferable(){
return this.props.current - this.props.expected;
}
transferValue(){
return Math.abs(this.transferable());
}
afterAction(action){
if(this.owner() === action.source){
const amount = this.current() - action.transferValue;
return new FundData({ owner: this.owner(), current: amount, expected: this.expected() });
} else if(this.owner() === action.destination){
const amount = this.current() + action.transferValue;
return new FundData({ owner: this.owner(), current: amount, expected: this.expected() });
};
}
}
module.exports = FundData;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment