cielux
10/24/2018 - 12:09 AM

Longest Largest Meeting

Finish this function to find the largest new meeting you can schedule. Largest means must number of people in the meeting. And if there are ties choose the meeting with the longest duration. A meeting can only span multiple hours if the same people can attend. Answer: The largest meeting we can have is with 3 people between 4 and 6.

const people = [
  [[0,3],[3,4],[6,8],[9,10],[10,13],[13,15],[17,19],[20,22],[22,24]],
  [[0,2],[2,4],[9,10],[10,12],[16,17],[19,21],[23,24]],
  [[4,5],[5,8],[14,15],[15,16],[18,19],[19,22]],
  [[6,9],[9,11],[12,15],[15,16],[21,23],[23,24]],
  [[0,1],[1,4],[4,7],[7,8],[8,10],[10,13],[13,14],[15,18],[19,21]]
];

function isBooked(hour, schedule) {
  for (const range of schedule) {
    if (hour >= range[0] && hour < range[1]) {
      return true;
    }
  }
  return false;
}

function isFree(hour, schedule) {
  return !isBooked(hour, schedule);
}

function getPeopleFree(hour, schedules) {
  let result = [];
  for (let i = 0; i < schedules.length; ++i) {
    const schedule = schedules[i];
    if (isFree(hour, schedule)) {
      result.push(i);
    }
  }
  return result;
}

// N.B. This assumes that people always appear in the same
// order. If this needs to be more permissive in the future,
// we can either sort or hash the arrays.
function samePeople(a, b) {
  return a.length === b.length && a.every((v, i) => v === b[i]);
}

function findMaxSet(list, map) {
  const max = Math.max(...list.map(map));
  return list.filter(e => map(e) === max);
}

/*
* Finish this function to find the largest new meeting you can schedule.
* Largest means must number of people in the meeting. And if there are ties choose the meeting with the longest duration.
* A meeting can only span multiple hours if the same people can attend.
* Answer: The largest meeting we can have is with 3 people between 4 and 6.
*/
function largestMeeting(schedules) {
  console.log("largestMeeting");
  
  let results = [];
  let hour = 0;
  while (hour < 24) {
    let result = {};
    result.start = hour;
    result.people = getPeopleFree(hour, schedules);
    while (++hour < 24 &&
           samePeople(result.people, getPeopleFree(hour, schedules)));
    result.length = hour - result.start;
    results.push(result);
  }
  console.log(results);
  
  /*// Scan for largest meeting
  const maxPeople = Math.max(...results.map(r => r.people.length));
  // Collect largest meetings
  const largestMeetings = results.filter(m => m.people.length === maxPeople);
  // Scan for longest largest meeting
  const maxHours = Math.max(...largestMeetings.map(m => m.length));
  // Collect longest largest meetings
  const longestLargestMeetings = largestMeetings.filter(m => m.length === maxHours);*/
  
  const largestMeetings =
        findMaxSet(results, meeting => meeting.people.length);
  const longestLargestMeetings =
        findMaxSet(largestMeetings, meeting => meeting.length);
  
  // Unfortunately our contract requires us to give an
  // incomplete answer; for now, just pick the earliest
  // meeting.
  //
  // IMPROVE(rain): Accept an optional functor for
  // selecting among multiple satisfactory meetings?
  const selectedValidMeeting = longestLargestMeetings[0];
  const count = selectedValidMeeting.people.length;
  const start = selectedValidMeeting.start;
  const end = start + selectedValidMeeting.length;
  
  return `The largest meeting we can have is with ${count} people between ${start} and ${end}.`;
}

console.log("Test passes: ", largestMeeting(people), "The largest meeting we can have is with 3 people between 4 and 6.");