Examples:
Example 1: Recurrence, overlap (same room), boundary conflict, different-room overlap, availability, cancel, listing
MeetingRoomScheduler s = new MeetingRoomScheduler(2, 2); // rooms: 0,1 employees: 0,1
// Initially, both rooms are free.
s.getAvailableRooms(10, 12)
=> [0, 1]
// Book a recurring meeting in room 0:
// bookingId=b1, employee=0, room=0, start=10, duration=3 => [10,12]
// repeats every 5 for exactly 20 occurrences:
// occurrence starts: 10, 15, 20, ... , 10 + 19*5 = 105
// last occurrence interval: [105, 107]
s.bookRoom("b1", 0, 0, 10, 3, 5)
=> true
// Availability check: at time=12, room0 is busy due to b1's first occurrence [10,12]
s.getAvailableRooms(12, 12)
=> [1]
// Overlap in SAME room due to CLOSED interval boundary:
// b2 is [12,12] (duration=1) which overlaps b1's [10,12] at time=12
s.bookRoom("b2", 1, 0, 12, 1, 10)
=> false
// Another overlap in SAME room:
// b3 is [16,16], but b1 has an occurrence [15,17], so it overlaps
s.bookRoom("b3", 1, 0, 16, 1, 10)
=> false
// Different room can overlap in time freely:
// b4 in room 1: start=12, duration=2 => [12,13], repeats every 6 for 20 occurrences
// last occurrence starts at 12 + 19*6 = 126 => last interval [126,127]
s.bookRoom("b4", 1, 1, 12, 2, 6)
=> true
// Now, within [12,12], room0 is busy (b1) and room1 is busy (b4)
s.getAvailableRooms(12, 12)
=> []
// List first 5 occurrences for room 0 (only b1 exists there)
s.listBookingsForRoom(0, 5)
=> ["b1-10-12", "b1-15-17", "b1-20-22", "b1-25-27", "b1-30-32"]
// List first 4 occurrences for room 1 (only b4 exists there)
s.listBookingsForRoom(1, 4)
=> ["b4-12-13", "b4-18-19", "b4-24-25", "b4-30-31("")]
// Employee-wise listing (first 3 occurrences)
s.listBookingsForEmployee(0, 3)
=> ["b1-10-12", "b1-15-17", "b1-20-22"]
s.listBookingsForEmployee(1, 3)
=> ["b4-12-13", "b4-18-19", "b4-24-25("")]
// Cancel removes ALL 20 occurrences of that recurring booking
s.cancelBooking("b1")
=> true
// Now room0 is free in [10,12], but room1 is still busy at 12 due to b4
s.getAvailableRooms(10, 12)
=> [0]
// Cancelling again is a no-op
s.cancelBooking("b1")
=> false
Example 2: Edge cases: invalid inputs, duration vs repeatDuration constraint, instant meeting, invalid availability query
MeetingRoomScheduler s = new MeetingRoomScheduler(1, 1); // room: 0 employee: 0
s.listBookingsForRoom(0, 5)
=> []
s.listBookingsForEmployee(0, 5)
=> []
// Invalid: startTime < 0
s.bookRoom("x1", 0, 0, -1, 1, 5)
=> false
// Invalid: duration <= 0
s.bookRoom("x2", 0, 0, 10, 0, 5)
=> false
// Invalid per rule: duration < repeatDuration is required (so duration == repeatDuration is not allowed)
s.bookRoom("x3", 0, 0, 10, 5, 5)
=> false
// Valid "instant" booking: duration=1 => interval [20,20], repeats every 7 for 20 occurrences
// occurrence times: 20, 27, 34, ... , 20 + 19*7 = 153
s.bookRoom("x4", 0, 0, 20, 1, 7)
=> true
// Invalid availability query (startTime > endTime)
s.getAvailableRooms(30, 10)
=> []
// At time=20, room0 is busy
s.getAvailableRooms(20, 20)
=> []
// With "check all 20 occurrences":
// x5 occurrence times: 21, 29, 37, 45, 53, 61, 69, ...
// x4 occurrence times: 20, 27, 34, 41, 48, 55, 62, 69, ...
// They overlap at time=69 within the first 20 occurrences, so booking must be rejected.
s.bookRoom("x5", 0, 0, 21, 1, 8)
=> false
// So only x4 appears in listings
s.listBookingsForRoom(0, 6)
=> ["x4-20-20", "x4-27-27", "x4-34-34", "x4-41-41", "x4-48-48", "x4-55-55"]
s.cancelBooking("does-not-exist")
=> false
s.cancelBooking("x4")
=> true
// Now time=20 becomes free
s.getAvailableRooms(20, 20)
=> [0]