function disperse(values, threshold, range) {
var delta = Array.apply(null, { length: values.length }).map(function () { return 0; }),
converged = false;
while (!converged) {
converged = true;
delta = delta.map(function (d, i, dd) {
if (i < dd.length - 1 && dd.length > 1 && values[i + 1] + dd[i + 1] - values[i] - d < threshold) {
converged = false;
dd[i + 1] += 1;
return d - 1;
}
return d;
});
}
converged = false;
while (!converged) {
converged = true;
delta = delta.map(function (d, i) {
var space;
if (i < delta.length - 2) {
space = values[i + 1] + delta[i + 1] - values[i] - d;
if (d < 0 && space > threshold) {
converged = false;
return d + space - threshold;
}
}
return d;
});
}
delta.reduce(function (r, d, i, dd) {
if (values[i] + d < r) {
dd[i] = r - values[i];
return r + threshold;
}
return values[i] + threshold + d;
}, range[0]);
delta.reduceRight(function (r, d, i, dd) {
if (values[i] + d > r) {
dd[i] = r - values[i];
return r - threshold;
}
return values[i] + d;
}, range[1]);
return values.map(function (v, i) {
return v + delta[i];
});
}
document.write('<pre>' + JSON.stringify(disperse([5, 6, 8, 72, 76], 10, [0, 100]), 0, 4) + '</pre>');
document.write('<pre>' + JSON.stringify(disperse([5, 6, 7, 8, 72, 76], 10, [0, 100]), 0, 4) + '</pre>');
document.write('<pre>' + JSON.stringify(disperse([24, 28, 92, 94, 95], 10, [0, 100]), 0, 4) + '</pre>');