Skip to content

Instantly share code, notes, and snippets.

@dontfreakout
Forked from filiph/distribute.js
Last active August 29, 2015 14:19
Show Gist options
  • Save dontfreakout/77229ae84cb9e2d88dc1 to your computer and use it in GitHub Desktop.
Save dontfreakout/77229ae84cb9e2d88dc1 to your computer and use it in GitHub Desktop.
// Takes [count] of items and the [partition] (array of percentages) to
// distribute against. Returns an array of integers that sums to [count]:
// an integer composition weighted by the partition.
//
// We don't use the Bresenham algorithm because it doesn't provide the best
// results for low values of [count].
function DISTRIBUTE(count, partition) {
// Custom function in Apps Script takes a 2D array. We're only interested in
// the first row.
partition = partition[0];
// First, distribute rounded down, but keep the remainders for each bin.
var result = [];
var remainders = [];
var alreadyDistributedCount = 0;
for (var i = 0; i < partition.length; i++) {
var currentCount = Math.floor(partition[i] * count);
var remainder = partition[i] * count - currentCount;
result.push(currentCount);
remainders.push(remainder);
alreadyDistributedCount += currentCount;
}
// Now iteratively add [partition] values to corresponding remainders.
var j = 0;
while (alreadyDistributedCount < count) {
remainders[j] += partition[j];
if (remainders[j] > 1) {
result[j] += 1;
remainders[j] -= 1;
alreadyDistributedCount += 1;
}
j += 1;
if (j >= partition.length) j = 0;
}
// Apps Script expects 2D array output. We only provide one row.
return [result];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment