Categories
interview

Find mismatches in badging records

Given an ordered list of employees who used their badge to enter or exit the room, write a function that returns two collections:
1. All employees who didn’t use their badge while exiting the room – they recorded an enter without a matching exit. (All employees are required to leave the room before the log ends.)
2. All employees who didn’t use their badge while entering the room – they recorded an exit without a matching enter. (The room is empty when the log begins.)
Each collection should contain no duplicates, regardless of how many times a given employee matches the criteria for belonging to it.

records1 = [
	  ["Martha",   "exit"],
	  ["Paul",     "enter"],
	  ["Martha",   "enter"],
	  ["Steve",    "enter"],
	  ["Martha",   "exit"],
	  ["Jennifer", "enter"],
	  ["Paul",     "enter"],
	  ["Curtis",   "exit"],
	  ["Curtis",   "enter"],
	  ["Paul",     "exit"],
	  ["Martha",   "enter"],
	  ["Martha",   "exit"],
	  ["Jennifer", "exit"],
	  ["Paul",     "enter"],
	  ["Paul",     "enter"],
	  ["Martha",   "exit"],
	  ["Paul",     "enter"],
	  ["Paul",     "enter"],
	  ["Paul",     "exit"],
	  ["Paul",     "exit"] 
	]

Expected output: ["Paul", "Curtis", "Steve"], ["Martha", "Curtis", "Paul"]

Other test cases:

records2 = [
	  ["Paul", "enter"],
	  ["Paul", "exit"],
	]

Expected output: [], []

records3 = [
	  ["Paul", "enter"],
	  ["Paul", "enter"],
	  ["Paul", "exit"],
	  ["Paul", "exit"],
	]

Expected output: ["Paul"], ["Paul"]

records4 = [
	  ["Paul", "enter"],
	  ["Paul", "exit"],
	  ["Paul", "exit"],
	  ["Paul", "enter"],
	]

Expected output: ["Paul"], ["Paul"]
const mismatches = (records) => {
  const obj = {};
  const notExited = [];
  const notEntered = [];
  for (const [name, state] of records) {
    if (!(name in obj)) {
      obj[name] = 0;
    }

    if (state === 'enter') {
      obj[name]++;
    } else {
      obj[name]--;
    }

    if (obj[name] > 1) {
      if (!notExited.includes(name)) {
        notExited.push(name);
      }
      obj[name] = 0;
    }
    if (obj[name] < 0) {
      if (!notEntered.includes(name)) {
        notEntered.push(name);
      }
      obj[name] = 0;
    }
  }

  for (const [key, val] of Object.entries(obj)) {
    if (val === 1) {
      if (!notExited.includes(key)) {
        notExited.push(key);
      }
    }
  }
  return [notExited, notEntered];
};

console.log(mismatches([
    ["Martha", "exit"],
    ["Paul", "enter"],
    ["Martha", "enter"],
    ["Steve", "enter"],
    ["Martha", "exit"],
    ["Jennifer", "enter"],
    ["Paul", "enter"],
    ["Curtis", "exit"],
    ["Curtis", "enter"],
    ["Paul", "exit"],
    ["Martha", "enter"],
    ["Martha", "exit"],
    ["Jennifer", "exit"],
    ["Paul", "enter"],
    ["Paul", "enter"],
    ["Martha", "exit"],
    ["Paul", "enter"],
    ["Paul", "enter"],
    ["Paul", "exit"],
    ["Paul", "exit"]
  ]),
  mismatches([
    ["Paul", "enter"],
    ["Paul", "exit"]
  ]),
  mismatches([
    ["Paul", "enter"],
    ["Paul", "enter"],
    ["Paul", "exit"],
    ["Paul", "exit"],
  ]),
  mismatches([
    ["Paul", "enter"],
    ["Paul", "exit"],
    ["Paul", "exit"],
    ["Paul", "enter"],
  ]));

Demo