Open In App

Reduce the instructions following the given conditions

Last Updated : 31 Aug, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array dir_list[] that represents direction where the valid directions are “UP”, “Left”, “Right” and “Down”. Your goal is to reduce the instructions by eliminating those that contradict one another, or those consecutive instructions that are opposite to one another. If the list becomes empty, print -1.

Note: UP and Down are opposite to each other and Left and Right are also opposite to each other.

Examples:

Input: dir_list = [“UP”, “Left”, “Right”, “Down”, “Right”, “UP”]
Output: [‘Right’, ‘UP’]
Explanation: Direction at index 1 and 2 cancel out each other. After their removal, dir_list become [“UP”, “Down”, “Right”, “UP”] Direction at index 0 and 1 also cancel out each other. After their removal, dir_list become [“Right”, “UP”]

Input: dir_list = [“UP”, “Down”]
Output: []
Explanation: UP and Down are consecutively opposite to each other so, they are cancel out each other leaving an empty list.

Approach: This can be solved using a stack.

The idea is to eliminate the opposite directions by comparing top element of stack and last element of list.

Follow the below steps to implement the idea:

  • First check if the List is empty or has only a single element, then, return the list itself.
  • Create a stack, append the last element of the list to the stack, and pop it from the list.
  • While the list is not empty
    • If the stack is empty, pop the last element of the list and append it to the stack
    • Set a = top element of the stack and pop the element and b = last element of the list and pop the element
    • Check if a and b are not opposed to each other, append a and b into the stack respectively.
  • After executing the loop, reverse the stack and return it.

Below is the implementation of the above approach.

C++14




// C++ program to solve desert
// crossing problem
#include <bits/stdc++.h>
using namespace std;
 
// Function to check if a and b is
// opposite or not
bool isOpposite(string a, string b)
{
    if ((a == "UP" && b == "Down")
        || (a == "Down" && b == "UP")) {
        return true;
    }
 
    if ((a == "Left" && b == "Right")
        || (a == "Right" && b == "Left")) {
        return true;
    }
 
    return false;
}
 
// Function to remove the opposite
// instructions
vector<string> reduceDir(vector<string> l)
{
 
    // Create a stack and append the last
    // element of list to the stack and
    // pop it from list
    stack<string> st;
    st.push(l.back());
    l.pop_back();
 
    // While list is not empty
    while (!l.empty()) {
 
        // When stack is empty
        if (st.empty()) {
            st.push(l.back());
            l.pop_back();
            continue;
        }
 
        // Find a and b
        string a = st.top();
        st.pop();
        string b = l.back();
        l.pop_back();
 
        // Check is a and b are opposite
        // or not
        if (!isOpposite(a, b)) {
 
            // If it is not then append the
            // popped element to the stack
            // again and also append the
            // popped element of list
            st.push(a);
            st.push(b);
        }
    }
 
    vector<string> res;
    while (!st.empty()) {
        res.push_back(st.top());
        st.pop();
    }
 
    // Return the stack
    return res;
}
 
// Driver Code
int main()
{
    vector<string> dir_list
        = { "UP", "Left", "Right", "Down", "Right", "UP" };
 
    vector<string> res_list = reduceDir(dir_list);
 
    if (res_list.empty()) {
        cout << "-1" << endl;
    }
    else {
        for (auto i : res_list) {
            cout << i << " ";
        }
        cout << endl;
    }
 
    return 0;
}


Java




// Java program to solve desert crossing problem
 
import java.io.*;
import java.util.*;
 
class GFG {
 
    // Function to check if a and b is opposite or not
    static boolean isOpposite(String a, String b)
    {
        if ((a.equals("UP") && b.equals("Down"))
            || (a.equals("Down") && b.equals("UP"))) {
            return true;
        }
 
        if ((a.equals("Left") && b.equals("Right"))
            || (a.equals("Right") && b.equals("Left"))) {
            return true;
        }
 
        return false;
    }
 
    // Function to remove the opposite instructions
    public static List<String> reduceDir(List<String> l)
    {
        // Create a stack and append the last element of
        // list to the stack and pop it from list
        Stack<String> stack = new Stack<>();
        stack.add(l.remove(l.size() - 1));
 
        // While list is not empty
        while (!l.isEmpty()) {
            // When stack is empty
            if (stack.isEmpty()) {
                stack.add(l.remove(l.size() - 1));
                continue;
            }
 
            // Find a and b
            String a = stack.pop();
            String b = l.remove(l.size() - 1);
 
            // Check is a and b are oppositte or not
            if (!isOpposite(a, b)) {
 
                // If it is not then append the popped
                // element to the stack again and also
                // append the popped element of list
                stack.push(a);
                stack.push(b);
            }
        }
 
        List<String> res = new ArrayList<>(stack);
        Collections.reverse(res);
 
        // return the result.
        return res;
    }
 
    public static void main(String[] args)
    {
        List<String> dir_list = new ArrayList<>(
            Arrays.asList("UP", "Left", "Right", "Down",
                          "Right", "UP"));
        List<String> res_list = reduceDir(dir_list);
 
        if (res_list.isEmpty()) {
            System.out.println("-1");
        }
        else {
            System.out.println(res_list);
        }
    }
}
 
// This code is contributed by karthik.


Python3




# Python program to solve desert
# crossing problem
 
# Function to check if a and b is
# opposite or not
 
 
def isOpposite(a, b):
 
    if (a == "UP" and b == "Down") or (a == "Down" and b == "UP"):
        return 1
 
    if (a == "Left" and b == "Right") or (a == "Right" and b == "Left"):
        return 1
 
    else:
        return 0
 
# Function to remove the opposite
# instructions
 
 
def reduceDir(l):
 
    # List is empty or has only single
    # element
    if len(l) == 0 or len(l) == 1:
        return l
 
    # Create a stack and append the last
    # element of list to the stack and
    # pop it from list
    stack = []
    stack.append(l.pop())
 
    # While list is not empty
    while len(l) != 0:
 
        # When stack is empty
        if len(stack) == 0:
            stack.append(l.pop())
            continue
 
        # Find a and b
        a = stack.pop()
        b = l.pop()
 
        # Check is a and b are opposite
        # or not
        if isOpposite(a, b) != 1:
 
            # If it is not then append the
            # popped element to the stack
            # again and also append the
            # popped element of list
            stack.append(a)
            stack.append(b)
 
    # Reverse the stack
    stack.reverse()
 
    # Return the stack
    return stack
 
# Driver Code
 
 
if __name__ == "__main__":
 
    dir_list = ["UP", "Left", "Right", "Down", "Right", "UP"]
 
    res_list = reduceDir(dir_list)
 
    if(len(res_list) == 0):
        print(-1)
    else:
        print(res_list)


C#




using System;
using System.Collections.Generic;
 
class GFG
{
   
      // Function to check if a and b is
    // opposite or not
    static bool IsOpposite(string a, string b)
    {
        if ((a == "UP" && b == "Down")
            || (a == "Down" && b == "UP"))
        {
            return true;
        }
        if ((a == "Left" && b == "Right")
            || (a == "Right" && b == "Left"))
        {
            return true;
        }
        return false;
    }
 
      // Function to remove the opposite
    // instructions
    static List<string> ReduceDir(List<string> l)
    {
           
          // Create a stack and append the last
           // element of list to the stack and
        // pop it from list
        Stack<string> st = new Stack<string>();
        st.Push(l[l.Count - 1]);
        l.RemoveAt(l.Count - 1);
       
          // While list is not empty
        while (l.Count > 0)
        {
              // When stack is empty
            if (st.Count == 0)
            {
                st.Push(l[l.Count - 1]);
                l.RemoveAt(l.Count - 1);
                continue;
            }
           
              // Find a and b
            string a = st.Peek();
            st.Pop();
            string b = l[l.Count - 1];
            l.RemoveAt(l.Count - 1);
           
              // Check is a and b are opposite
            // or not
            if (!IsOpposite(a, b))
            {
                  // If it is not then append the
                    // popped element to the stack
                // again and also append the
                // popped element of list
                st.Push(a);
                st.Push(b);
            }
        }
        List<string> res = new List<string>();
        while (st.Count > 0)
        {
            res.Add(st.Peek());
            st.Pop();
        }
       
           // Return the stack
        return res;
    }
 
      // Driver Code
    static void Main()
    {
        List<string> dir_list = new List<string>
        {
            "UP", "Left", "Right", "Down", "Right", "UP"
        };
        List<string> res_list = ReduceDir(dir_list);
        if (res_list.Count == 0)
        {
            Console.WriteLine("-1");
        }
        else
        {
            foreach (var i in res_list)
            {
                Console.Write(i + " ");
            }
            Console.WriteLine();
        }
    }
}


Javascript




// Function to check if a and b is
// opposite or not
function GFG(a, b) {
    if ((a === "UP" && b === "Down") || (a === "Down" && b === "UP")) {
        return true;
    }
    if ((a === "Left" && b === "Right") || (a === "Right" && b === "Left")) {
        return true;
    }
    return false;
}
// Function to remove opposite instructions
function reduceDir(dirList) {
    // If the list is empty or has only a single element, return it as is
    if (dirList.length === 0 || dirList.length === 1) {
        return dirList;
    }
    const stack = [];
    stack.push(dirList.pop());
    // While the list is not empty
    while (dirList.length !== 0) {
        // When the stack is empty
        if (stack.length === 0) {
            stack.push(dirList.pop());
            continue;
        }
        // Find a and b
        const a = stack.pop();
        const b = dirList.pop();
        // Check if a and b are opposite or not
        if (!GFG(a, b)) {
            // If they are not opposite
            // push the popped elements back to the stack
            stack.push(a);
            stack.push(b);
        }
    }
    // Reverse the stack to get the correct order
    stack.reverse();
    return stack;
}
// Driver Code
const dirList = ["UP", "Left", "Right", "Down", "Right", "UP"];
const resList = reduceDir(dirList);
// Check if the resulting list is
// empty or not and print accordingly
if (resList.length === 0) {
    console.log(-1);
} else {
    console.log(resList);
}


Output

['Right', 'UP']




Time Complexity: O(N)
Auxiliary Space: O(N)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads