function placeLabels(placement, startBound, endBound, labelSize) {
placement.sort((a, b) => a - b);
let N = placement.length;
let M = endBound - startBound + 1;
let dp = Array(N)
.fill(0)
.map(() => Array(M).fill(Infinity));
let path = Array(N)
.fill(0)
.map(() => Array(M).fill(0));
for (let j = 0; j < M; j++) {
dp[0][j] = Math.abs(placement[0] - (startBound + j));
}
for (let i = 1; i < N; i++) {
let minPrevRow = { val: Infinity, pos: -1 };
for (let j = 0; j < M; j++) {
while (minPrevRow.pos < j - labelSize) {
minPrevRow.pos++;
minPrevRow.val = Math.min(minPrevRow.val, dp[i - 1][minPrevRow.pos]);
}
dp[i][j] = minPrevRow.val + Math.abs(placement[i] - (startBound + j));
path[i][j] = minPrevRow.pos;
}
}
let minCost = Infinity,
pos = -1;
for (let j = 0; j < M; j++) {
if (dp[N - 1][j] < minCost) {
minCost = dp[N - 1][j];
pos = j;
}
}
let newPlacement = [];
for (let i = N - 1; i >= 0; i--) {
newPlacement[i] = startBound + pos;
pos = path[i][pos];
}
return newPlacement;
}