Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 19.07.2021, 16:31
Аспирант
Отправить личное сообщение для dc65k Посмотреть профиль Найти все сообщения от dc65k
 
Регистрация: 19.05.2020
Сообщений: 46

Как правильно решить задачу про диапазоны часов?
Всем привет. Недавно увидел задачу, написал небольшое решение. Подскажите, как более правильно её решить?
Дан список отсутствий работников на рабочем месте, например [9,10] - с 9:00 до 10:00
Требуется вывести диапазоны часов, когда все работники были на местах. Рабочий день: 9-18 ч
input:
    [
        [9, 10],
        [15, 17],
        [14, 16],
    ]

output:
    [
        [10, 14],
        [17, 18],
    ]


Моё решение:

/*
input:
    [
        [9, 10],
        [15, 17],
        [14, 16],
    ]

output:
    [
        [10, 14],
        [17, 18],
    ]
*/

const input = [
    [9, 10], // 10 - 18
    [15, 17], // 9 - 15 // 17 - 18
    [14, 16], // 9 - 14 // 16 - 18
];

const getWorkTime = (input) => {

    const obj = {};

    for (let i = 9; i <= 18; i++) {
        obj[i] = 0;
    }

    for (const value of input) {
        obj[value[0]] += 1;
        obj[value[1]] += 1;
    }

    let isNegative = false;

    let item = [];

    const keys = Object.keys(obj);

    const output = keys.reduce((accumulator, currentValue, index, array) => {

        if (obj[currentValue] === 0) {

            isNegative = true;

            if (isNegative) {
                item.push(currentValue);
            }

        } else {
            isNegative = false;
        }

        if (!isNegative && item.length) {
            accumulator.push(item);
            item = [];
        }

        if (index === keys.length - 1) {
            accumulator.push(item);
        }

        return accumulator;
    }, []);

    return output.map((currentValue) => {
        return [Number(currentValue[0]) - 1, Number(currentValue[output.length]) + 1];
    }).map((currentValue) => {

        if (!currentValue[1]) {
            currentValue[1] = currentValue[0] + 1;
        }

        return currentValue;
    });
}

console.log(getWorkTime(input));

Последний раз редактировалось dc65k, 19.07.2021 в 16:34.
Ответить с цитированием
  #2 (permalink)  
Старый 19.07.2021, 17:15
Аватар для ksa
ksa ksa вне форума
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,228

Сообщение от dc65k
Требуется вывести диапазоны часов, когда все работники были на местах. Рабочий день: 9-18 ч
Ищи максимальное "снизу" и минимальное "сверху"...
Ответить с цитированием
  #3 (permalink)  
Старый 19.07.2021, 17:19
Аватар для ksa
ksa ksa вне форума
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,228

dc65k, текста у тебя дофига... Все в одном цикле можно сделать.
Ответить с цитированием
  #4 (permalink)  
Старый 19.07.2021, 18:30
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,126

dc65k,
<script>
/*
input:
    [
        [9, 10],
        [15, 17],
        [14, 16],
    ]
output:
    [
        [10, 14],
        [17, 18],
    ]
*/
const input = [
        [9, 10],
        [15, 17],
        [14, 16]
        ];
const getWorkTime = (input, min, max) => {
    let ar = [], temp = [], push;
    for (let i = min; i <= max; i++) {
        let clear = input.some(([a, b]) => i >= a && i < b);
        let len = temp.length;
        if (clear) {
            if (len) {
                temp[1] = i;
                temp = [];
                push = false;
            }
        } else temp[+!!len] = i;
        if (temp.length == 2 && !push) {
        ar.push(temp);
        push = true;
        }
    }
    return ar
}
let a = getWorkTime(input, 9, 18);
document.write(JSON.stringify(a))
    </script>
Ответить с цитированием
  #5 (permalink)  
Старый 20.07.2021, 01:17
Аватар для Vlasenko Fedor
Профессор
Отправить личное сообщение для Vlasenko Fedor Посмотреть профиль Найти все сообщения от Vlasenko Fedor
 
Регистрация: 13.03.2013
Сообщений: 1,572

<script>
const res = [];
const workTime = [9, 18];
const input = [
    [9, 10],
    [15, 17],
    [14, 16],
];
let [start, end] = workTime;
input.sort((a, b) => b[1] - a[1]).forEach(([a, b]) => {
    if (b < end) res.push([b, end]);
    end = Math.min(a, end);
});
if (end > start) res.push([start, end]);
document.write(JSON.stringify(res.sort(([a], [b]) => a - b)));
</script>

Вариант

Последний раз редактировалось Vlasenko Fedor, 20.07.2021 в 01:59. Причина: Причесал
Ответить с цитированием
  #6 (permalink)  
Старый 20.07.2021, 05:55
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,012

Сообщение от Vlasenko Fedor
Вариант
Если не ошибаюсь, можно идти от старта, тогда не придется сортировать второй раз
<script>
const res = [];
const workTime = [9, 18];
const input = [
    [9, 10],
    [15, 17],
    [14, 17.4],
];
let [start, end] = workTime;
input.sort(([a], [b]) => a - b).forEach(([a, b]) => {
    if (start < a) res.push([start, a]);
    start = Math.max(start, b);
});
if (start < end) res.push([start, end]);
document.write(JSON.stringify(res));
</script>
Ответить с цитированием
  #7 (permalink)  
Старый 20.07.2021, 08:42
Аватар для Vlasenko Fedor
Профессор
Отправить личное сообщение для Vlasenko Fedor Посмотреть профиль Найти все сообщения от Vlasenko Fedor
 
Регистрация: 13.03.2013
Сообщений: 1,572

Alexandroppolus,

4.2.2. Составление расписания стр 61
Олимпиадное программирование. / пер. с англ. А. А. Слинкин – М.:
ДМК Пресс, 2018. – 300 с.: ил.
ISBN 978-5-97060-644-5

идея – отсортировать события по времени конца и выбирать в
качестве следующего событие, которое заканчивается как можно раньше.
Оказывается, что этот алгоритм всегда дает оптимальное решение.

Alexandroppolus,
твой вариант лучше, не увидел коллизий, в этом примере

Последний раз редактировалось Vlasenko Fedor, 20.07.2021 в 11:53.
Ответить с цитированием
Ответ



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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как правильно работать с порядком вывода в React? gsdev99 Элементы интерфейса 1 28.01.2020 17:55
Как правильно сделать бесконечный скролл с автоматической загрузкой контента (React.j darktowerk56c Элементы интерфейса 1 07.10.2019 15:56
Как правильно создать объект из строки- (native javascript)? s24344 Элементы интерфейса 2 26.08.2018 11:19
Пасоны, как правильно парсить параметры? megaupload Оффтопик 15 05.05.2013 14:44
Как правильно послать XML в POST запросе LowCoder AJAX и COMET 10 15.07.2009 23:20