Created
January 27, 2018 21:40
-
-
Save matthamil/8506b932f79fd6ff37b2f186b1ab1fd7 to your computer and use it in GitHub Desktop.
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
/** | |
* Scheduling events and goals is a core feature of our platform. | |
* Users should be able to set goals to complete for themselves. | |
* The purpose of setting goals is to keep the user motivated and help | |
* them to stay clean. | |
* | |
* Users can set goals for themselves that repeat multiple times a week. | |
* Below is an example goal from the API. Bryan created a goal for himself | |
* to meditate three times a week on Mondays, Wednesdays, and Fridays. | |
* | |
* When the user creates a goal like the one below, the database can't | |
* save a list of days on which the goal is due. To remedy this problem, | |
* we use a base10 representation of binary to create a single number that | |
* stores info on what days the goal repeats on. | |
* | |
* Days of the week: | |
* [ 'M', 'T', 'W', 'Th', 'F', 'S', 'Su' ] | |
* | |
* Base10 representation of binary | |
* [ 1, 2, 4, 8, 16, 32, 64 ] | |
* | |
* The goal below repeats every Monday, Wednesday, and Friday. To find the reccurenceDays | |
* value, we add up the values for each day of the week, 1 + 4 + 16 = 21. | |
* | |
* This representation of the data is helpful for our database, but it is not helpful | |
* for working with dates in JavaScript. We need to be able to convert this base10 representation | |
* into an array of values that represent the day's index in the week. | |
* | |
* JavaScript representation of days of the week: | |
* [ 1, 2, 3, 4, 5, 6, 0 ] | |
* | |
* These values are from Date.getDay(). | |
* | |
* For the sake of our business problem, Mondays are the first day of the week, although JS treats | |
* Sunday as the first day of the week (Sunday.getDay() === 0). | |
* | |
* Your goal is to create two functions: | |
* 1. convertBase10ToArrayOfIndexes | |
* 2. convertBase10ToArrayOfDays | |
* | |
* The first should accept the reccurenceDays value as input and output an array of index values | |
* representing which days of the week the goal repeats on. | |
* | |
* E.g.: input 21 --> output [ 1, 3, 5 ] | |
* | |
* The second function should accept the reccurenceDays value as input and output an array of | |
* strings for each day the goal repeats on. | |
* | |
* E.g.: input 21 --> output [ 'M', 'W', 'F' ] | |
*/ | |
const goal = { | |
activeDate: "2018-01-23T22:10:57.00Z", | |
author: { | |
firstName: "Bryan", | |
lastName: "Smith", | |
id: 173 | |
}, | |
name: "Meditate", | |
description: "Meditate three times a week, on Monday, Wednesday, and Friday", | |
goalId: 710, | |
originalDueDate: "2018-01-24T23:00:00.00Z", | |
recurrenceDays: 21 | |
}; | |
const dayOfWeekIndexMapping = { | |
1: 1, | |
2: 2, | |
4: 3, | |
8: 4, | |
16: 5, | |
32: 6, | |
64: 0 | |
}; | |
const dayOfWeekMapping = { | |
1: "M", | |
2: "T", | |
4: "W", | |
8: "Th", | |
16: "F", | |
32: "S", | |
64: "Su" | |
}; | |
export const convertBase10ToArrayOfIndexes = ( | |
remainingRecurrenceDays, | |
index = 64, | |
days = [] | |
) => { | |
if (index === 1 || remainingRecurrenceDays === index) { | |
return [dayOfWeekIndexMapping[index], ...days]; | |
} | |
if (remainingRecurrenceDays > index) { | |
return convertBase10ToArrayOfIndexes( | |
remainingRecurrenceDays - index, | |
index / 2, | |
[dayOfWeekIndexMapping[index], ...days] | |
); | |
} | |
if (remainingRecurrenceDays < index) { | |
return convertBase10ToArrayOfIndexes( | |
remainingRecurrenceDays, | |
index / 2, | |
days | |
); | |
} | |
}; | |
export const convertBase10ToArrayOfDays = ( | |
remainingRecurrenceDays, | |
index = 64, | |
days = [] | |
) => { | |
if (index === 1 || remainingRecurrenceDays === index) { | |
return [dayOfWeekMapping[index], ...days]; | |
} | |
if (remainingRecurrenceDays > index) { | |
return convertBase10ToArrayOfDays( | |
remainingRecurrenceDays - index, | |
index / 2, | |
[dayOfWeekMapping[index], ...days] | |
); | |
} | |
if (remainingRecurrenceDays < index) { | |
return convertBase10ToArrayOfDays(remainingRecurrenceDays, index / 2, days); | |
} | |
}; | |
/** | |
* Bonus: | |
* | |
* We schedule push notifications to remind the user about their goals | |
* 15 minutes before they are due. This function should return info | |
* about the next cycle of push notifications that should occur for this goal. | |
* In the above goal example, this should return the times of the next | |
* push notifications that should occur to remind the user about his goal. | |
* You need to find the next 3 push notification times since this goal | |
* repeats 3 times a week. | |
* | |
* Write a test case for this as well. | |
* | |
* You are allowed to use third-party date libraries like moment or date-fns (recommended). | |
*/ | |
export const getNextPushNotifications = () => {}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment