Last active
April 12, 2024 11:17
-
-
Save zoffixznet/18a516b312ce7dccf61ebab48beeec5d 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
// | |
// Take-home coding exercise answer for Pete Evstratov: | |
// | |
// The original code had multiple issues that have been addressed in this version: | |
// | |
// 1. Original question on why the script runs slow: because the code was searching for address and | |
// employee information on each iteration of a loop leading to an O(2n^2) algo. | |
// I changed the code to use two maps instead to look up that info, before we start iterating to | |
// construct the email. | |
// | |
// 2. The original code was incorrectly using .endDate for years of service calculations. I changed it to .startDate | |
// | |
// 3. The original code was not checking if the employee was still active. I added a check to ensure .endDate was not set | |
// | |
// 4. The original code was not rounding the years of service to the nearest year. I added a Math.round() call, to fix that. | |
// In a real-world scenario, I would ask for clarification on how to handle partial years of service, as some companies | |
// do, in fact, offer partial days of vacation. | |
// | |
// 5. (Going with the above assumption of wanting only whole vacation days) The original code was not checking if the employee | |
// had been with the company for at least a year and would've sent "good news" emails to employees who haven't earned any days | |
// | |
// 6. In real-world scenario, I would ask for additional clarification on whether this program would apply to employees who are | |
// employed on a part-time or contract-basis. And I'd also clarify, whether `today-startDate` actually represents the number | |
// of years of service. Because an employee may have left the company and later returned or may have been on a leave of absence. | |
// | |
export interface AddressBook { | |
emp_id: string|null; | |
first: string; | |
last: string; | |
email: string; | |
} | |
export interface Payroll { | |
emp_id: string; | |
vacationDays: number; | |
} | |
interface Employee { | |
id: string; | |
name: string; | |
startDate: Date; | |
endDate: Date|null; | |
} | |
export interface EmailApi { | |
createBatch(): number | |
queueEmail(batchId: number, email: string, subject: string, body: string): void | |
flushBatch(batchId: number): Promise<void> | |
} | |
function yearsSince(startDate: Date, endDate: Date): number { | |
const millisecondsPerYear = 365 * 24 * 60 * 60 * 1000; | |
return Math.round(( endDate.getTime() - startDate.getTime() ) / millisecondsPerYear); | |
} | |
/** | |
* We haved decided to grant bonus vacation to every employee, 1 day per year of experience | |
* we need to email them a notice. | |
*/ | |
async function grantVacation( | |
emailApi: EmailApi, | |
payroll: Payroll[], | |
addresses: AddressBook[], | |
employees: Employee[], | |
) { | |
const addressMap = new Map(addresses.map(x => [x.emp_id, x])); | |
const empInfoMap = new Map(employees.map(x => [x.id, x])); | |
const today = new Date(); | |
const emailBatchId = emailApi.createBatch(); | |
for (var index in payroll) { | |
const payrollInfo = payroll[index]; | |
const addressInfo = addressMap.get(payrollInfo.emp_id); | |
const empInfo = empInfoMap.get(payrollInfo.emp_id); | |
// Ensure we send the email only to employees who are currently active and have been with us for at least a year | |
if (addressInfo && empInfo && ! empInfo.endDate && empInfo.startDate <= today) { | |
const yearsEmployed = yearsSince(empInfo.startDate, today); | |
if (yearsEmployed < 1) continue; | |
const newVacationBalance = yearsEmployed + payrollInfo.vacationDays; | |
emailApi.queueEmail( | |
emailBatchId, | |
addressInfo.email, | |
"Good news!", | |
`Dear ${empInfo.name}\n` + | |
`based on your ${yearsEmployed} years of employment, you have been granted ${yearsEmployed} days of vacation, bringing your total to ${newVacationBalance}` | |
); | |
} | |
} | |
await emailApi.flushBatch(emailBatchId); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment