// алгоритм распределения положительного остатка
function spreadRemainder(result, remainder) {
// сортируем по убыванию, чтоб лучшие получали прибавку первыми
const sortedKeys = Object
.keys(result)
.sort((a, b) => result[b] - result[a]);
const length = sortedKeys.length;
let i = 0;
// пока остаётся остаток проходимся по сортированным значениям
while(remainder) {
const index = sortedKeys[i++ % length];
// уменьшаем остаток на единицу
remainder--;
// увеличиваем результат на единицу
result[index]++;
}
return result;
}
function split(sum, ...results) {
// общее количество часов
const sumResults = results.reduce((a, b) => a + b);
// целочисленно делим число на общее количество часов
const part = Math.floor(sum / sumResults);
// остаток от целочисленного деления
const remainder = sum % sumResults;
// каждые часы умножаем на результат деления
const result = results.map(hours => hours * part);
// если есть остаток
if(remainder)
spreadRemainder(result, remainder);
return result;
}
split(751, 12, 18, 13); // [ 210, 313, 228 ]
// алгоритм распределения остатков
function spreadDifference(result, difference) {
const keys = Object.keys(result);
const length = keys.length;
let i = 0;
// если остаток положительный
if (difference > 0) {
// сортируем по убыванию, чтоб лучшие получали прибавку первыми
keys.sort((a, b) => result[b] - result[a]);
// пока остаётся остаток проходимся по сортированным значениям
while(difference) {
// difference всегда меньше количества людей
// потому тут i++ не может убежать за пределы keys
const index = keys[i++];
// уменьшаем остаток на единицу
difference--;
// увеличиваем результат на единицу
result[index]++;
}
} else {
// сортируем по возрастанию, чтоб худшие получали минус первыми
keys.sort((a, b) => result[a] - result[b]);
// пока остаётся остаток проходимся по сортированным значениям
while(difference) {
// difference всегда меньше количества людей, однако
// из-за нулей возможно прохождения по keys несколько раз
const index = keys[i++ % length];
// результат - ноль, не отнимаем от нуля
if(result[index] === 0)
continue;
// увеличиваем остаток на единицу
difference++;
// уменьшаем результат на единицу
result[index]--;
}
}
return result;
}
function split(sum, ...results) {
// делим число на общее количество часов
const part = sum / results.reduce((a, b) => a + b);
// каждые часы умножаем на результат деления и округляем
const result = results.map(hours => Math.round(hours * part));
// финальная сумма с учётом округлений
const resultSum = result.reduce((a, b) => a + b);
// разница между финальной суммой и изначальной
let difference = sum - resultSum;
// если есть разница
if(difference)
spreadDifference(result, difference);
return result;
}
split(751, 12, 18, 13); // [ 210, 314, 227 ]
difference
при этом никогда не больше половины количества людей, т.е. равномерно нераспределим. show
параметр, включающий плавность. Если такого нет - переписать функцию show
, чтоб он там был.overlay
и что делает твой метод show
?'slow'
: overlay.show('slow')
, или любой другой из кучи вариантов, которых можно увидеть если посмотреть в документацию. resize
и ручная обработка или множество ResizeObserver
? Надо тестировать конкретный случай. Но, в случае множества меняющихся элементов, я бы всё равно использовал множество ResizeObserver
, потому что это проще и удобнее поддерживать, и только если бы это стало узким местом смотрел бы иные варианты. matchMedia
точно не нужно, ты делаешь это неправильно. На matchMedia
можно повесить слушателя onchange
(раньше addListener
) и он будет срабатывать только на изменение. for in
не юзаешь, конечно, чего делать не надо в любом случае.Object.defineProperty(cookies, 'get', {
value(domain) {
//...
},
configurable: true
});
this
в примере? Или fetch?Судя по всему ты вообще не знаешь javascript. Изучи основы, а потом возвращайся.
То что я тебе напишу ответ, вида:
тебе нифига не поможет, ты через 5 минут снова споткнёшься на ровном месте.