Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #11 (permalink)  
Старый 12.06.2018, 02:37
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,075

равномерное распределение суммы
вариант на котором остановился, если есть замечания напишите, всем откликнушимся большое спасибо!!!
<script>
function allocate(input, total) {
  const output = [];
  const length = input.length;
  const order = input.map((value, index) => ({value,index}));
  const sortedOrder = order.sort((a, b) => a.value - b.value);
  for (let i = 0; i < length; i++) {
    let {value,index} = sortedOrder[i];
    let num = Math.floor(total/(length - i))
    if(num > value) num = value;
    total -= num;
    output[index] = num
  }
  return output
};

let input = [5,10,0,12];
for (let total = 0; total < 41; total++) {
    let output = allocate(input, total)
    document.write(`${total}=>${output}<br>`)
}
  </script>

Последний раз редактировалось рони, 12.06.2018 в 08:39. Причина: добавлено const length
Ответить с цитированием
  #12 (permalink)  
Старый 12.06.2018, 04:52
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,005

Сообщение от рони
если есть замечания напишите
Можно немного уменьшить объём вспомогательной памяти, если создать отсортированную копию интпута, по ней за один обход вычислить максимум, за второй обход уже расставить значения. Тогда, вроде бы, и арифметика вся будет целочисленной, без делений и округлений
Ответить с цитированием
  #13 (permalink)  
Старый 12.06.2018, 06:45
Аватар для Белый шум
Профессор
Отправить личное сообщение для Белый шум Посмотреть профиль Найти все сообщения от Белый шум
 
Регистрация: 19.01.2012
Сообщений: 498

Alexandroppolus,
Максимум можно получить с помощью Math.max(), но чем это поможет - что-то не вдупляю.

рони,
Проход хоть и один, но для каждого элемента массива выполняется деление - сложная операция, по идее. Хотя я хз как там процессоры внутри работают, может им это и проще чем пару лишних проходов сделать.
Ответить с цитированием
  #14 (permalink)  
Старый 12.06.2018, 08:33
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,075

Alexandroppolus,

Сообщение от Alexandroppolus
если создать отсортированную копию интпута
есть sortedOrder

Сообщение от Alexandroppolus
вычислить максимум
max = sortedOrder.slice(-1)[0].value
и как это использовать?
Ответить с цитированием
  #15 (permalink)  
Старый 18.06.2018, 13:02
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,005

рони,
я про тот "максимум", который можно отсыпать в output[i]

вот, изобразил слова в г-коде. Идея в принципе та же, но нет деления на каждой итерации (есть только целочисленное умножение), и дополнительной памяти только массив целых чисел, а не массив объектов. Не знаю, насколько это сможет ускорить, проверять было лень

function allocate(input, total) {
    var output = [];
    var length = input.length;
    var sortedInput = input.slice().sort(function (a, b) { return a - b; });
    var lastValue = 0;
    var maxH = 0;
    var remainder = 0;

    for (var i = 0; total > 0 && i < length; ++i) {
        var item = sortedInput[i];
        var height = item - lastValue;
        if (height > 0) {
            lastValue = item;
            var width = length - i;
            var area = width * height;
            if (total < area) {
                height = Math.floor(total / width);
                remainder = total % width;
            }
            maxH += height;
            total -= area;
        }
    }
    for (var i = 0; i < length; ++i) {
        var item = input[i];
        output.push(item > maxH ? maxH + (--remainder >= 0 ? 1 : 0) : item);
    }
    return output
}

// проверка для разных total
var input = [5,10,0,12, 7, 3];
for (var total = 0; total < 41; total++) {
    var output = allocate(input, total);
    console.log(`${total} => ${output}`);
}


см. консоль
Ответить с цитированием
  #16 (permalink)  
Старый 18.06.2018, 15:21
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,075

Alexandroppolus,
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как передать в массив перемеенную как ключ массива? фдуч Общие вопросы Javascript 15 11.01.2018 21:21
Как обработать переданные функции параметры как массив? javascript_pupil Общие вопросы Javascript 7 19.08.2016 13:59
Массив не принимает значение переменной как ключ wet jQuery 5 04.08.2016 08:30
Константный массив, как приватное поле класса AndreyMG Общие вопросы Javascript 1 13.05.2016 19:54
Как можно методом ajax вернуть ассоциативный массив js? Hurray AJAX и COMET 2 09.01.2016 00:19