Remove redundant directions from array using reduce method in javascript

Viewed 343

I have a problem where I am supposed to remove redundant directions from array. For example, if I have ["N", "S", "E", "W", "E"], I would return ["E"] because north and south cancel out and east and west cancel out to leave the one east. If they are adjacent, they cancel out. If I have ['W', 'N', 'S', 'E', 'N'], it returns ["N"] because N,S cancel, leaving W, E which also cancels. I created a function that works:

function mapQuest(arr) {
  const directions = { N: 2, S: -2, W: 1, E: -1 };

  for (let i = 0; i < arr.length; i++) {
    while (directions[arr[i]] + directions[arr[i + 1]] == 0) {
      arr.splice(i, 2);
      i = 0;
    }
  }
  return arr;
}

But the problem is asking to solve the problem using reduce method in javascript. I started to write one:

function mapQuest(arr) {
  let result = arr.reduce((acc, dir) => acc[dir]++, { N: 0, S: 0, W: 0, E: 0 });
}

But I don't know where to go from here and how to cancel out only adjacent directions without a for loop iterating through i. If someone could help out, that would be great. Thanks!

2 Answers

You can check whether there is an opposite left in the array. If there is one, simply splice it. If not, push the current direction into the Array:

function mapQuest(arr) {
  const opposites = { N: 'S', S: 'N', W: 'E', E: 'W' };
  return arr.reduce((acc, dir) => {
    const oppositeIndex = acc.indexOf(opposites[dir]);
    if (oppositeIndex > -1) {
      acc.splice(oppositeIndex, 1);
    } else {
      acc.push(dir);
    }
    return acc;
  }, []);
}

console.log(mapQuest(["N", "S", "E", "W", "E"])); // ["E"]
console.log(mapQuest(['W', 'N', 'S', 'E', 'N'])); // ["N"]

Try this:

let arr = ['W', 'N', 'S', 'E', 'N'];
    
    let result = arr.reduce((acc, cur) => {
        if(acc.toCancel.length === 0){
            acc.toCancel.push(cur);
            acc.result = cur;
            return acc;
        }else{
            let pair = `${acc.toCancel[0]}${cur}`;
            if(acc.pairs.includes(pair)){
                acc.toCancel = [];
                acc.result = cur === acc.result? "":acc.result;         
            }
            return acc;
        }
    },{toCancel:[], result:"", pairs:["EW", "NS", "WE", "SN"]});
    
    console.log(result);
Related