Skip to content

Instantly share code, notes, and snippets.

@zoffixznet
Last active April 12, 2024 11:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zoffixznet/18a516b312ce7dccf61ebab48beeec5d to your computer and use it in GitHub Desktop.
Save zoffixznet/18a516b312ce7dccf61ebab48beeec5d to your computer and use it in GitHub Desktop.
//
// 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