Search code examples
algorithmschedule

On-call Scheduling Algorithm


First question posted here, I appreciate the help in advance!

DS for shift:

{
    hourStart: 0,
    hourEnd: 23,
    primaryOnCall: "dpeters@example.com",
    secondaryOnCall: "mfurgeson@example.com",
}

GIVEN there is always a "default" shift for hours 0-23, n number of shifts which may overlap each other, and earliest shift takes highest priority (other than default). Shifts may overlap to the next day. Return a new array of shifts that cover the the entire day.

example input:

[
    {
        hourStart: 0,
        hourEnd: 23,
        primaryOnCall: "dpeters@example.com",
        secondaryOnCall: "mfurgeson@example.com",
    },
    {
        hourStart: 18,
        hourEnd: 2,
        primaryOnCall: "mfrugal@example.com",
        secondaryOnCall: "ismith@example.com",
    },
    {
        hourStart: 07,
        hourEnd: 15,
        primaryOnCall: "jswanson@example.com",
        secondaryOnCall: "hcotel@example.com",
    }
]

example output (needn't be sorted):

[
    {
        hourStart: 0,
        hourEnd: 2,
        primaryOnCall: "mfrugal@example.com",
        secondaryOnCall: "ismith@example.com",
    },
    {
        hourStart: 3,
        hourEnd: 6,
        primaryOnCall: "dpeters@example.com",
        secondaryOnCall: "mfurgeson@example.com",
    },
    {
        hourStart: 7,
        hourEnd: 15,
        primaryOnCall: "jswanson@example.com",
        secondaryOnCall: "hcotel@example.com",
    },
    {
        hourStart: 16,
        hourEnd: 17,
        primaryOnCall: "dpeters@example.com",
        secondaryOnCall: "mfurgeson@example.com",
    },
    {
        hourStart: 18,
        hourEnd: 23,
        primaryOnCall: "mfrugal@example.com",
        secondaryOnCall: "ismith@example.com",
    },
]

One of my colleagues suggested brute forcing it by creating a hashmap of every hour in the day and then looping through that at the end to recreate schedules. It would help if anything was fixed (always only 3 shifts in a day, schedules don't overlap, priority of what overlaps doesn't matter) but none are at play here. Again, thank you for reading and I look forward to seeing your responses!


Solution

  • One thing is that there are only 24 hours in a day, so you can just create a table with 24 slots (henceforth referred to as TimeSlot) and each slot could have an entry with a priority number. These entries are smaller constituents of shifts. Each entry is labelled with priority by the shift's starting hour. One can set the default shift to have a priority of +∞ so that it always gets the least priority.

    E.g.

    Decide the default shift if hourStart == 0 && hourEnd == 23. Now iterate over this shift's hours and insert them into the TimeSlot, hour by hour

    [Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞)]
    

    Move to the next slot, from 18 to 2, Now the TimeSlot looks like

    [S1(18), S1(18), S1(18), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), Def(+∞), S1(18), S1(18), S1(18), S1(18), S1(18), S1(18), S1(18)]
    

    since all the default slots are of lower priority than S1.

    Move to the next slot, from 7 to 15, Now the TimeSlot looks like

    [S1(18), S1(18), S1(18), Def(+∞), Def(+∞), Def(+∞), Def(+∞), S2(7), S2(7), S2(7), S2(7), S2(7), S2(7), S2(7), S2(7), S2(7), Def(+∞), S1(18), S1(18), S1(18), S1(18), S1(18), S1(18), S1(18)]
    

    again replacing all the default slots with (and even S1 if there was such an overlap) S2.

    That's it. You have the schedule.