Categories
interview

Employee badging times – Javascript

We are working on a security system for a badged-access room in our company’s building.

We want to find employees who badged into our secured room unusually often. We have an unordered list of names and entry times over a single day. Access times are given as numbers up to four digits in length using 24-hour time, such as “800” or “2250”.

Write a function that finds anyone who badged into the room three or more times in a one-hour period. Your function should return each of the employees who fit that criteria, plus the times that they badged in during the one-hour period. If there are multiple one-hour periods where this was true for an employee, just return the earliest one for that employee.

badge_times = [
[‘Paul’, ‘1355’],
[‘Jennifer’, ‘1910’],
[‘Jose’, ‘835’],
[‘Jose’, ‘830’],
[‘Paul’, ‘1315’],
[‘Chloe’, ‘0’],
[‘Chloe’, ‘1910’],
[‘Jose’, ‘1615’],
[‘Jose’, ‘1640’],
[‘Paul’, ‘1405’],
[‘Jose’, ‘855’],
[‘Jose’, ‘930’],
[‘Jose’, ‘915’],
[‘Jose’, ‘730’],
[‘Jose’, ‘940’],
[‘Jennifer’, ‘1335’],
[‘Jennifer’, ‘730’],
[‘Jose’, ‘1630’],
[‘Jennifer’, ‘5’],
[‘Chloe’, ‘1909’],
[‘Zhang’, ‘1’],
[‘Zhang’, ’10’],
[‘Zhang’, ‘109’],
[‘Zhang’, ‘110’],
[‘Amos’, ‘1’],
[‘Amos’, ‘2’],
[‘Amos’, ‘400’],
[‘Amos’, ‘500’],
[‘Amos’, ‘503’],
[‘Amos’, ‘504’],
[‘Amos’, ‘601’],
[‘Amos’, ‘602’],
[‘Paul’, ‘1416’],
];

Expected output (in any order)

{
Paul: [‘1315’, ‘1355’, ‘1405’],
Jose: [‘830’, ‘835’, ‘855’, ‘915’, ‘930’],
Zhang: [’10’, ‘109’, ‘110’],
Amos: [‘500’, ‘503’, ‘504’],
}
n: length of the badge records array.

const badge_records = [
  ['Paul', '1355'],
  ['Jennifer', '1910'],
  ['Jose', '835'],
  ['Jose', '830'],
  ['Paul', '1315'],
  ['Chloe', '0'],
  ['Chloe', '1910'],
  ['Jose', '1615'],
  ['Jose', '1640'],
  ['Paul', '1405'],
  ['Jose', '855'],
  ['Jose', '930'],
  ['Jose', '915'],
  ['Jose', '730'],
  ['Jose', '940'],
  ['Jennifer', '1335'],
  ['Jennifer', '730'],
  ['Jose', '1630'],
  ['Jennifer', '5'],
  ['Chloe', '1909'],
  ['Zhang', '1'],
  ['Zhang', '10'],
  ['Zhang', '109'],
  ['Zhang', '110'],
  ['Amos', '1'],
  ['Amos', '2'],
  ['Amos', '400'],
  ['Amos', '500'],
  ['Amos', '503'],
  ['Amos', '504'],
  ['Amos', '601'],
  ['Amos', '602'],
  ['Paul', '1416']
];

const getOftenUsersOfBadge = (records) => {
  records.sort((a, b) => a[1] - b[1]);
  const obj = {};
  for (const [name, time] of records) {
    (obj[name] || (obj[name] = [])).push(time);
  }
  const result = {};
  for (const [key, val] of Object.entries(obj)) {
    const len = val.length;
    if (len >= 3) {
      for (let i = 2; i < len; i++) {
        if (val[i] - val[i - 2] <= 100) {
          const start = i - 2;
          const max = parseInt(val[start]) + 100;
          while (parseInt(val[++i]) <= max) {}
          result[key] = val.slice(start, i);
          break;
        }
      }
    }
  }
  return result;
};

console.log(getOftenUsersOfBadge(badge_records));

/* Explanation:
1) Sort the input records based on times in increasing order.
2) Build a map { name : [time1, time2,  ... timen], }
3) Computing times
          1 --> 00:01
        101 --> 01:01
        diff is 100 for 1 hour.
    No need to check (i < len) in the while loop as we break the loop on first failure of condition.
*/

Demo