This is a take home exercise for Grayce. The goal of this exercise is to assign members to care partners based on characteristics of the members and care partners. We read the data from a json file and then assign members to care partners based on the following criteria:
- We prioritize members based on their acuity. We assign members with higher acuity (complex) first and lower acuity (just_browsing) last.
- We match the member to the care partner based on the member's use_case and the care partner's specialties.
In case there are no specialties provided by the care partner, we use them to match with "just_browsing" acuity members.
-
We take into account the timezone of the care recipient and the care partner. We prioritize care partners that are closer to the care recipient than the care giver. (This is a personal preference, we can change this to prioritize care partners that are closer to the care giver than the care recipient or find a middle ground. However more data is required to make a decision)
-
Each member is assigned to a care partner based on the use_case, closest timezone (In case they need to communicate effectively) and the calculated score of the care partner. The score of the care partner is based on the current work load of the care partner.
Following are the assumptions made for this exercise:
- Location of the care recipient and care giver is provided in the data. However has no affect on the assignment of the member to the care partner.
- We are assuming "just_browsing" acuity members to be of least priority.
- We are assuming there is no capacity limit for the care partners.
- We are assuming that the care partners are available to take on new cases.
- We are assuming that the care partners with more active cases have more work load.
{
"id": 1,
"acuity": "simple",
"use_case": "infant",
"first_name": "Christine",
"last_name": "Carter",
"care_recipient_location": {
"country_code": "US",
"lat": "36.8638097",
"lng": "-76.05593929999999",
"locality": "Virginia Beach",
"postal_code": "23454",
"state": "Virginia",
"timezone": "America/New_York"
},
"caregiver_location": {
"country_code": "US",
"lat": "41.6417186",
"lng": "-84.02019159999999",
"locality": "Delta",
"postal_code": "43515",
"state": "Ohio",
"timezone": "America/New_York"
}
}
{
"id": 1,
"current_active_cases": 23,
"current_cases": 516,
"first_name": "Roseanna",
"last_name": "Betsy",
"specialties": [
"pregnancy",
"self"
],
"timezone": "America/Los_Angeles"
},
Install Node.js and NPM from here if not already installed.
Then follow the following steps:
- Clone the repository
git clone https://github.com/kashishkhullar/grayce.git
- Install the dependencies
npm install
- Run the code
npm start
-
Members are sorted based on acuity which allows us to prioritize members based on their acuity. We can then assign members with higher acuity first and then lower acuity last.
members.sort((a, b) => { return sort_order[a.acuity] - sort_order[b.acuity]; });
-
We have created three structures in the code:
care_partner_mapping
- Maps use_case to timezone to care partner idscare_partner_cases
- Maps care partner ids to their current active cases and current casesassigned_members
- List of members that have been assigned to a care partner
-
We iterated through the care partners and store them in the
care_partner_mapping
andcare_partner_cases
objects.
care_partner_mapping[specialty][care_partner.timezone].push(care_partner.id);
In case there are no specialties provided by the care partner, we store them in the
general
specialty.
care_partner_mapping["general"][care_partner.timezone].push(care_partner.id);
- We iterated through the members, take their
use_case
and find closest timezone for them (using care recipient location)
For comparing timezones
luxon
module is used to calculate the difference between the timezones.
- We calculate the score of the care partner based on the current work load of the care partner. We use the
current_active_cases
and inactive cases (current_cases
-current_active_cases
) and multiply them to constant weights to calculate the score of the care partner.
const score =
WEIGHTS.ACTIVE_CASES * care_partner_cases[carePartner].current_active_cases +
WEIGHTS.INACTIVE_CASES *
(care_partner_cases[carePartner].current_cases - care_partner_cases[carePartner].current_active_cases);
These weights can be adjusted based on the business requirements. A higher score is assigned when the inactive cases are more than the active cases. Therefore a weight of
0.9
is assigned to the inactive cases and0.1
to the active cases. Weights are normalized to1
using min-max normalization.
- We then assign the member to the best calculated care partner.
- Language data would be more helpful in assigning members to care partners. For example, if the care recipient speaks Spanish, we can assign them to a care partner that speaks Spanish.
- A heap data structure could be utilized to store the care partners and its cases to improve the time complexity of the code. (However, the care partner will be shared among multiple heaps based on the use_case and timezone of the care recipient if the same storage structure is followed).
- Given there are
N members
,M care partners
,P specialties
, the time complexity of the code isO(NlogN + M*P + N*M)
. - In real world scenario, where we will have large number of members, we won't be sorting the values and members are joining the system in real time, we need a priority to which will sort the members based on their acuity and then assign the top.
- Instead of using the scores, each timezone can be assigned a min heap with care partner id and their cases. This will allow us to assign the member to the care partner with the least cases in the same timezone first and the heapify operation will take
O(logM)
time. - We should put a max capacity to all the care partners and then assign the members to the care partners based on their capacity and make the load balancer such that it removes the care partner from the heap if the capacity is full.
Thanks,
Kashish ๐