Skip to content
This repository was archived by the owner on Jun 24, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
* Event is the container class for when a specific group of people are meeting and are therefore
* busy. Events are considered read-only.
*/
public final class Event {
public final class Event implements Comparable<Event>{
private final String title;
private final TimeRange when;
private final Set<String> attendees = new HashSet<>();
Expand Down Expand Up @@ -75,6 +75,9 @@ public Set<String> getAttendees() {
// internal data.
return Collections.unmodifiableSet(attendees);
}
public int compareTo(Event eventB) {
return this.getWhen().start() - eventB.getWhen().start();
}

@Override
public int hashCode() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,73 @@

package com.google.sps;

import java.util.Collection;
import java.util.*;
import java.lang.Math;

public final class FindMeetingQuery {
public Collection<TimeRange> query(Collection<Event> events, MeetingRequest request) {
throw new UnsupportedOperationException("TODO: Implement this method.");
long duration = request.getDuration();
ArrayList<Event> allEvents = new ArrayList();
ArrayList<Event> allEventsOptional = new ArrayList();
Set<String> attendees = new HashSet<String>(request.getAttendees());
Set<String> allAttendeesOptional = new HashSet<String>(request.getAttendees());
allAttendeesOptional.addAll(request.getOptionalAttendees());
//Add all events that attendees go to
for (Event event : events) {
Set<String> curAttendees = new HashSet<String>(attendees);
Set<String> curAttendeesOptional = new HashSet<String>(allAttendeesOptional);
curAttendees.retainAll(event.getAttendees());
curAttendeesOptional.retainAll(event.getAttendees());
if (!(curAttendees.isEmpty())){
allEvents.add(event);
}
if(!(curAttendeesOptional.isEmpty())){
allEventsOptional.add(event);
}

}
Collections.sort(allEvents);
Collections.sort(allEventsOptional);
ArrayList<TimeRange> timesOptional = getTimes(allEventsOptional, request);
if (!(timesOptional.isEmpty()) || request.getAttendees().size() == 0){
return timesOptional;
}
ArrayList<TimeRange> times = getTimes(allEvents, request);
return times;
}

private ArrayList<TimeRange> getTimes(ArrayList<Event> allEvents, MeetingRequest request) {
ArrayList<TimeRange> times = new ArrayList();
int start = 0;
Boolean cont = false;
for (int i = 0; i < allEvents.size(); i++) {
TimeRange curTime = allEvents.get(i).getWhen();
if (!cont) {
TimeRange curRange = TimeRange.fromStartEnd(start, curTime.start(), false);
if ((long) curRange.duration() >= request.getDuration()) {
times.add(curRange);
}
}
//If next event overlaps with current, make start the greater of the two events
if ((i != allEvents.size() - 1) && curTime.overlaps(allEvents.get(i+1).getWhen())) {
start = Math.max(curTime.end(), start);
cont = true;
} else {
//If it doesn't overlap check gap during next iteration
start = Math.max(curTime.end(), start);
cont = false;
}
//If last event check if end of day is a possible time
if (i == allEvents.size() - 1) {
TimeRange curRange = TimeRange.fromStartEnd(start, TimeRange.END_OF_DAY, true);
if ((long) curRange.duration() >= request.getDuration()) {
times.add(curRange);
}
}
}
if (allEvents.size() == 0 && request.getDuration() <= TimeRange.END_OF_DAY) {
times.add(TimeRange.fromStartEnd(TimeRange.START_OF_DAY, TimeRange.END_OF_DAY, true));
}
return times;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public final class FindMeetingQueryTest {
// Some people that we can use in our tests.
private static final String PERSON_A = "Person A";
private static final String PERSON_B = "Person B";
private static final String PERSON_C = "Person C";

// All dates are the first day of the year 2020.
private static final int TIME_0800AM = TimeRange.getTimeInMinutes(8, 0);
Expand All @@ -43,6 +44,7 @@ public final class FindMeetingQueryTest {
private static final int TIME_1000AM = TimeRange.getTimeInMinutes(10, 0);
private static final int TIME_1100AM = TimeRange.getTimeInMinutes(11, 00);

private static final int DURATION_15_MINUTES = 15;
private static final int DURATION_30_MINUTES = 30;
private static final int DURATION_60_MINUTES = 60;
private static final int DURATION_90_MINUTES = 90;
Expand Down Expand Up @@ -270,5 +272,119 @@ public void notEnoughRoom() {

Assert.assertEquals(expected, actual);
}
@Test
public void disregardOptionalAttendee() {
Collection<Event> events = Arrays.asList(
new Event("Event 1", TimeRange.fromStartDuration(TIME_0800AM, DURATION_30_MINUTES),
Arrays.asList(PERSON_A)),
new Event("Event 2", TimeRange.fromStartDuration(TIME_0900AM, DURATION_30_MINUTES),
Arrays.asList(PERSON_B)),
new Event("Event 3", TimeRange.fromStartDuration(TimeRange.START_OF_DAY, TimeRange.END_OF_DAY),
Arrays.asList(PERSON_C)));

MeetingRequest request =
new MeetingRequest(Arrays.asList(PERSON_A, PERSON_B), DURATION_30_MINUTES);
request.addOptionalAttendee(PERSON_C);
Collection<TimeRange> actual = query.query(events, request);
Collection<TimeRange> expected =
Arrays.asList(TimeRange.fromStartEnd(TimeRange.START_OF_DAY, TIME_0800AM, false),
TimeRange.fromStartEnd(TIME_0830AM, TIME_0900AM, false),
TimeRange.fromStartEnd(TIME_0930AM, TimeRange.END_OF_DAY, true));

Assert.assertEquals(expected, actual);
}
@Test
public void considerOptionalAttendee() {
Collection<Event> events = Arrays.asList(
new Event("Event 1", TimeRange.fromStartDuration(TIME_0800AM, DURATION_30_MINUTES),
Arrays.asList(PERSON_A)),
new Event("Event 2", TimeRange.fromStartDuration(TIME_0900AM, DURATION_30_MINUTES),
Arrays.asList(PERSON_B)),
new Event("Event 3", TimeRange.fromStartDuration(TIME_0830AM, DURATION_30_MINUTES),
Arrays.asList(PERSON_C)));

MeetingRequest request =
new MeetingRequest(Arrays.asList(PERSON_A, PERSON_B), DURATION_30_MINUTES);
request.addOptionalAttendee(PERSON_C);
Collection<TimeRange> actual = query.query(events, request);
Collection<TimeRange> expected =
Arrays.asList(TimeRange.fromStartEnd(TimeRange.START_OF_DAY, TIME_0800AM, false),
TimeRange.fromStartEnd(TIME_0930AM, TimeRange.END_OF_DAY, true));

Assert.assertEquals(expected, actual);
}
@Test
public void disregardIfNoFit() {
// Have one person, but make it so that there is just enough room at one point in the day to
// have the meeting.
//
// Events : |--A--| |----A----|
// Day : |---------------------|
// Options : |-----|

Collection<Event> events = Arrays.asList(
new Event("Event 1", TimeRange.fromStartEnd(TimeRange.START_OF_DAY, TIME_0830AM, false),
Arrays.asList(PERSON_A)),
new Event("Event 2", TimeRange.fromStartEnd(TIME_0900AM, TimeRange.END_OF_DAY, true),
Arrays.asList(PERSON_A)),
new Event("Event 3", TimeRange.fromStartDuration(TIME_0830AM, DURATION_15_MINUTES),
Arrays.asList(PERSON_B))
);

MeetingRequest request = new MeetingRequest(Arrays.asList(PERSON_A), DURATION_30_MINUTES);
request.addOptionalAttendee(PERSON_B);
Collection<TimeRange> actual = query.query(events, request);
Collection<TimeRange> expected =
Arrays.asList(TimeRange.fromStartDuration(TIME_0830AM, DURATION_30_MINUTES));

Assert.assertEquals(expected, actual);
}

@Test
public void onlyOptionalFit() {
// Have one person, but make it so that there is just enough room at one point in the day to
// have the meeting.
//
// Events : |--A--| |----A----|
// Day : |---------------------|
// Options : |-----|

Collection<Event> events = Arrays.asList(
new Event("Event 1", TimeRange.fromStartEnd(TimeRange.START_OF_DAY, TIME_0830AM, false),
Arrays.asList(PERSON_A)),
new Event("Event 2", TimeRange.fromStartEnd(TIME_0900AM, TimeRange.END_OF_DAY, true),
Arrays.asList(PERSON_B))
);
MeetingRequest request = new MeetingRequest(Arrays.asList(), DURATION_30_MINUTES);
request.addOptionalAttendee(PERSON_A);
request.addOptionalAttendee(PERSON_B);
Collection<TimeRange> actual = query.query(events, request);
Collection<TimeRange> expected =
Arrays.asList(TimeRange.fromStartDuration(TIME_0830AM, DURATION_30_MINUTES));
Assert.assertEquals(expected, actual);
}
@Test
public void noMandatoryAttendeesConflict() {
// Have one person, but make it so that there is not enough room at any point in the day to
// have the meeting.
//
// Events : |--A-----| |-----A----|
// Day : |---------------------|
// Options :

Collection<Event> events = Arrays.asList(
new Event("Event 1", TimeRange.fromStartEnd(TimeRange.START_OF_DAY, TIME_0830AM, false),
Arrays.asList(PERSON_A)),
new Event("Event 2", TimeRange.fromStartEnd(TIME_0900AM, TimeRange.END_OF_DAY, true),
Arrays.asList(PERSON_A)));

MeetingRequest request = new MeetingRequest(Arrays.asList(), DURATION_60_MINUTES);
request.addOptionalAttendee(PERSON_A);
Collection<TimeRange> actual = query.query(events, request);
Collection<TimeRange> expected = Arrays.asList();

Assert.assertEquals(expected, actual);
}

}