Skip to content

Instantly share code, notes, and snippets.

@AlexKratky
Created June 5, 2022 12:39
Show Gist options
  • Select an option

  • Save AlexKratky/e272bf37dc1640de16725ce9173cb0cf to your computer and use it in GitHub Desktop.

Select an option

Save AlexKratky/e272bf37dc1640de16725ce9173cb0cf to your computer and use it in GitHub Desktop.
Get peak (maximum usage) of items at one moment depending on start and end date

This solution is for finding the peak (or you can call it maximum usage at one moment) of items depending on date ranges (which can be for example reservations).

Usage is as I mentioned for instance in the reservations system. Example case: You have a reservation system with items and multiple warehouses, in the first location, you have 25 items and you want to move part of them to another location, however, there are multiple upcoming reservations in the first location, so you just need to check, if in the first location will be enough items for that reservation after you transport a certain amount of items (which will lower the amount in the first location). The first solution that comes to mind is to sum all amounts of upcoming reservations, but that will only work if all reservations overlap each other, otherwise, the sum can be even higher than the total sum of all items. Using this solution you will find max usage at one moment.

Princip is very simple, every peak is at the start of some reservation, so we take every start of reservation and select all that overlaps that start and we sum the amount and get one of the peaks, last step is to sort peaks to find the highest one.

I have vizualize a few scenarios that this algorithm covers: https://docs.google.com/spreadsheets/d/1mCY0t9CESu2bMBcHwvpeG66vOCFx5oZXFwTYtFQYsNc/edit?usp=sharing

scenario1:

image

scenario2:

image

scenario3:

image

scenario4:

image

const getDateFromDay = (day, hours = 15, minutes = 0, seconds = 0) => {
let d = new Date();
d.setDate(day);
d.setHours(hours)
d.setMinutes(minutes)
d.setSeconds(seconds)
d.setMilliseconds(0)
return d;
}
/**
* @see https://docs.google.com/spreadsheets/d/1mCY0t9CESu2bMBcHwvpeG66vOCFx5oZXFwTYtFQYsNc/edit?usp=sharing
*/
const scenario1 = [
{
name: 'Blue',
amount: 7,
start: getDateFromDay(1),
end: getDateFromDay(15),
},
{
name: 'Yellow',
amount: 4,
start: getDateFromDay(2),
end: getDateFromDay(4),
},
{
name: 'Red',
amount: 4,
start: getDateFromDay(7),
end: getDateFromDay(10),
},
{
name: 'Pink',
amount: 3,
start: getDateFromDay(12),
end: getDateFromDay(15),
},
{
name: 'Green',
amount: 3,
start: getDateFromDay(4),
end: getDateFromDay(7),
},
{
name: 'Black',
amount: 6,
start: getDateFromDay(6),
end: getDateFromDay(14),
},
];
const scenario2 = [
{
name: 'Red',
amount: 1,
start: getDateFromDay(1),
end: getDateFromDay(2),
},
{
name: 'Green',
amount: 4,
start: getDateFromDay(1),
end: getDateFromDay(2),
},
{
name: 'Yellow',
amount: 3,
start: getDateFromDay(1),
end: getDateFromDay(2),
},
{
name: 'Black',
amount: 4,
start: getDateFromDay(1),
end: getDateFromDay(2),
},
{
name: 'Gray',
amount: 5,
start: getDateFromDay(1),
end: getDateFromDay(2),
},
{
name: 'Pink',
amount: 5,
start: getDateFromDay(1),
end: getDateFromDay(2),
},
{
name: 'Lime',
amount: 21,
start: getDateFromDay(3),
end: getDateFromDay(15),
},
];
const scenario3 = [
{
name: 'Cyan',
amount: 6,
start: getDateFromDay(1),
end: getDateFromDay(4),
},
{
name: 'Gray',
amount: 14,
start: getDateFromDay(1),
end: getDateFromDay(3),
},
{
name: 'Pink',
amount: 3,
start: getDateFromDay(8),
end: getDateFromDay(15),
},
{
name: 'Dark Red',
amount: 4,
start: getDateFromDay(9),
end: getDateFromDay(13),
},
{
name: 'Light Yellow',
amount: 3,
start: getDateFromDay(9),
end: getDateFromDay(12),
},
{
name: 'Black',
amount: 4,
start: getDateFromDay(9),
end: getDateFromDay(12),
},
{
name: 'Olive',
amount: 4,
start: getDateFromDay(9),
end: getDateFromDay(12),
},
{
name: 'Lime',
amount: 5,
start: getDateFromDay(9),
end: getDateFromDay(12),
},
];
const scenario4 = [
{
name: 'Blue',
amount: 7,
start: getDateFromDay(1),
end: getDateFromDay(15),
},
{
name: 'Yellow',
amount: 4,
start: getDateFromDay(2),
end: getDateFromDay(4),
},
{
name: 'Red',
amount: 4,
start: getDateFromDay(7),
end: getDateFromDay(10),
},
{
name: 'Pink',
amount: 3,
start: getDateFromDay(12),
end: getDateFromDay(15),
},
{
name: 'Green',
amount: 3,
start: getDateFromDay(4),
end: getDateFromDay(7),
},
{
name: 'Black',
amount: 6,
start: getDateFromDay(7),
end: getDateFromDay(14),
},
{
name: 'Brown',
amount: 3,
start: getDateFromDay(13),
end: getDateFromDay(14),
},
{
name: 'Purple',
amount: 5,
start: getDateFromDay(13),
end: getDateFromDay(14),
},
];
const scenarios = [scenario1, scenario2, scenario3, scenario4];
for (const [index, scenario] of scenarios.entries()) {
let peaks = [];
for (const reservation of scenario) {
let p = reservation.amount;
const entries = [reservation];
const others = scenario.filter(el => el.name !== reservation.name && (reservation.start >= el.start && reservation.start <= el.end))
for (const other of others) {
p += other.amount;
entries.push(other)
}
peaks.push({
amount: p,
entries,
reservation
})
}
peaks = peaks.map(el => { return {amount: el.amount, entries: el.entries.map(entry => entry.name), date: el.reservation.start}}).sort((a, b) => b.amount - a.amount);
console.log(`Peaks for scenario${index+1}: `, peaks);
console.log('')
if (index === 0) {
console.log((peaks[0].amount === 20 ? ' ✅' : ' ❌') + ` scenario1 has amount ${peaks[0].amount}/20`)
}
if (index === 1) {
console.log((peaks[0].amount === 22 ? ' ✅' : ' ❌') + ` scenario1 has amount ${peaks[0].amount}/22`)
}
if (index === 2) {
console.log((peaks[0].amount === 23 ? ' ✅' : ' ❌') + ` scenario1 has amount ${peaks[0].amount}/23`)
}
if (index === 3) {
console.log((peaks[0].amount === 24 ? ' ✅' : ' ❌') + ` scenario1 has amount ${peaks[0].amount}/24`)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment