Files
lynchmark/tests/7_scheduler/outputs/stealth_union-alpha EFF_high.js
2026-09-16 16:14:56 +00:00

49 lines
1.8 KiB
JavaScript

async function findAvailableSlots(cal1, cal2, constraints) {
const { DateTime } = await import('https://esm.sh/luxon@3.4.4');
const { durationMinutes, searchRange, workHours } = constraints;
const s = DateTime.fromISO(searchRange.start, { zone: 'utc' });
const e = DateTime.fromISO(searchRange.end, { zone: 'utc' });
const dur = { minutes: durationMinutes };
const busy = [...cal1, ...cal2]
.map(x => [DateTime.fromISO(x.start, { zone: 'utc' }), DateTime.fromISO(x.end, { zone: 'utc' })])
.filter(([a, b]) => b > s && a < e)
.map(([a, b]) => [a < s ? s : a, b > e ? e : b])
.sort((a, b) => a[0] - b[0]);
const merged = [];
for (const [a, b] of busy) {
const last = merged[merged.length - 1];
if (!last || a > last[1]) merged.push([a, b]);
else if (b > last[1]) last[1] = b;
}
const [wsh, wsm] = workHours.start.split(':').map(Number);
const [weh, wem] = workHours.end.split(':').map(Number);
const slots = [];
for (let day = s.startOf('day'); day <= e; day = day.plus({ days: 1 })) {
const ws = day.set({ hour: wsh, minute: wsm, second: 0, millisecond: 0 });
const we = day.set({ hour: weh, minute: wem, second: 0, millisecond: 0 });
const winS = ws < s ? s : ws;
const winE = we > e ? e : we;
if (winS >= winE) continue;
let cur = winS;
for (const [a, b] of merged) {
if (b <= cur) continue;
if (a >= winE) break;
if (a > cur) add(cur, a < winE ? a : winE);
if (b > cur) cur = b > winE ? winE : b;
if (cur >= winE) break;
}
if (cur < winE) add(cur, winE);
}
function add(a, b) {
let t = a;
while (t.plus(dur) <= b) {
const n = t.plus(dur);
slots.push({ start: t.toUTC().toISO(), end: n.toUTC().toISO() });
t = n;
}
}
return slots;
}
export default findAvailableSlots;
// Generation time: 191.955s
// Result: PASS