'Finding performance feasibility using array strings

Here is the requirement details:

time = ["09-13", "12-14"]

getResult(time) = false

The first performance runs from 9 a.m. to 1 p.m. and the second one starts at 12 p.m. So you won't be able to see each performance in full.

time = ["07-09", "10-12", "15-19"]

getResult(time) = true

but i could not able to get the result. I am finding challange to get it done. any one help me?

here is my try:

const getResult = (time) => {
  const nums = [];
  let pre = 0;
  time.map((item,index) => {
    item.split('-').map((v,i) => {
      nums.push(+v);//converting as number
    });
  });
  const result = nums.map((v,i) => {
    if(!i) return;
    console.log(v-pre)//but logically this is not works
    pre = v;
  })
}

//time = ["09-13", "12-14"]; //false
time = ["07-09", "10-12", "15-19"] //true
getResult(time); //should be false

Thanks in advance.



Solution 1:[1]

Your format is already useful for direct >= comparisons, once we split the values on their -'s. So we can simply sort the values, then check that in every case after the first one, that the start portion (before the -) is at least as large as the end portion (after the -) of the previous value. It could look like this:

const feasible = (times) => [... times] 
  .sort () 
  .every ((t, i, a) => i == 0 || t .split ('-') [0] >= a [i - 1] .split ('-') [1])  


console .log (feasible (["09-13", "12-14"]))
console .log (feasible (["07-09", "10-12", "15-19"]))

We use the i == 0 || to simply avoid testing the first of the sorted values.

This involves splitting each of the values twice (well, except the first one.) If this inefficiency bothers you, we could solve it (using more memory; there's always a tradeoff!) by splitting them and saving the result:

const feasible = (times) => [... times] 
  .sort () 
  .map (s => s .split ('-')) 
  .every ((t, i, a) => i == 0 || t [0] >= a [i - 1]  [1])  

Solution 2:[2]

Turn each range into each individual hour within the range, then:

  • if the hour already exists in the array, return false
  • else, push to the array

const getResult = (ranges) => {
  const filled = [];
  for (const range of ranges) {
    let [start, end] = range.split('-').map(Number);
    while (end !== start) { // Exclusive
      if (filled.includes(start)) return false;
      filled.push(start);
      start++;
    }
  }
  return true;
};
console.log(getResult(["09-13", "12-14"]));
console.log(getResult(["07-09", "10-12", "15-19"]));

Your current approach doesn't look to have any notion of turning the ranges into their individual hours, or of identifying overlaps.

Solution 3:[3]

  • Sort the time slots based on their start time.
  • Loop over all the time slots in the sorted array and if anytime the start of a slot is less than the end of the previous one, then return false.
  • If the whole loop is exhausted return true.

function isValid(time) {
  const sortedTime = [...time].sort((a, b) => {
    const slotA = Number(a.split("-")[0]);
    const slotB = Number(b.split("-")[0]);
    return slotA - slotB;
  });

  let last;
  for (let t of sortedTime) {
    const [start, end] = t.split("-").map(Number);
    if (last && start < last) {
      return false;
    }
    last = end;
  }
  return true;
}

console.log(isValid(["12-14", "09-13"]));
console.log(isValid(["10-12", "07-09", "15-19"]));

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Scott Sauyet
Solution 2 CertainPerformance
Solution 3