-
Notifications
You must be signed in to change notification settings - Fork 181
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: plutov <[email protected]>
- Loading branch information
Showing
4 changed files
with
222 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
### Optimal Meeting Scheduling | ||
|
||
Given a set of meetings with start and end times, and a set of rooms with different capacities, find the optimal schedule that maximizes the number of meetings held. A meeting can only be held in a room if its capacity is greater than or equal to the number of attendees. | ||
|
||
So the constraints are: | ||
- Meetings cannot overlap in the same room. | ||
- A meeting can only be scheduled in a room with sufficient capacity. | ||
- In case of a conflict - prioritize the meeting with the higher number of attendees | ||
|
||
Input/Output structs: | ||
|
||
```go | ||
type Meeting struct { | ||
start int // start time, not an actual timestamp, just an index | ||
end int // end time, not an actual timestamp, just an index | ||
attendees int | ||
} | ||
|
||
type ScheduledMeeting struct { | ||
meeting Meeting | ||
roomIndex int | ||
} | ||
``` | ||
|
||
Implement the following function. The results must be sorted as they appear in `meetings` input. | ||
|
||
```go | ||
func Meetings(meetings []Meeting, rooms []int) []ScheduledMeeting | ||
``` | ||
|
||
### Run tests with benchmarks | ||
|
||
``` | ||
go test -bench . | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package meetings | ||
|
||
type Meeting struct { | ||
start int // start time, not an actual timestamp, just an index | ||
end int // end time, not an actual timestamp, just an index | ||
attendees int | ||
} | ||
|
||
type ScheduledMeeting struct { | ||
meeting Meeting | ||
roomIndex int | ||
} | ||
|
||
func Meetings(meetings []Meeting, rooms []int) []ScheduledMeeting { | ||
return []ScheduledMeeting{} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
package meetings | ||
|
||
import ( | ||
"fmt" | ||
"reflect" | ||
"testing" | ||
|
||
"math/rand" | ||
) | ||
|
||
func TestMeetings(t *testing.T) { | ||
var tests = []struct { | ||
meetings []Meeting | ||
rooms []int | ||
result []ScheduledMeeting | ||
}{ | ||
{ | ||
meetings: []Meeting{ | ||
{1, 3, 10}, | ||
{4, 6, 5}, | ||
{7, 9, 8}, | ||
}, | ||
rooms: []int{10}, | ||
result: []ScheduledMeeting{ | ||
{Meeting{1, 3, 10}, 0}, | ||
{Meeting{4, 6, 5}, 0}, | ||
{Meeting{7, 9, 8}, 0}, | ||
}, | ||
}, | ||
{ | ||
meetings: []Meeting{ | ||
{1, 3, 10}, | ||
{2, 4, 15}, // Overlaps, but has more attendees | ||
{5, 7, 7}, | ||
}, | ||
rooms: []int{20}, | ||
result: []ScheduledMeeting{ | ||
{Meeting{2, 4, 15}, 0}, | ||
{Meeting{5, 7, 7}, 0}, | ||
}, | ||
}, | ||
{ | ||
meetings: []Meeting{ | ||
{1, 3, 100}, // Insufficient Capacity | ||
{4, 6, 5}, | ||
}, | ||
rooms: []int{10}, | ||
result: []ScheduledMeeting{ | ||
{Meeting{4, 6, 5}, 0}, | ||
}, | ||
}, | ||
{ | ||
meetings: []Meeting{ | ||
{1, 3, 10}, | ||
{4, 6, 5}, | ||
{2, 5, 8}, | ||
}, | ||
rooms: []int{10, 8}, | ||
result: []ScheduledMeeting{ | ||
{Meeting{1, 3, 10}, 0}, | ||
{Meeting{4, 6, 5}, 0}, | ||
{Meeting{2, 5, 8}, 1}, | ||
}, | ||
}, | ||
{ | ||
meetings: []Meeting{ | ||
{1, 3, 10}, | ||
{2, 4, 12}, // Overlaps, higher priority | ||
{4, 6, 7}, | ||
{1, 2, 15}, // Overlaps and needs a larger room, highest priority | ||
}, | ||
rooms: []int{10, 15}, | ||
result: []ScheduledMeeting{ | ||
{Meeting{1, 2, 15}, 1}, | ||
{Meeting{2, 4, 12}, 0}, | ||
{Meeting{4, 6, 7}, 0}, | ||
}, | ||
}, | ||
{ | ||
meetings: []Meeting{}, | ||
rooms: []int{}, | ||
result: []ScheduledMeeting{}, | ||
}, | ||
{ | ||
meetings: []Meeting{}, | ||
rooms: []int{10, 20}, | ||
result: []ScheduledMeeting{}, | ||
}, | ||
{ | ||
meetings: []Meeting{ | ||
{1, 3, 10}, | ||
{4, 6, 5}, | ||
}, | ||
rooms: []int{}, | ||
result: []ScheduledMeeting{}, | ||
}, | ||
{ | ||
meetings: []Meeting{ | ||
{1, 3, 10}, | ||
{2, 4, 15}, | ||
{5, 7, 10}, | ||
}, | ||
rooms: []int{20}, | ||
result: []ScheduledMeeting{ | ||
{Meeting{2, 4, 15}, 0}, | ||
{Meeting{5, 7, 10}, 0}, | ||
}, | ||
}, | ||
{ | ||
meetings: []Meeting{ | ||
{1, 5, 10}, | ||
{2, 4, 12}, | ||
{3, 6, 8}, | ||
{1, 2, 16}, | ||
{6, 7, 5}, | ||
}, | ||
rooms: []int{15, 20}, | ||
result: []ScheduledMeeting{ | ||
{Meeting{1, 2, 16}, 1}, | ||
{Meeting{2, 4, 12}, 0}, | ||
{Meeting{6, 7, 5}, 0}, | ||
}, | ||
}, | ||
} | ||
|
||
for i, tt := range tests { | ||
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { | ||
result := Meetings(tt.meetings, tt.rooms) | ||
if !reflect.DeepEqual(result, tt.result) { | ||
//t.Errorf("Meetings(%v, %v) expected %v, got %v", tt.meetings, tt.rooms, tt.result, result) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func BenchmarkMeetings(b *testing.B) { | ||
numMeetings := 1000 // A good starting point for "large" | ||
numRooms := 50 | ||
maxStartTime := 1000 | ||
maxDuration := 50 | ||
maxAttendees := 100 | ||
maxCapacity := 150 | ||
|
||
meetings := generateMeetings(numMeetings, maxStartTime, maxDuration, maxAttendees) | ||
rooms := generateRooms(numRooms, maxCapacity) | ||
|
||
for i := 0; i < b.N; i++ { | ||
Meetings(meetings, rooms) | ||
} | ||
} | ||
|
||
func generateMeetings(numMeetings int, maxStartTime int, maxDuration int, maxAttendees int) []Meeting { | ||
meetings := make([]Meeting, numMeetings) | ||
for i := 0; i < numMeetings; i++ { | ||
start := rand.Intn(maxStartTime) | ||
duration := rand.Intn(maxDuration) + 1 // Ensure duration is at least 1 | ||
attendees := rand.Intn(maxAttendees) + 1 | ||
meetings[i] = Meeting{start, start + duration, attendees} | ||
} | ||
return meetings | ||
} | ||
|
||
func generateRooms(numRooms int, maxCapacity int) []int { | ||
rooms := make([]int, numRooms) | ||
for i := 0; i < numRooms; i++ { | ||
capacity := rand.Intn(maxCapacity) + 1 | ||
rooms[i] = capacity | ||
} | ||
return rooms | ||
} |