Javascript.RU

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

Задача про отель
Всем привет. Подскажите, верно ли я решил данную задачу?

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

const dates = [
    [1, 2],
    [1, 3],
    [2, 4],
    [2, 3],
]

const f = (arr) => {

    let acc = 0;

    let arrivalDate = arr.reduce((accumulator, currentValue) => {

        let key = currentValue[0]

        if (accumulator[key]) {
            accumulator[key] += 1
        } else {
            accumulator[key] = 1
        }

        return accumulator
    }, {});

    let departureDate = arr.reduce((accumulator, currentValue) => {

        let key = currentValue[1]

        if (accumulator[key]) {
            accumulator[key] += 1
        } else {
            accumulator[key] = 1
        }

        return accumulator
    }, {});

    for (let i = 0; i < arr.length; i++) {

        let current = arr[i];

        acc -= departureDate[current[1]];
        acc += arrivalDate[current[0]];
    }

    return acc;
}

console.log(f(dates));
Ответить с цитированием
  #2 (permalink)  
Старый 14.03.2022, 16:35
Аватар для ksa
ksa ksa вне форума
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,227

Предложу такой вариант...
const dt = [
    [1, 2],
    [1, 3],
    [2, 4],
    [2, 3],
]
let min = dt[0][0]
let max = dt[0][0]
dt.forEach(el => {
	min = Math.min(min, el[0])
	max = Math.max(max, el[1])
})
let t = 0
for (let i = min; i <= max; i++) {
	let c = 0
	dt.forEach(el => {
		if ((el[0] <= i) && (i < el[1])) ++c
	})
	alert(i + ' - ' + c)
	t = Math.max(t, c)
}
alert(t)
Ответить с цитированием
  #3 (permalink)  
Старый 14.03.2022, 19:07
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,123


const dt = [
    [1, 2],
    [1, 3],
    [2, 4],
    [2, 3]
]
let arr = dt.flat();
let min = Math.min(...arr);
let max = Math.max(...arr);

let t = 0;
for (let i = min; i <= max; i++) {
	let c = 0;
	dt.forEach(el => {
		if ((el[0] <= i) && (i < el[1])) ++c
	})
	alert(i + ' - ' + c)
	t = Math.max(t, c)
}
alert(t)


const dt = [
            [1, 2],
            [1, 3],
            [2, 4],
            [2, 3]
        ]
        let arr = dt.map(([a, b]) => Array.from({
            length: b - a
        }, (_, i) => a + i)).flat().sort((a, b) => a - b);

        let c = 0,
            t = 0,
            n;
        for (let i of arr) {
            if (i === n) c++;
            else {
                c = 1;
                n = i;
            }
            if (c > t) t = c;

        }

        alert(t)
Ответить с цитированием
  #4 (permalink)  
Старый 17.03.2022, 20:11
Аватар для Alexandroppolus
Профессор
Отправить личное сообщение для Alexandroppolus Посмотреть профиль Найти все сообщения от Alexandroppolus
 
Регистрация: 25.10.2016
Сообщений: 1,012

Сообщение от рони
Math.min(...arr)
на здоровенном массиве это свалится в переполнение стека.

----
мой вариант:
function getMaxCount(dates) {
    const sortedByBegin = dates.slice().sort((a, b) => a[0] - b[0]);
    const ends = dates.map(d => d[1]).sort((a, b) => a - b);

    let count = 0, endPos = 0;
    return sortedByBegin.reduce((max, date, i) => {
        // учитываем все выезды, которые были после предыдущей проверки
        while (endPos < ends.length && ends[endPos] <= date[0]) {
            count--;
            endPos++;
        }

        return Math.max(max, ++count);
    }, 0);
}

alert(getMaxCount([
    [1, 2],
    [1, 3],
    [2, 4],
    [2, 3]
]));


работает за O(N * ln(N)) времени и O(N) памяти, но при этом не закладывается на максимальные даты, плюс можно применить например для отрезков, у которых начало и конец вещественные. Универсально, в общем.

если интервалы уже отсортированы по дате заезда, то вторую строку лучше переписать так
const sortedByBegin = dates;
Ответить с цитированием
  #5 (permalink)  
Старый 17.03.2022, 21:33
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,123

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



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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Школьная задача про массив StasChis Общие вопросы Javascript 2 05.06.2020 23:16
Задача про шахматы и ферзей Ramundo Общие вопросы Javascript 1 12.07.2019 10:47
Задача про графы LunarionXIV Общие вопросы Javascript 0 23.12.2014 13:39
Задача про Drag-n-Drop eirnvn Общие вопросы Javascript 5 01.07.2013 18:50
Задача про квадрат и треугольник dawsonsky Javascript под браузер 0 20.09.2012 15:34