Overview 🔍
The challenge Directions Reduction ask you to find shortest route from array of directions.
Examples:
Input
-> Output
["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"]
-> ["WEST"]
/*
Because moving "NORTH" and "SOUTH", or "EAST" and "WEST", is unnecessary.
*/
/*
Case: omit the first "NORTH"-"SOUTH" pair
["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"]
-> ["SOUTH", "EAST", "WEST", "NORTH", "WEST"]
Case: omit the "EAST"-"WEST" pair
-> ["SOUTH", "NORTH", "WEST"]
Case: omit the "NORTH"-"SOUTH" pair
-> ["WEST"]
*/
// this case cannot be reduced:
["NORTH", "WEST", "SOUTH", "EAST"]
-> ["NORTH", "WEST", "SOUTH", "EAST"]
Solutions 1: LIFO
function dirReduc(plan) {
var opposite = {
'NORTH': 'SOUTH', 'EAST': 'WEST', 'SOUTH': 'NORTH', 'WEST': 'EAST'};
return plan.reduce(function(dirs, dir){
if (dirs[dirs.length - 1] === opposite[dir])
dirs.pop(); // Remove last direction if it's the opposite
else
dirs.push(dir); // Otherwise, add current direction to the stack
return dirs;
}, []);
}
This is a LIFO (Last-in-First-out) approach implemented using reduce
.
Steps:
- Declare an empty stack (
dirs
) - For each direction in the input array (
plan
), check if the last element of the stack (dirs
) is the opposite of the current direction - If they are opposites, pop the last element from the stack (and skip current direction). Otherwise, push the current direction onto the stack.
- Repeat this process until all directions have been processed.
Solutions 2: Regular Expression
function dirReduce(arr) {
let str = arr.join(''), pattern = /NORTHSOUTH|EASTWEST|SOUTHNORTH|WESTEAST/;
while (pattern.test(str)) str = str.replace(pattern,''); // Remove pairs while they exist
return str.match(/(NORTH|SOUTH|EAST|WEST)/g)||[];
}
Alternative Version:
function dirReduc(arr) {
const pattern = /NORTHSOUTH|EASTWEST|SOUTHNORTH|WESTEAST/;
let str = arr.join('');
while (pattern.test(str)) {
str = str.replace(pattern, ''); // Remove pairs while they exist
}
const result = str.match(/(NORTH|SOUTH|EAST|WEST)/g);
return result || [];
}
Steps:
- Join the input array (
arr
) into a single string so we can manipulate it using regular expressions. - Define a regular expression (
pattern
) that matches opposite direction pairs (e.g., 'NORTHSOUTH', 'EASTWEST'). - Use the
replace
method in a loop to remove any direction pairs found by the regular expression. - After all pairs have been removed, use the
match
method to extract the remaining directions from the string and return them as an array.
Discussion and Insights 💭
I believe the minimum case for this solution is as follows:
1. ["SOUTH", "EAST", "WEST", "NORTH"]
-> []
2. ["NORTH", "WEST", "SOUTH", "EAST"]
-> ["NORTH", "WEST", "SOUTH", "EAST"]
I prefer Solution 2, as it is concise and uses regular expressions in a clever way. Initially, I couldn't imagine solving it with regular expressions, but the use of join
, match
, while
, replace
, and test
methods to eliminate pairs is impressive.
If you're curious about these solutions or want to explore more challenges, visit here.
Welcome to leave a comment below!
Thank you for reading 🙌
Top comments (0)